/* ---------------------------------------------------------------
 File:                           Analyzer.java
 Package:                        FSM Analyzer 2.0
 Author:                         Dr. Ratnesh Kumar and Greg Stamp
 V2.0 10/28/2006
 Initial Developers: Bharath Oruganti
 ---------------------------------------------------------------*/
 
/*
 * Dr. Ratnesh Kumar, Greg Stamp.
 * Department of Electrical and Computer Engineering
 * Iowa State University
 * October, 2006.
 *
 * Copyright (c) 2006
 * All rights reserved.
 */

package mainAnalyzer;


import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.applet.Applet;
import javax.swing.*;
import flap.*;


// **********************************
// * This class provides the Applet
// **********************************
public class Analyzer extends Applet {

	static final long serialVersionUID = 1L;
    // For easy access to workingDirectory and fileSeparator values
    public final static String fileSeparator = System.getProperty(
            "file.separator");
    public final static String workingDirectory = System.getProperty("user.dir");

    // Data members
    static AnalyzerFrame appFrame = null;
    Toolkit   toolKit = Toolkit.getDefaultToolkit();
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

    // this member controls all opened Environment windows
    // made public for use by Environment.java
    public static flap.MainMenu flapMainMenu = null;

    TextArea  taText;
    public static int UserMode = 0; // added UserMode determines if files and help window pop-up
    Choice    cFontNames, cFontSizes;
    Checkbox  cbItalic, cbBold;
    Label     statusBar, mylabel;
    String OPER; // the output file for currently chosen application function (refer to decada.c).
    String VAR; // the parameter for currently chosen application function.
    int INPUTSIZE; // the number of input files for currently chosen application function.
    String HELPFILE; // the help file for currently chosen application function.
    static String MI_NEW = "New",
            MI_OPEN = "Open",
            MI_SAVE = "Save",
            MI_SAVEAS = "Save As", 
            MI_EXIT = "Exit", // putting in menu use upper right
            MI_SHOWGRAPHIC = "Show Graphic",
            MI_RUN = "Run",
            MI_REFRESH = "Refresh",
            CONT_MASK_TABLE = "Controllability/Masking Table";
		   
    Vector MENU = new Vector(2, 2);
    MenuInfo m = new MenuInfo();
    AddMenuFrame amf;
    DeleteMenuFrame dmf;
    String newmenu = new String();
	
    static String myFontString[];

    static String		    
            YES = "Yes",
            COMP_MA = "Complete User Manual",
            FSM_AN = "DECADA Analysis",
            FSM_DE = "DECADA Design",
            // added		
            DEV_HELP = "For Developers",
            STATE_MACHINE = "State Machine",
            ADVANCED = "Advanced",
            BEGINNER = "Beginner",
            FONT = "Font",
            DEF_FNAME = "Helvetica",
            DEF_FSIZE = "14",
            NEW_FILE = "untitled.txt";

    StringBuffer currFile = null;
    boolean inAnApplet = true, Edited = false, showStatusMsgInBrowser = true;
    Panel topPanel, fontPanel, buttonPanel;
    Image iconImage;

    // "main" invoked when run as an application
    public static void main(String args[]) {
        // Open AppSettings file
        File file = new File("AppSettings"); 
        BufferedReader inFile = null;
        String line = null;
    
        if (file.exists()) { 
            try {
                inFile = new BufferedReader(new java.io.FileReader(file));
            } catch (java.io.FileNotFoundException exp) {
                System.out.println("Error opening AppSettings file");  
                exp.printStackTrace();
            }

            try {
                line = inFile.readLine();
            } catch (java.io.IOException exp) {
                exp.printStackTrace();
            }

            UserMode = Integer.parseInt(line);
	
            try {
                inFile.close();
            } catch (java.io.IOException exp) {
                exp.printStackTrace();
            }
        }

        if (args.length > 0) {
            appFrame = new AnalyzerFrame(new Analyzer(), args[0]);
        } else {
            appFrame = new AnalyzerFrame(new Analyzer(), null);
        }
    }

