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


/** sets up and displays the syntax diagrams for Curry
 ** (Using setup() function), all the diagrams
 ** are constructed and loaded into the cardlayout.The applet
 ** layout is changed to Cardlayout.

 ** So in the beginning, all the diagrams are in the cardLayout.
 ** The start diagram is displayed first.  If a nonterminal
 ** diagram is the target of a mouse click, the name of the
 ** nonterminal is used to lookup up the corresponding diagram
 ** in the cardLayout .
 ** A stack is used to navigate the diagrams
 */

public class CurryDiagram extends Applet{


	//private Stack stack = new Stack();
	//private int current;
	//private Diagram currentDiagram;
        //private Regular currentRegular;
 	//private Grammar grammar = new Grammar();
 	//private Button b = new Button("back");
	//private String previous, cur_symbol;
	//private CardLayout card_layout ;


        // public Panel app = new MainPanel();
	//private int fontSize = 18;
	//private Font font = new Font ("Dialog", Font.BOLD, fontSize);


	// set up the table
	// layout the screen for the start diagram

	public void init() {
          //setBackground(Color.lightGray);

                add(new MainPanel (this) );

	}

       public static void main  (String [] args) { 
                (new CurryFrame ("Syntax Diagrams")).show(); }



/*****************************************************************
 * Pull the diagrams from the object 'grammar'. The diagrams are 
 * constructed and put into panels and then entered in to
 * the cardlayout.

 * newPanel    : holds the actual diagram
 * Buttonpanel : holds the button, enables future addition of
	         more buttons
 * diagramPanel: holds the newPanel and the Label (Ex start)  and
		 the ButtonPanel
 * outermost   : holds the diagramPAnel and the  Label Curry Diagrams

   The newPanel had to be added to center the diagrams. The outermost
   panel holds all the individual panels.

If the notion of diagrams is changed, the number of Panels can be
reduced.
*******************************************************************/

//	private void setup() { }
 // end setup()


} // end class


class CurryFrame extends Frame {
    /** Construct the frame and add the GUI to it. */

    CurryFrame (String frameTitle) {
       super(frameTitle);
       add("North", new MainPanel (null));
        pack ();
    }
    /** Handle window destroy events */ 
    public boolean handleEvent (Event evt) {
        if (evt.id == Event.WINDOW_DESTROY) System.exit (0);
        return super.handleEvent (evt);
    }
}



class MainPanel extends Panel
{

        private Stack stack = new Stack();
	private int current;
	private Diagram currentDiagram;
        private Regular currentRegular;
 	private Grammar grammar = new Grammar();
 	private Button b = new Button("back");
	private String previous, cur_symbol;
	private CardLayout card_layout ;
	// private Font innerFont ;
	private int fontSize = 18;
	private Font font = new Font ("Dialog", Font.BOLD, fontSize);
       
 	Button n = new Button("back");
	String name;
        String t;
	int numOfDiagrams = grammar.diagramList.size();

	private Font innerFont = new Font ("TimesRoman", Font.ITALIC, 18);

        private final static Dimension wh = new Dimension(900,450);
        public Dimension preferredSize () {  return wh ; }

        MainPanel (Applet ignore)
  {
		setFont(font);
		fontSize = 24;

		// set the layout as cardlayout

		card_layout = new CardLayout();
		setLayout (card_layout);

 

   
       // do this for all the Diagrams in class grammar 
	for(int i = 0; i<numOfDiagrams;i++){
		Panel diagramPanel = new Panel();
		Panel newPanel = new Panel();
	        Panel outermost = new Panel();
		Panel ButtonPanel = new Panel();
                Panel regPanel    = new Panel();
		diagramPanel.setFont(innerFont);
		diagramPanel.setLayout (new BorderLayout());

		outermost.setFont(font);
		outermost.setLayout (new BorderLayout());

        // load the individual diagrams

		currentDiagram = (Diagram)(grammar.diagramList.elementAt(i));
		//newPanel.add ("Center", currentDiagram);
		name = new String((String)grammar.diagramNames.elementAt(i));
                if ( (name.equals("Identifier")) || (name.equals("Nil")) ||
                     (name.equals("StringLiteral")) || (name.equals("Symbol")) ||
                         (name.equals("Anonymous")) || (name.equals("Space")) ||
                                (name.equals("Unit")) ||
                                (name.equals("CharLiteral")) ||
                                (name.equals("Exponent")) ||
                                 (name.equals("Octal") ) ||
                                 (name.equals("Hexadecimal")) ||
                                 (name.equals("Decimal")) 
				 || (name.equals("ModuleIdentifier")) )
                            
                  {
                    //newPanel.add("Center",new Label((String)(grammar.diagramList.elementAt(i))));
                    //currentDiagram = (Diagram)(grammar.diagramList.elementAt(i));
                    regPanel.add("North",currentDiagram);
                    newPanel.add("Center",regPanel);
                    regPanel.setBackground(Color.white);

                  }
                 else
                   {
                    setBackground(Color.lightGray);

                    //currentDiagram = (Diagram)(grammar.diagramList.elementAt(i));
	       //newPanel.add ("Center", currentDiagram);

                    newPanel.add ("Center", currentDiagram);
                   }
		diagramPanel.add ("North", new Label(name));
		diagramPanel.add ("Center", newPanel);
		Button m = new Button("back");
		Button startButton = new Button("start");
	        //ButtonPanel.add ("Center", new Button("back"));

               // disable the button for the start diagram

		if(name.equals("start")) {
			m.disable();
			// Also disable startButton
			startButton.disable();
		}

	        ButtonPanel.add ("Center",startButton );
		ButtonPanel.add ("East", m);
		diagramPanel.add ("South", ButtonPanel);

		//cur_symbol = "start";


		outermost.add ("North",new Label("Curry Diagrams") );
                outermost.add("Center",diagramPanel);
		//outermost.add ("South",new Button("back"));

// add the name of the field to the cardlayout

		add(name,outermost);
                
		//add ("b",ButtonPanel);
	}
   previous = "start";
  
  
	 	card_layout.show(this,"start");
		repaint();

  }


