import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

/**
 * Main panel of MT0
 * 
 * @author Nobo Komagata 
 * @version 5/30/03
 */
public class MainPanel extends Panel implements ActionListener
{
    // Parser instance
    private ShiftReduceParser parser;
    
    // AWT components
    private int columns = 5;
    private int areaWidth = 40;
    private TextArea fileLocArea = 
        new TextArea(MT0.FILELOC, 1, areaWidth, TextArea.SCROLLBARS_NONE);
    private Button loadButton = new Button("Load");
    private TextArea grammarArea = new TextArea(15, areaWidth);

    private TextArea inputArea = 
        new TextArea("", 2, areaWidth, TextArea.SCROLLBARS_VERTICAL_ONLY);

    private Button shiftButton = new Button("Shift");
    private Button reduceButton = new Button("Reduce");
    private Button alternativeButton = new Button("Alternative");
    private Button backButton = new Button("Backtrack");
    private Button resetButton = new Button("Set/Reset");

    private TextArea stackArea = 
        new TextArea("(bottom)[]", 3, areaWidth, TextArea.SCROLLBARS_VERTICAL_ONLY);
    private TextArea messageArea = 
        new TextArea("", 2, areaWidth, TextArea.SCROLLBARS_VERTICAL_ONLY);

    /**
     * Constructor for objects of class MainPanel
     */
    public MainPanel()
    {
        // Use "GridBagC" for simplified layout setting 
        setLayout(new GridBagLayout());

        // Title
        add(new Label(MT0.TITLE, Label.CENTER), 
            new GridBagC(0, 0, GridBagC.REMAINDER, 1));
            
        // File loc
        add(new Label("File Location (local only; also try Example2.txt)", Label.LEFT), 
            new GridBagC(0, GridBagC.RELATIVE, columns - 1, 1));
        add(loadButton, new GridBagC(columns - 1, 1, 1, 1));
        add(fileLocArea, new GridBagC(0, GridBagC.RELATIVE, columns, 1));

        // Grammar
        add(new Label("Grammar (no error checking; debug using Java console)", Label.LEFT), 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));
        add(grammarArea, 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));

        // Input
        add(new Label("Input (case sensitive; space-delimited; RESET after data entry)", Label.LEFT), 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));
        add(inputArea, new GridBagC(0, GridBagC.RELATIVE, columns, 1));

        // Buttons
        add(shiftButton, new GridBagC(0, 7, 1, 1));
        add(reduceButton, new GridBagC(GridBagC.RELATIVE, 7, 1, 1));
        add(alternativeButton, new GridBagC(GridBagC.RELATIVE, 7, 1, 1));
        add(backButton, new GridBagC(GridBagC.RELATIVE, 7, 1, 1));
        add(resetButton, new GridBagC(GridBagC.RELATIVE, 7, 1, 1));

        // Stack
        add(new Label("Stack", Label.LEFT), 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));
        add(stackArea, 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));

        // Message
        add(new Label("Message", Label.LEFT), 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));
        add(messageArea, 
            new GridBagC(0, GridBagC.RELATIVE, GridBagC.REMAINDER, 1));

        // set actionListener for each button
        loadButton.addActionListener(this);
        shiftButton.addActionListener(this);
        reduceButton.addActionListener(this);
        alternativeButton.addActionListener(this);
        backButton.addActionListener(this);
        resetButton.addActionListener(this);
        
        // load and set the default grammar file
        messageArea.setText(loadGrammarFile(MT0.FILELOC));
        parser = new ShiftReduceParser(grammarArea.getText(), "");
   }

    /**
     * Load a grammar file specified in the "Input" area
     * 
     * @param       URL (String)
     * @return      Message
     */
    public String loadGrammarFile(String urlStr)
    {
        try {
            URL url;
            url = new URL(urlStr);
            BufferedReader in = 
                new BufferedReader(new InputStreamReader(url.openStream()));
    
            String line, data = "";
            while((line = in.readLine()) != null) {
                data += (line + "\n");
            }
    
            in.close();
            grammarArea.setText(data);
            return "Info: Grammar file successfully loaded";
        }
        catch (Exception x) {
            grammarArea.setText("");
            return("ERROR: Grammar file access (network)");
        }
    }
    
    /**
     * Event handler (button actions)
     *
     * @param       ActionEvent
     * @return      void
     */
    public void actionPerformed(ActionEvent e)
    {
        messageArea.setText("");
        String msg = "";
        
        if (e.getSource() == loadButton)
            msg = loadGrammarFile(fileLocArea.getText());
    
        if (e.getSource() == resetButton) {
            parser = new ShiftReduceParser(grammarArea.getText(), 
                inputArea.getText());
            msg = "Info: Grammar/input reset; Ready to proceed";
        }
    
        if (e.getSource() == shiftButton)
            msg = parser.shift();
    
        if (e.getSource() == reduceButton)
            msg = parser.reduce();
    
        if (e.getSource() == alternativeButton)
            msg = parser.alternative();
    
        if (e.getSource() == backButton)
            msg = parser.backtrack();
     
        inputArea.setText(parser.input.toStringPlain());
        stackArea.setText(parser.stack.toString());
        messageArea.setText(msg);
    }
}