    // "init" invoked automatically when run as an
    // applet or if directly called by another class
    public void init() {
        setBackground(new Color(225, 225, 225));

        // Initialize variables
        currFile = new StringBuffer(NEW_FILE);

        flapMainMenu = new flap.MainMenu(null, inAnApplet);

        // all event listeners
        AnalyzerActionListener allListener = new AnalyzerActionListener();
        MyItemListener myItemListener = new MyItemListener();
	  
        // List of Font Names
        cFontNames = new Choice();
        for (int i = 0; i < ge.getAvailableFontFamilyNames().length; i++) {
            cFontNames.addItem(ge.getAvailableFontFamilyNames()[i]);
        }
        cFontNames.select(DEF_FNAME);
        cFontNames.addItemListener(myItemListener);

        // List of Font Sizes
        cFontSizes = new Choice();
        cFontSizes.addItem("8");
        cFontSizes.addItem("10");
        cFontSizes.addItem("12");
        cFontSizes.addItem("14");
        cFontSizes.addItem("18");
        cFontSizes.addItem("24");
        cFontSizes.addItem("48");
        cFontSizes.select(DEF_FSIZE);
        cFontSizes.addItemListener(myItemListener);
        
	// Font Tool Bar 
        // moving inline with buttons
        fontPanel = new Panel();
        fontPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        fontPanel.add(cFontNames);
        fontPanel.add(cFontSizes);

        // Push Button Tool Bar
        buttonPanel = new Panel();
        buttonPanel.setFont(new Font("Helvetica", Font.BOLD, 10));
        Button showgraphicButton, runButton, refreshButton;
        buttonPanel.add(runButton = new Button(MI_RUN));
        buttonPanel.add(showgraphicButton = new Button(MI_SHOWGRAPHIC));
        buttonPanel.add(refreshButton = new Button(MI_REFRESH));
        runButton.addActionListener(allListener);
        showgraphicButton.addActionListener(allListener);
        refreshButton.addActionListener(allListener);
        buttonPanel.add(
        mylabel = new Label("Current Application" + 
			    "                                             "));
        mylabel.setBackground(new Color(150, 200, 255));

        // Top of screen panel
        topPanel = new Panel();
        topPanel.setLayout(new BorderLayout(1, 2));
        topPanel.add("West", buttonPanel);
        topPanel.add("South", fontPanel);

        // Text Editing Area
        taText = new TextArea(24, 31);
        taText.setBackground(Color.white);
        taText.addKeyListener(new TextAreaKeyListener());

        // Status Bar
        statusBar = new Label(NEW_FILE, Label.LEFT);

        // Add Panels to Applet (a Panel itself)
        setLayout(new BorderLayout(1, 2));
        add("North", topPanel);
        add("Center", taText);

        super.enableEvents(AWTEvent.WINDOW_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
        setTextFont();
    }

    // Set padding for fill3DRect() in paint()
    public Insets getInsets() {
        return new Insets(4, 4, 4, 4);
    }

    public void callProcessEvent(AWTEvent evt) {
        processEvent(evt);
    }
   
    protected void processEvent(AWTEvent evt) {

        if (evt.getID() == Event.WINDOW_DESTROY) {
            terminate(0);
        } else if (evt.getSource() instanceof TextArea) {
            if (evt.getID() == Event.KEY_PRESS) {
                Edited = true;
            }

        }
    }

    protected void setTextFont() {
        // Set TextArea to requested font
        Integer i = new Integer(cFontSizes.getSelectedItem());
        int style = Font.BOLD;

        taText.setFont(
                new Font(cFontNames.getSelectedItem(), style, i.intValue()));
    }

    protected void newFile() {
        saveWarning();
        // Clear screen for new file
        taText.setText("");
        currFile.setLength(0);
        currFile.append(NEW_FILE);
        statusMsg(NEW_FILE);
    }

    protected void readFiletoVar(String filename) {
 
        try {
            new ReadFileVar(filename, MENU);
        } catch (FileNotFoundException e) {
            System.err.println(e.toString());
        } catch (IOException e) {
            System.err.println(e.toString());
        }
 
    }

    // Read a local file
    protected void readFile(String filename) {
        saveWarning();

        statusMsg("Please wait...");
        try {
            new ReadFile(filename, taText);
            currFile.setLength(0);
            currFile.append(filename);
            statusMsg(currFile.toString());
        } catch (FileNotFoundException e) {
            showCatchError(e);
        } catch (IOException e) {
            showCatchError(e);
        } finally {
            statusMsg("");
        }
    }

    // Write to local file
    protected void writeFile(String filename) {
        statusMsg("Please wait...");
        try {  
            new WriteFile(filename, taText);
            currFile.setLength(0);
            currFile.append(filename);
            statusMsg(currFile.toString());
            Edited = false;
        } catch (IOException e) {
            showCatchError(e);
        } finally {
            statusMsg("");
        }
    }

    protected void statusMsg(String msgText) {
        statusBar.setText(msgText);
        if (inAnApplet && showStatusMsgInBrowser) {
            showStatus(msgText);
        }
    }
   
    protected void showCatchError(Throwable e) {
        statusMsg(e.toString());
        if (inAnApplet) {
            showStatus(e.getMessage());
        } else {
            System.err.println(e.getMessage());
        }
    }

    /* Ask if user wants to save file if it's been modified. 
       Returns true if user chooses yes/no or file is not modified. 
       Retuns false if user cancels the action */
    protected boolean saveWarning() { 
        boolean retValue = true;

        if (Edited == true) {
            int choice = JOptionPane.showConfirmDialog(this,
                    "Data on text area is not yet saved. Do you want to save it?",
                    "File is modified.", JOptionPane.YES_NO_CANCEL_OPTION);  

            if (choice == JOptionPane.YES_OPTION) {
                MenuItem dummyMI = new MenuItem(MI_SAVE);

                dummyMI.addActionListener(new AnalyzerActionListener());
                dummyMI.dispatchEvent(
                        new ActionEvent(dummyMI, Event.ACTION_EVENT, MI_SAVE));
                retValue = true;
            } else if (choice == JOptionPane.NO_OPTION) {
                retValue = true;
            } else if (choice == JOptionPane.CANCEL_OPTION) {
                retValue = false;
            }
            Edited = false;
        }
        return retValue;
    }

    protected void terminate(int rc) {
        saveWarning();
        System.exit(rc);
    }

    class TextAreaKeyListener implements KeyListener {
        public void keyTyped(KeyEvent ke) {
            Edited = true;
        }

        public void keyPressed(KeyEvent ke) {}
	
        public void keyReleased(KeyEvent ke) {}
    }


    class AnalyzerActionListener implements ActionListener {
        String outputFile = null; // moved here for refresh option
        
        String fileSeparator = System.getProperty("file.separator"); //for running decada from commandline
        
        boolean WindowsOS = (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1);


    public void actionPerformed(ActionEvent evt) {
            statusMsg("");
            // Button or Menu item selected
            if (evt.getSource() instanceof Button
                    || evt.getSource() instanceof MenuItem) {
                String menuLabel = evt.getActionCommand();
    
                if (menuLabel.equals(MI_OPEN)) {
                    saveWarning();
                    DoFileDialog fd;

                    try {
                        if (inAnApplet) {
                            setEnabled(false); // Simulate modality
                            fd = new DoFileDialog(null, "Open a File");
                        } else {
                            fd = new DoFileDialog(appFrame, "Open a File");
                        }

                        if (fd.getPath() != null) {
                            readFile(fd.getPath());
                        }
                    } catch (AWTError e) {
                        showCatchError(e);
                        if (inAnApplet) {
                            statusMsg(
                                    e.toString()
                                            + "  (probably due to security restrictions)");
                        }
                    } finally {
                        if (inAnApplet) {
                            setEnabled(true);
                        }
                    }
                } else if (menuLabel.equals(MI_NEW)) {
                    newFile();
                } 
		else if (menuLabel.equals(MI_SAVE)) {
                    if ((currFile == null)
                            || (currFile.toString().trim().equals("") == true)
                            || (currFile.toString().equals(NEW_FILE) == true)) {
                        DoFileDialog fd;
 
                        try {
                            if (inAnApplet) {
                                setEnabled(false); // Simulate modality
                                fd = new DoFileDialog(null, "Save File As",
                                        FileDialog.SAVE);
                            } else {
                                fd = new DoFileDialog(appFrame, "Save File As",
                                        FileDialog.SAVE);
                            }
                            if (fd.getPath() != null) {
                                writeFile(fd.getPath());
                            }
                        } catch (AWTError e) {
                            showCatchError(e);
                            if (inAnApplet) {
                                statusMsg(
                                        e.toString()
                                                + "  (probably due to security restrictions)");
                            }
                        } finally {
                            if (inAnApplet) {
                                setEnabled(true);
                            }
                        }
		
                    } else { 
                        writeFile(currFile.toString());
                    }
                } else if (menuLabel.equals(MI_SAVEAS)) {
                    saveWarning();
                    DoFileDialog fd;

                    try {
                        if (inAnApplet) {
                            setEnabled(false); // Simulate modality
                            fd = new DoFileDialog(null, "Save File As",
                                    FileDialog.SAVE);
                        } else {
                            fd = new DoFileDialog(appFrame, "Save File As",
                                    FileDialog.SAVE);
                        }
                        if (fd.getPath() != null) {
                            writeFile(fd.getPath());
                        }
                    } catch (AWTError e) {
                        showCatchError(e);
                        if (inAnApplet) {
                            statusMsg(
                                    e.toString()
                                            + "  (probably due to security restrictions)");
                        }
                    } finally {
                        if (inAnApplet) {
                            setEnabled(true);
                        }
                    }
                } else if (menuLabel.equals(MI_SHOWGRAPHIC)) {
                    if ((currFile == null)
                            || (currFile.toString().trim().equals(""))
                            || (currFile.toString().equals(NEW_FILE))) {	
                        JOptionPane.showMessageDialog(appFrame,
                                "No file is currently opened on the main window",
                                "Error: No file to be shown",
                                JOptionPane.ERROR_MESSAGE);
                    } else {
                        flapMainMenu.OpenFileAsGraphic(currFile.toString());
                    }
                } else if (menuLabel.equals(MI_EXIT)) {
                    terminate(0);
                } else if (menuLabel.equals(MI_RUN)) {
                    saveWarning();
		    
		    // VAR is set if user has specified an application function to be run
                    if (VAR != null) 
                    {
                        
                        StringBuffer runParam = null;

                        if(WindowsOS)
                             runParam = new StringBuffer("decada " + VAR);
                        else 
                             runParam = new StringBuffer("./decada " + VAR);
                             

                        Frame parentFrame = null;
                        DoFileDialog fd;
 
                        try { 
                            if (!inAnApplet) {
                                parentFrame = appFrame;
                            }

                            int option = JOptionPane.showConfirmDialog(
                                    parentFrame,
                                    "Would you like to specify the input files\n"
                                            + "to the application function you want to run?\n"
                                            + "(Click \"No\" if you'd like to use default files)");

                            if (option == JOptionPane.CANCEL_OPTION) {
                                statusMsg("Run is cancelled...");
                                return;
                            } else if (option == JOptionPane.YES_OPTION) { // Users want to specify their input files
                                JOptionPane.showMessageDialog(
                                        parentFrame,
                                        "Please specify input files according to order\n"
                                                + "described in Help file\n",
                                                "See manual" + " .."
                                                + fileSeparator + "manual"
                                                + fileSeparator + "apps"
                                                + fileSeparator + HELPFILE,
                                                JOptionPane.YES_NO_CANCEL_OPTION);
                                for (int j = 0; j < INPUTSIZE; j++) {
                                    if (inAnApplet) {
                                        setEnabled(false);
                                    }	// Simulate modality 
                                    fd = new DoFileDialog(parentFrame,
                                            "Pick a file");
                                    // ???What if cancel
                                    runParam.append(" " + fd.getPath());
                                }
			
                                OPER = JOptionPane.showInputDialog(
                                        "Please enter the name of output file (without extension)"
                                		+"will be stored in data directory",
                                        "input file?");

                                /* ???What if cancel
                                 if (OPER==JOptionPane.CANCEL_OPTION) {
                                 statusMsg("Run is cancelled...");
                                 return;
                                 }
                                 else*/
                                runParam.append(
                                        " .." + fileSeparator + "data"
                                        + fileSeparator + OPER + ".results");
                                // would like to encapsulate filenames in quotes in case there are spaces in filenames
                                // this causes problems with running decada
                            }

                            try {
                                Runtime run1 = Runtime.getRuntime();
                                Process prcc1 = run1.exec(runParam.toString());
                                BufferedInputStream inStream = new BufferedInputStream(
                                        prcc1.getInputStream());
                                BufferedInputStream errStream = new BufferedInputStream(
                                        prcc1.getErrorStream());
  	         
                                int exitValue = prcc1.waitFor();

                                if (exitValue != 0) {
                                    JOptionPane.showMessageDialog(parentFrame,
                                            "The executable file \"decada\" did not terminate properly. "
                                            + "There might be error in the application run.",
                                            "Error",
                                            JOptionPane.ERROR_MESSAGE);
                                    int last = inStream.available();

                                    for (int i = 0; i < last; i++) {
                                        System.out.print((char) inStream.read());
                                    }
                                    last = errStream.available();
                                    for (int i = 0; i < last; i++) {
                                        System.out.print((char) errStream.read());
                                    }
			    
                                }
                            } catch (Exception ex) {
                                System.out.println(ex.getMessage());
                                terminate(1);
                            }

                            // Moved to larger scope for refresh option String outputFile = null;
                            if (OPER != null) {
                                outputFile = new String(
                                        ".." + fileSeparator + "data"
                                        + fileSeparator + OPER + ".results");
                                readFile(outputFile);

                                /* The following functions do not return an FSM: reachability, normality,
                                   observability,diagnosability,controllability
                                   It would be better to handle this by introducing another variable to the MenuItems file*/
                                if (!(VAR.equals("a") || VAR.equals("W")
                                        || VAR.equals("V") || VAR.equals("X")
                                        || VAR.equals("y"))) {
                                    flapMainMenu.OpenFileAsGraphic(outputFile);
                                } // open output result as a graphic

                            } else {
                                System.out.println(
                                        "Error in reading output file: OPER is null");
                                return;
                            }

                        } catch (Exception e) {
                            System.out.println(e.toString());
                        }
                    } else { // User hasn't chosen application to run before clicking "Run" menuitem.
                        Frame parentFrame = null;

                        if (!inAnApplet) {
                            parentFrame = appFrame;
                        }
                        JOptionPane.showMessageDialog(parentFrame,
                                "Please choose an application function to be run before clicking \"Run\"",
                                "Error", JOptionPane.ERROR_MESSAGE);
                    }
                } else if (menuLabel.equals(MI_REFRESH)) {
                    if (outputFile != null) { // Need to run an application before using refresh
                        readFile(outputFile); //Scenario where file opened but no app run?
                    }
                } else if (menuLabel.equals(ADVANCED)) { 
                    Analyzer.UserMode = 1;
                    File file = new File("AppSettings"); 
                    BufferedWriter inFile = null;
                    //REMOVEDString line = null;
    
                    if (file.exists()) { 
                        try {
                            inFile = new BufferedWriter(
                                    new java.io.FileWriter(file));
                        } catch (java.io.IOException exp) {
                            exp.printStackTrace();
                        }

                        try {
                            inFile.write("1");
                            inFile.newLine();
                        } catch (java.io.IOException exp) {
                            exp.printStackTrace();
                        }
	
                        try {
                            inFile.close();
                        } catch (java.io.IOException exp) {
                            exp.printStackTrace();
                        }
                    }
                } // end advanced else if
                else if (menuLabel.equals(BEGINNER)) { 
                    Analyzer.UserMode = 0;
                    File file = new File("AppSettings"); 
                    BufferedWriter inFile = null;
                    //REMOVEDString line = null;
    
                    if (file.exists()) { 
                        try {
                            inFile = new BufferedWriter(
                                    new java.io.FileWriter(file));
                        } catch (java.io.IOException exp) {
                            exp.printStackTrace();
                        }

                        try {
                            inFile.write("0");
                            inFile.newLine();
                        } catch (java.io.IOException exp) {
                            exp.printStackTrace();
                        }
	
                        try {
                            inFile.close();
                        } catch (java.io.IOException exp) {
                            exp.printStackTrace();
                        }
                    }
                }
                else if (menuLabel.equals(FSM_DE)) {
                    mylabel.setText("DECADA DESIGN");
                    OtherTFrame ot = new OtherTFrame(new OtherT(),
                            "DECADA ANALYZER [HELP ON DECADA DESIGNER]",
                            "../manual/part2.tex");

                    if (!inAnApplet) {
                        ot.setLocation(appFrame.getX() + 30,
                                appFrame.getY() + 30);
                    }
                } else if (menuLabel.equals(COMP_MA)) {
                    mylabel.setText("COMPLETE USER MANUAL");
                    TutorialFrame tp = new TutorialFrame(new Tutorial(),
                            "COMPLETE USER MANUAL FOR F.S.M. ANALYZER",
                            "../manual/trans.tex");

                    if (!inAnApplet) {
                        tp.setLocation(appFrame.getX() + 30,
                                appFrame.getY() + 30);
                    }
                } else if (menuLabel.equals(FSM_AN)) {
                    mylabel.setText("DECADA ANALYSIS");
                    OtherTFrame ot = new OtherTFrame(new OtherT(),
                            "DECADA ANALYZER [HELP ON DECADA ANALYSIS]",
                            "../manual/part1.tex");

                    if (!inAnApplet) {
                        ot.setLocation(appFrame.getX() + 30,
                                appFrame.getY() + 30);
                    }
                } else if (menuLabel.equals(DEV_HELP)) {
                    mylabel.setText("Help For Developers");
                    OtherTFrame ot = new OtherTFrame(new OtherT(),
                            "Help for Developers", "../manual/developerHelp.tex");

                    if (!inAnApplet) {
                        ot.setLocation(appFrame.getX() + 30,
                                appFrame.getY() + 30);
                    }
                } else if (menuLabel.equals(STATE_MACHINE)) {
                    mylabel.setText("ST. MACH. DIAGRAMS"); {
                        saveWarning();
                        DoFileDialog fd;
 
                        try {
                            flapMainMenu.postEvent(
                                    new Event(new Button(), Event.ACTION_EVENT,
                                    flap.MainMenu.STR_FSA));
                        } catch (Exception e) {
                            System.out.println(e.toString());
                        }
                    }

                } else if (menuLabel.equals(CONT_MASK_TABLE)) { 
		// opens a table in which user may put in controllability/masking information.	

                    InputFileFrame iff = new InputFileFrame(appFrame);
	      
                } else if (evt.getSource() instanceof MenuItem) {

                    for (int i = 0; i < MENU.size(); i++) {
                        m = (MenuInfo) MENU.elementAt(i);
                        if (evt.getActionCommand().equals(m.gettitle())) {
                            InputFrame ip[] = { null, null, null, null, null};
                            
                            mylabel.setText(m.gettitle());
                            OPER = m.getoutput();
                            VAR = m.getparameter();
                            INPUTSIZE = m.getinputsize();
                            HELPFILE = m.gethelpfile();
                            int AppFrameRightEdge = appFrame.getX()
                                    + appFrame.getWidth(); // put pop-up windows to right of main window
                            
		            // If UserMode = 0 (Beginner) then display default input files and help info
			    if (UserMode == 0) {
                                 
                                /*close previously opened windows*/
                                Frame[] frames = Frame.getFrames();
                                for (int f=0; f < frames.length; f++)
                                    {
                                       if(frames[f].getTitle().indexOf("Input Window")!=-1 ||
                                          frames[f].getTitle().indexOf("Help Window")!=-1)
                                          frames[f].dispose();
                                    }

                                /*open new windows*/
                                for (int j = 0; j < INPUTSIZE; j++) {

                                	ip[j] = new InputFrame(
                                            new Input(flapMainMenu),
                                            " Input Window-" + m.getinputstring(j),
                                            "../data/" + m.getinputstring(j));

                                    if (j == 0) {
                                        ip[j].setLocation(AppFrameRightEdge,
                                                appFrame.getY());
                                    } else {
                                        ip[j].setLocation(AppFrameRightEdge,
                                                ip[j - 1].getY()
                                                + ip[j - 1].getHeight());
                                    }
                                }
                                GuiIndexFrame gi = new GuiIndexFrame(
                                        new GuiIndex(), "Help Window ",
                                        "../manual/apps/" + m.gethelpfile());
                                //changed to put under main window
                                gi.setLocation(appFrame.getX(),
                                        appFrame.getY()
                                        + appFrame.getHeight());
                            }// end usermode if
                        }
                    }
                }
            }
            taText.requestFocus();
        }// end of actionPerformed
    }// end of AnalyzerActionListener class
   

    class MyItemListener implements ItemListener {
        public void itemStateChanged(ItemEvent evt) {
       
            // Font name, style or size change
            if (evt.getSource() instanceof Choice
                    || evt.getSource() instanceof Checkbox) {
                setTextFont();
            }
        }// end of itemStateChanged method
    }// end of MyItemListener class
}


// **************************************
// * This provides a frame for the Applet
// **************************************
class AnalyzerFrame extends JFrame {
    
