
import java.applet.Applet;
import java.awt.*;
import java.util.Vector;

/**  class  DecisionDiagram
 *   DecisionDiagram is the diagram for decision syntax
 *   Constructors exist for 2, 3, or 4 diagrams
 *   An additional constructor for an array of diagrams
 *   requires the size of the array as its last parameter
 *   This diagram lays out the alternative syntax diagrams
 *   using the IfConnector.
 */
public class DecisionDiagram extends Diagram{

    //  constructors for 2, 3, and 4 branches have the same basic logic
    //
    //  create an array of diagrams to send on the the inner diagram
    //
    //  set the connector location to the connector location of the
    //  first diagram
    //
    //  create an IfConnector for each end, sending the connector location
    //  and height of each diagram as parameters
    //
    //  create an inner diagram object sending the array and the number
    //  of elements in the array
    //
    //  add the begin connector, inner diagram and end connector to the
    //  diagram

    //  2 branch constructor
    public DecisionDiagram(Diagram diagram1,
                        Diagram diagram2) {

        Diagram [] diag = new Diagram [2];
        diag[0] = diagram1;
        diag[1] = diagram2;
        setLayout (new SequentialLayout());
        connectorLocation = diagram1.connectorLocation;
        Dimension size1 = diagram1.preferredSize();
        Dimension size2 = diagram2.preferredSize();
        Diagram connect = new IfConnector ("begin",
					   diagram1.connectorLocation,
					   size1.height,
					   diagram2.connectorLocation,
					   size2.height);
        add (connect);
        Diagram inner = new InnerDiagram (diag, 2);
        add (inner);
        Diagram connectEnd = new IfConnector ("end",
					      diagram1.connectorLocation,
					      size1.height,
					      diagram2.connectorLocation,
					      size2.height);
        add (connectEnd);
    }

    //3 branches
    public DecisionDiagram(Diagram diagram1,
                        Diagram diagram2,
                        Diagram diagram3) {

        Diagram [] diag = new Diagram [3];
        diag[0] = diagram1;
        diag[1] = diagram2;
        diag[2] = diagram3;
        setLayout (new SequentialLayout());
        connectorLocation = diagram1.connectorLocation;
        Dimension size1 = diagram1.preferredSize();
        Dimension size2 = diagram2.preferredSize();
        Dimension size3 = diagram3.preferredSize();
        Diagram connect = new IfConnector ("begin",
                            diagram1.connectorLocation, size1.height,
                            diagram2.connectorLocation, size2.height,
                            diagram3.connectorLocation, size3.height);
        add (connect);
        Diagram inner = new InnerDiagram (diag, 3);
        add (inner);
        Diagram connectEnd = new IfConnector ("end",
                            diagram1.connectorLocation, size1.height,
                            diagram2.connectorLocation, size2.height,
                            diagram3.connectorLocation, size3.height);
        add (connectEnd);
    }

    //4 branches
    public DecisionDiagram(Diagram diagram1,
                        Diagram diagram2,
                        Diagram diagram3,
                        Diagram diagram4) {
        Diagram [] diag = new Diagram [4];
        diag[0] = diagram1;
        diag[1] = diagram2;
        diag[2] = diagram3;
        diag[3] = diagram4;

        setLayout (new SequentialLayout());
        connectorLocation = diagram1.connectorLocation;
        Dimension size1 = diagram1.preferredSize();
        Dimension size2 = diagram2.preferredSize();
        Dimension size3 = diagram3.preferredSize();
        Dimension size4 = diagram4.preferredSize();
        Diagram connect = new IfConnector ("begin",
                            diagram1.connectorLocation, size1.height,
                            diagram2.connectorLocation, size2.height,
                            diagram3.connectorLocation, size3.height,
                            diagram4.connectorLocation, size4.height);
        add (connect);
        Diagram inner = new InnerDiagram (diag, 4);
        add (inner);
        Diagram connectEnd = new IfConnector ("end",
                            diagram1.connectorLocation, size1.height,
                            diagram2.connectorLocation, size2.height,
                            diagram3.connectorLocation, size3.height,
                            diagram4.connectorLocation, size4.height);
        add (connectEnd);
    }

    //any number of branches from an array of Diagrams

    public DecisionDiagram(Diagram [] diag, int num) {
	initFromArray(diag, num);
    }

    //any number of branches from a Vector of Diagrams

    public DecisionDiagram(Vector vect) {
	int size = vect.size();
	Diagram [] diag = new Diagram[size];
	vect.copyInto((Object[])diag);

	if (size > 0) {
            initFromArray(diag, size);
	} else {
	    System.out.println("Error instantiating DecisionDiagram");
	    System.out.println("    Diagram vector parameter is empty");
	}
    }

    //  create arrays to store the terminal Locations and
    //  heights of each diagram in the diag array

    //  store the term location and height in the arrays

    //  create connectors using the arrays as parameters

    //  create an inner diagram sending the diag array and
    //  size of diag array

    //  add the connectors and inner diagrams to the diagram

    private void initFromArray(Diagram [] diag, int num) {
        int [] termLoc = new int [num];
        int [] height = new int [num];
        setLayout (new SequentialLayout());
        connectorLocation = diag[0].connectorLocation;
        for (int i = 0; i < num; i++){
            Dimension size = diag[i].preferredSize();
            termLoc [i] =  diag [i].connectorLocation;
            height [i] = size.height;
        }
        Diagram connect = new IfConnector ("begin", termLoc, height, num);
        add (connect);
        Diagram inner = new InnerDiagram (diag, num);
        add (inner);
        Diagram connectEnd = new IfConnector ("end", termLoc, height, num);
        add (connectEnd);
    }
}

/** class InnerDiagram
 *  puts together the inner part of the decision structure
 *  each diagram is added using the vertical layout interface
 *  diagrams smaller than the widest are extended to fit
 */
class InnerDiagram extends Diagram{

    //  InnerDiagram
    //
    //    make an array to hold the sizes of the diagrams sent
    //
    //  set the connector location as the locatio of the first
    //  diagram
    //
    //  use the vertical layout manager
    //
    //  load the size array and accumulate the total width of
    //  the completed diagram
    //
    //  use a loop to check to see if the width of the diagram
    //  being added is greater than the total width.  If so,
    //  extend it using Xdiagram
    //  add the diagram to inner diagram

    public InnerDiagram(Diagram [] diag, int num) {
        int width = 0;
        Dimension [] size = new Dimension [num];
        connectorLocation = diag [0].connectorLocation;
        setLayout (new VerticalLayout());
        for (int i = 0; i < num; i++){
            size [i] = diag [i].preferredSize();
            width = Math.max(size [i].width, width);
        }
        for (int i = 0; i < num; i++){
            if (width > size [i].width){
                Diagram newdiagram = new Xdiagram(width - size[i].width,
						  diag[i]);
                add (newdiagram);
            }
            else
                add (diag[i]);
        }
    }
}