	// if the mouse is clicked on a nonterminal, get the
	// correct diagram from the cardLayout and replace the
	// current diagram with the new one
	public boolean mouseDown (Event evt, int x, int y){

		if (evt.target instanceof NonTerminalDiagram){
 			NonTerminalDiagram theNTD = (NonTerminalDiagram) evt.target;
			theNTD.normal();
			stack.push(previous);
			previous = theNTD.symbol;

	 	card_layout.show(this,theNTD.symbol);
		}
   		return true;
	}


	public boolean action (Event e, Object arg){
		String s ;
 		NonTerminalDiagram theNTD ;

	if(arg.equals("back")){
		if(stack.size() >0) {
		s = (String) stack.pop();

		previous = s;
	 	this.card_layout.show(this,s);
		}

	 return true;
	}
	// Add else for new start button
	else if (arg.equals("start")) {
		// Show the start card
		this.card_layout.show(this, "start");
		return true;
	}
	 return false;

	} // end action




	// brighten the diagram if the mouse enters it
	public boolean mouseEnter (Event evt, int x, int y){
		if (evt.target instanceof NonTerminalDiagram){
			NonTerminalDiagram thisOne = (NonTerminalDiagram) evt.target;
                         if ( (thisOne.symbol.equals("Identifier")) ||
                              (thisOne.symbol.equals("Nil")) ||
                              (thisOne.symbol.equals("Symbol")) ||
                              (thisOne.symbol.equals("StringLiteral")) ||
                               (thisOne.symbol.equals("Anonymous")) ||
                                (thisOne.symbol.equals("Unit")) ||
                                (thisOne.symbol.equals("CharLiteral")) ||
                                (thisOne.symbol.equals("Exponent")) ||
                                 (thisOne.symbol.equals("Octal") ) ||
                                 (thisOne.symbol.equals("Space")) ||
                                 (thisOne.symbol.equals("Hexadecimal")) ||
                                 (thisOne.symbol.equals("Decimal")) ||
				 (thisOne.symbol.equals("ModuleIdentifier")) )
                                  
                          {
                            thisOne.brightenRegular();
                          }
                        else
			    thisOne.brighten();
			thisOne.repaint();
		}
		return true;
	}



	// return the color to normal on the mouse exiting
	public boolean mouseExit (Event evt, int x, int y){
		if (evt.target instanceof NonTerminalDiagram){
			NonTerminalDiagram thisOne = (NonTerminalDiagram) evt.target;
                        if ( (thisOne.symbol.equals("Identifier")) ||
                             (thisOne.symbol.equals("Nil")) ||
                             (thisOne.symbol.equals("Symbol")) ||
                            (thisOne.symbol.equals("StringLiteral")) ||
                               (thisOne.symbol.equals("Anonymous")) ||
                                (thisOne.symbol.equals("Unit")) ||
                               (thisOne.symbol.equals("Space")) ||
                                (thisOne.symbol.equals("CharLiteral")) ||
                                (thisOne.symbol.equals("Exponent")) ||
                                 (thisOne.symbol.equals("Octal") ) ||
                                 (thisOne.symbol.equals("Hexadecimal")) ||
                                 (thisOne.symbol.equals("Decimal")) ||
				 (thisOne.symbol.equals("ModuleIdentifier")) )
                            
                          {
                            thisOne.normalRegular();
                          }
                        else
			    thisOne.normal();

			thisOne.repaint();
		}
		return true;
	}



}