	static final long serialVersionUID = 1L;
	Analyzer teApplet;

    public AnalyzerFrame(Analyzer t, 
            String openWithFile) {
        super("DECADA: Discrete-Event Control & Diagnosis Analyzer");
        teApplet = t;
        teApplet.readFiletoVar("MenuItems"); 

        // Build File Menu
        Menu fm = new Menu("File");
        fm.add(new MenuItem(Analyzer.MI_NEW));
        fm.add(new MenuItem(Analyzer.MI_OPEN));
        fm.add(new MenuItem(Analyzer.MI_SAVE));
        fm.add(new MenuItem(Analyzer.MI_SAVEAS));
        fm.add(new MenuItem("-"));
        fm.add(new MenuItem(Analyzer.MI_EXIT));
        fm.addActionListener(teApplet.new AnalyzerActionListener());
       
        // Build Applications Menu
        Menu Ap1 = new Menu("Applications");
        for (int i = 0; i < teApplet.MENU.size(); i++) {
            teApplet.m = (MenuInfo) teApplet.MENU.elementAt(i);
            String str = new String(teApplet.m.gettitle());

            Ap1.add(new MenuItem(str));
        }
        Ap1.addActionListener(teApplet.new AnalyzerActionListener());
        
	//Build Draw Menu
        Menu Dr = new Menu("Draw");
        Dr.add(new MenuItem(Analyzer.STATE_MACHINE));
        Dr.add(new MenuItem(Analyzer.CONT_MASK_TABLE));
        Dr.addActionListener(teApplet.new AnalyzerActionListener());
	
        // Build Settings Menu
        Menu Sg = new Menu("Settings");
        Menu Sg_mode = new Menu("User Mode");
        Sg_mode.add(new MenuItem(Analyzer.ADVANCED));
        Sg_mode.add(new MenuItem(Analyzer.BEGINNER));
        Sg.add(Sg_mode);
        // Move font settings here in future
        Sg.addActionListener(teApplet.new AnalyzerActionListener());
        Sg_mode.addActionListener(teApplet.new AnalyzerActionListener());

        // Build Help Menu
        Menu Hp = new Menu("Help");
        Hp.add(new MenuItem(Analyzer.COMP_MA));
        Hp.add(new MenuItem(Analyzer.FSM_AN));
        Hp.add(new MenuItem(Analyzer.FSM_DE));
        // moving developer help here
        Hp.add(new MenuItem(Analyzer.DEV_HELP));
        Hp.addActionListener(teApplet.new AnalyzerActionListener());

        // Add Menu Bar and Menu to Frame
        MenuBar mb = new MenuBar();
        mb.add(fm);
        mb.add(Ap1);
        mb.add(Dr);
        mb.add(Sg); // add settings menu
        mb.add(Hp);
        setMenuBar(mb);

        teApplet.inAnApplet = false;
        // Call init() method as a browser would
        teApplet.init();
        getContentPane().add("Center", teApplet);

        // Open a file if requested
        if (openWithFile != null) {
            teApplet.readFile(openWithFile);
        } 

        super.enableEvents(AWTEvent.WINDOW_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
        pack();
        setVisible(true);
    }

    protected void processEvent(AWTEvent evt) {
        // Forward all events to Applet class
        if (teApplet != null) {
            teApplet.callProcessEvent(evt);
        } else {
            super.processEvent(evt);
        }
    }

}


// ***********************************************
// This reads a file into variables for
// automatic creation of menus
// ************************************************
 
class ReadFiletoVar {
    StringBuffer sb = new StringBuffer();
    ReadFiletoVar(String FileName, Vector v)
        throws IOException,
                FileNotFoundException {
        FileInputStream fis;

        sb = new StringBuffer();
 
        fis = new FileInputStream(FileName);
        int oneChar;
        int i = 0;
 
        while ((oneChar = fis.read()) != -1) {
            if ((char) oneChar == ',') {
                v.addElement(new String(sb.toString()));
                i++;
                sb.setLength(0);
            } else {
                sb.append((char) oneChar);
            }
        }
        v.addElement(new String(sb.toString()));
        fis.close();
    }
}


class AddMenuFrame extends Frame {
	static final long serialVersionUID = 1L;
	TextArea tf;
    String  str = new String();

