// Purpose.  Composite design pattern

// 1. Create a "lowest common denominator" that makes classes interchangeable
// 2. All concrete classes declare an "isa" relationship to the interface
// 3. All "container" classes couple themselves to the interface
// 4. "Container" classes use polymorphism as they delegate to their children

interface Component { void traverse(); }      // 1. "lowest common denominator"

class Primitive implements Component {        // 2. "Isa" relationship
   private int value;
   public Primitive( int val ) { value = val; }
   public void traverse()      { System.out.print( value + "  " ); }
}

abstract class Composite implements Component {      // 2. "Isa" relationship
   private Component[] children = new Component[9];  // 3. Couple to interface
   private int         total    = 0;
   private int         value;
   public Composite( int val )    { value = val; }
   public void add( Component c ) { children[total++] = c; } // 3. Couple to
   public void traverse() {                                  //    interface
      System.out.print( value + "  " );
      for (int i=0; i < total; i++)
          children[i].traverse();            // 4. Delegation and polymorphism
}  }

class Row extends Composite {                // Two different kinds of "con-
   public Row( int val ) { super( val ); }   // tainer" classes.  Most of the
   public void traverse() {                  // "meat" is in the Composite
      System.out.print( "Row" );             // base class.
      super.traverse();
}  }

class Column extends Composite {
   public Column( int val ) { super( val ); }
   public void traverse() {
      System.out.print( "Col" );
      super.traverse();
}  }

public class CompositeDemo {
   public static void main( String[] args ) {
      Composite first  = new Row( 1 );          // Row1
      Composite second = new Column( 2 );       //   |
      Composite third  = new Column( 3 );       //   +-- Col2
      Composite fourth = new Row( 4 );          //   |     |
      Composite fifth  = new Row( 5 );          //   |     +-- 7
      first.add( second );                      //   +-- Col3
      first.add( third  );                      //   |     |
      third.add( fourth );                      //   |     +-- Row4
      third.add( fifth  );                      //   |     |     |
      first.add(  new Primitive( 6 ) );         //   |     |     +-- 9
      second.add( new Primitive( 7 ) );         //   |     +-- Row5
      third.add(  new Primitive( 8 ) );         //   |     |     |
      fourth.add( new Primitive( 9 ) );         //   |     |     +-- 10
      fifth.add(  new Primitive(10 ) );         //   |     +-- 8
      first.traverse();                         //   +-- 6
}  }

// Row1  Col2  7  Col3  Row4  9  Row5  10  8  6




// Purpose.  Composite design pattern.  A static attribute in the Entity
// base class can be manipulated by each Box object to control indentation.

import java.util.List;
import java.util.ArrayList;

abstract class Entity {
    protected static StringBuffer indent = new StringBuffer();
    public abstract void traverse();
}

class Product extends Entity {
    private int value;
    public Product( int val ) { value = val; }
    public void traverse() {
        System.out.println( indent.toString() + value );
}   }

class Box extends Entity {
    private List children = new ArrayList();
    private int  value;
    public Box( int val )       { value = val; }
    public void add( Entity c ) { children.add( c ); }
    public void traverse() {
        System.out.println( indent.toString() + value );
        indent.append( "   " );
        for (int i=0; i < children.size(); i++)
            ((Entity)children.get(i)).traverse();
        indent.setLength( indent.length() - 3 );
}   }

public class CompositeLevels {
    public static void main( String[] args ) {
        Box root = initialize();
        root.traverse();
    }

    private static Box initialize() {
        Box[] nodes = new Box[7];
        nodes[1] = new Box( 1 );
        int[] s = { 1, 4, 7 };
        for (int i=0; i < 3; i++) {
            nodes[2] = new Box( 21+i );
            nodes[1].add( nodes[2] );
            int lev = 3;
            for (int j=0; j < 4; j++) {
                nodes[lev-1].add( new Product( lev*10 + s[i] ) );
                nodes[lev] = new Box( lev*10 + s[i]+1 );
                nodes[lev-1].add( nodes[lev] );
                nodes[lev-1].add( new Product( lev*10 + s[i]+2 ) );
                lev++;
        }   }
        return nodes[1];
}   }

/****************
1
   21
      31
      32
         41
         42
            51
            52
               61
               62
               63
            53
         43
      33
   22
      34
      35
         44
         45
            54
            55
               64
               65
               66
            56
         46
      36
   23
      37
      38
         47
         48
            57
            58
               67
               68
               69
            59
         49
      39
****************/




// Purpose.  User-configurable "views" of a Composite.  A second static
// attribute is used to remember the "current level" of the traversal.

import java.util.List;
import java.util.ArrayList;

abstract class Entity {
    protected static StringBuffer indent = new StringBuffer();
    protected static int level = 1;
    public abstract void traverse( int[] levels );
    protected boolean printThisLevel( int[] levels ) {
        for (int i=0; i < levels.length; i++)
            if (level == levels[i])
                return true;
        return false;
}   }

class Product extends Entity {
    private int value;
    public Product( int val ) { value = val; }
    public void traverse( int[] levels ) {
        if (printThisLevel( levels ))
            System.out.println( indent.toString() + value );
}   }

class Box extends Entity {
    private List children = new ArrayList();
    private int  value;
    public Box( int val )       { value = val; }
    public void add( Entity c ) { children.add( c ); }
    public void traverse( int[] levels ) {
        if (printThisLevel( levels )) {
            System.out.println( indent.toString() + value );
            indent.append( "   " );
        }
        level++;
        for (int i=0; i < children.size(); i++)
            ((Entity)children.get(i)).traverse( levels );
        level--;
        if (printThisLevel( levels ))
            indent.setLength( indent.length() - 3 );
}   }

public class CompositeLevelsAns {
    public static void main( String[] args ) {
        Box root = initialize();
        int[] levels = new int[args.length];
        for (int i=0; i < args.length; i++)
            levels[i] = Integer.parseInt( args[i] );
        root.traverse( levels );
    }

    private static Box initialize() {
        Box[] nodes = new Box[7];
        nodes[1] = new Box( 1 );
        int[] s = { 1, 4, 7 };
        for (int i=0; i < 3; i++) {
            nodes[2] = new Box( 21+i );
            nodes[1].add( nodes[2] );
            int lev = 3;
            for (int j=0; j < 4; j++) {
                nodes[lev-1].add( new Product( lev*10 + s[i] ) );
                nodes[lev] = new Box( lev*10 + s[i]+1 );
                nodes[lev-1].add( nodes[lev] );
                nodes[lev-1].add( new Product( lev*10 + s[i]+2 ) );
                lev++;
        }   }
        return nodes[1];
}   }

/***************************************
D:\java> java CompositeLevelsAns 2 4 6
21
   41
   42
      61
      62
      63
   43
22
   44
   45
      64
      65
      66
   46
23
   47
   48
      67
      68
      69
   49

D:\java> java CompositeLevelsAns 3 6
31
32
   61
   62
   63
33
34
35
   64
   65
   66
36
37
38
   67
   68
   69
39

D:\java> java CompositeLevelsAns 1 2 3 4 5 6
1
   21
      31
      32
         41
         42
            51
            52
               61
               62
               63
            53
         43
      33
   22
      34
      35
         44
         45
            54
            55
               64
               65
               66
            56
         46
      36
   23
      37
      38
         47
         48
            57
            58
               67
               68
               69
            59
         49
      39
***************************************/