    public AddMenuFrame() {
        super("Add a new menu item");
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        c.gridx = 6;
        c.gridy = 0;
        tf = new TextArea(1, 30);
        gridbag.setConstraints(tf, c);
        add(tf);
        c.gridx = 0;
        c.gridy = 12;
        Button b1 = new Button("Ok");

        b1.addActionListener(new buttonListener());
        gridbag.setConstraints(b1, c);
        add(b1);
        c.gridx = 4;
        c.gridy = 12;
        Button b2 = new Button("Cancel");

        b2.addActionListener(new buttonListener());
        gridbag.setConstraints(b2, c);
        add(b2);
        setSize(400, 250);
        setVisible(true);
    }

    public String getstring() {
        return tf.getText();
    }

    public String getstringvalue() {
        return str;
    }

    class buttonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            Object o = e.getSource();

            if (o instanceof Button) {
                if (((Button) o).getLabel().equals("Ok")) {
                    str = "\n" + (tf.getText());
                    try {
                        new WriteFileVar("MenuItems", str, true);
                    } catch (Exception e1) {
                        System.out.println(e1.toString());
                    }
                    ((Window) ((Component) e.getSource()).getParent()).setVisible(
                            false);
                    ((Window) ((Component) e.getSource()).getParent()).dispose();
                } else if (((Button) o).getLabel().equals("Cancel")) {
                    ((Window) ((Component) e.getSource()).getParent()).setVisible(
                            false);
                    ((Window) ((Component) e.getSource()).getParent()).dispose();
                }// end of if-elseif
            }// end of outer if
        }// end of actionPerformed
    }// end of buttonListener
}


class DeleteMenuFrame extends Frame {
    
	static final long serialVersionUID = 1L;
	java.awt.List l1;
    Vector v2;
    String items[];
    String  string = new String();

    public DeleteMenuFrame() {}

    public DeleteMenuFrame(Vector v1) {
        super("Delete a new menu item");
        v2 = v1;
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

        setLayout(gridbag);
        c.gridx = 6;
        c.gridy = 0;
        l1 = new java.awt.List(5, true);
        for (int i = 0; i < v1.size(); i++) {
            MenuInfo m1 = (MenuInfo) v1.elementAt(i);

            l1.add(m1.title);
        }
        gridbag.setConstraints(l1, c);
        add(l1);
        c.gridx = 0;
        c.gridy = 12;
        Button b1 = new Button("Ok");

        b1.addActionListener(new buttonListener());
        gridbag.setConstraints(b1, c);
        add(b1);
        c.gridx = 4;
        c.gridy = 12;
        Button b2 = new Button("Cancel");

        b2.addActionListener(new buttonListener());
        gridbag.setConstraints(b2, c);
        add(b2);
        setSize(400, 250);
        setVisible(true);
    }

    boolean isContained(String str, String array[]) {
        boolean flag = false;

        for (int i = 0; i < array.length; i++) {
            if (str == array[i]) {
                flag = true;
            }
        }
        return flag;
    }

    class buttonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            Object o = e.getSource();

            if (o instanceof Button) {
                if (((Button) o).getLabel().equals("Ok")) {
                    boolean flag = false;

                    items = l1.getSelectedItems();
                    for (int i = 0; i < v2.size(); i++) {
                        MenuInfo m = (MenuInfo) v2.elementAt(i);

                        if (isContained(m.title, items) == false) {
                            string = "";
                            string += m.title + "(";
                            for (int j = 0; j < m.input.size(); j++) {
                                string += (String) m.input.elementAt(j);
                                string += ",";
                            }
                            string += m.output + ":" + m.helpfile + "@"
                                    + m.parameter + ");";
                            try {
                                if (flag == false) {
                                    new WriteFileVar("MenuItems", string, false);
                                    flag = true;
                                } else {
                                    new WriteFileVar("MenuItems", string, true);
                                }
                            } catch (Exception e1) {
                                System.out.println(e1.toString());
                            }
                        }// end of if (isContained...)
                    }// end of for loop
                    ((Window) ((Component) e.getSource()).getParent()).setVisible(
                            false);
                    ((Window) ((Component) e.getSource()).getParent()).dispose();
                } else if (((Button) o).getLabel().equals("Cancel")) {
                    ((Window) ((Component) e.getSource()).getParent()).setVisible(
                            false);
                    ((Window) ((Component) e.getSource()).getParent()).dispose();
                }// end of if-elseif
            }// end of outer if
        }// end of actionPerformed
    }// end of buttonListener
}

