import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;


public class GUI1 implements SchemeTesterInterface1 { 

    JFrame guiFrame;
    Container guiPane;
    JScrollPane gPane, tablePane, commentsPane;

    JLabel frameLabel, nameLabel, labLabel, codefileLabel, spcaseLabel, 
        tableLabel, sendToLabel, senderLabel, subjectLabel, commentsLabel;
    JTextField nameField, labField, codefileField, spcaseField, tableField, 
        sendToField, senderField, subjectField, commentsField;
    JButton runtestButton, submitButton;

    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints gridcons = new GridBagConstraints();

    boolean nameAvailable;
    boolean labAvailable;
    boolean codefileAvailable;
    boolean spcaseAvailable;
    
    boolean runtestButtonPressed;

    public GUI1() {
       // Set the look and feel
       try {
           UIManager.setLookAndFeel(
               UIManager.getCrossPlatformLookAndFeelClassName());
       } catch(Exception e) {}

       // Create the frame and container
       guiFrame = new JFrame("Scheme Tester");
       guiPane = guiFrame.getContentPane();
       guiPane.setSize(800, 500); 

       gridbag = new GridBagLayout();
       gridcons = new GridBagConstraints();
       guiPane.setLayout(gridbag);

       // Add the window elements for round 1
       addFirstWidgets ();
       
       // Handle button events
       // run test button
       runtestButton.addActionListener(new sendInfoAction (this));
       
       // Exit when window is closed
       guiFrame.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {
               System.exit(0);
           }
       });

       runtestButtonPressed = false;
       
       // show the gui
       guiFrame.pack();
       guiFrame.setVisible(true);
    }

    // method to place first round of window elements in appropriate positions
    private void addFirstWidgets() {
        
        // Lay out each window element
        // Processing proceeds row by row

        // Row 1
        // place overall title
        gridcons.gridx = 0;
        gridcons.gridy = 0;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 2;
        frameLabel = new JLabel ("Welcome to the Scheme Testing Program");
        frameLabel.setBorder(BorderFactory.createEmptyBorder(30, 100, 10, 100));
        gridbag.setConstraints(frameLabel, gridcons);
        guiPane.add(frameLabel, SwingConstants.CENTER);

        // Row 2
        // place name label
        gridcons.gridx = 0;
        gridcons.gridy = 1;
        gridcons.gridwidth = 1;
        gridcons.weightx = 0.0;
        nameLabel = new JLabel ("Enter your name:");
        gridbag.setConstraints(nameLabel, gridcons);
        guiPane.add(nameLabel);

        // place name text box
        gridcons.gridx = 1;
        gridcons.gridy = 1;
        nameField = new JTextField(20);
        gridbag.setConstraints(nameField, gridcons);
        guiPane.add(nameField);

        // Row 3
        // place lab number
        gridcons.gridx = 0;
        gridcons.gridy = 2;
        gridcons.gridwidth = 1;
        gridcons.weightx = 0.0;
        labLabel = new JLabel ("Enter the lab number:");
        gridbag.setConstraints(labLabel, gridcons);
        guiPane.add(labLabel);

        // place lab number text box
        gridcons.gridx = 1;
        gridcons.gridy = 2;
        labField = new JTextField(20);
        gridbag.setConstraints(labField, gridcons);
        guiPane.add(labField);

        // Row 4
        // code file label
        gridcons.gridx = 0;
        gridcons.gridy = 3;
        gridcons.gridwidth = 1;
        gridcons.weightx = 0.0;
        codefileLabel = new JLabel ("Enter location of code to be tested:");
        gridbag.setConstraints(codefileLabel, gridcons);
        guiPane.add(codefileLabel);
        
        // code file text box
        gridcons.gridx = 1;
        gridcons.gridy = 3;
        codefileField = new JTextField(20);
        gridbag.setConstraints(codefileField, gridcons);
        guiPane.add(codefileField);
        
        // Row 5
        // special test cases file
        gridcons.gridx = 0;
        gridcons.gridy = 4;
        gridcons.weightx = 0.0;
        gridcons.gridwidth = 1;
        spcaseLabel = new JLabel ("Enter location of special test cases file:");
        gridbag.setConstraints(spcaseLabel, gridcons);
        guiPane.add(spcaseLabel);

        // special test cases file text box
        gridcons.gridx = 1;
        gridcons.gridy = 4;
        spcaseField = new JTextField(20);
        gridbag.setConstraints(spcaseField, gridcons);
        guiPane.add(spcaseField);

        // Row 6
        // Run Test button
        gridcons.gridx = 0;
        gridcons.gridy = 5;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 2;
        runtestButton = new JButton("RUN TEST");
        runtestButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        gridbag.setConstraints(runtestButton, gridcons);
        guiPane.add(runtestButton, SwingConstants.CENTER);

    } // addFirstWidgets

    // method to place second round of window elements in appropriate positions
    private void addSecondWidgets() {
        
        // Row 7
        // place result Table label
        gridcons.gridx = 0;
        gridcons.gridy = 6;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 2;
        tableLabel = new JLabel ("Your Results");
        tableLabel.setBorder(BorderFactory.createEmptyBorder(30, 5, 5, 5));
        gridbag.setConstraints(tableLabel, gridcons);
        guiPane.add(tableLabel, SwingConstants.CENTER);

        // Row 8
        // place result table text box
        gridcons.gridx = 0;
        gridcons.gridy = 7;
        gridcons.ipadx = 0; // make this box wide
        gridcons.ipady = 0; //       and tall
        tableField = new JTextField(100);
        tableField.setEditable(false);
        tableField.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
        tablePane = new JScrollPane(tableField);
        tablePane.setHorizontalScrollBarPolicy
            (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        tablePane.setVerticalScrollBarPolicy
            (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        Dimension preferredSize = new Dimension (400, 200);
        tablePane.setPreferredSize(preferredSize);
        gridbag.setConstraints(tablePane, gridcons);
        guiPane.add(tablePane);

        // Row 9
        // addressee's email address label
        gridcons.gridx = 0;
        gridcons.gridy = 8;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 1;
        sendToLabel = new JLabel ("Enter Instructor's E-mail Address:");
        gridbag.setConstraints(sendToLabel, gridcons);
        guiPane.add(sendToLabel);
        
        // addressee's email address text box
        gridcons.gridx = 1;
        gridcons.gridy = 8;
        sendToField = new JTextField(20);
        gridbag.setConstraints(sendToField, gridcons);
        guiPane.add(sendToField);

        // Row 10
        // sender's email address label
        gridcons.gridx = 0;
        gridcons.gridy = 9;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 1;
        senderLabel = new JLabel ("Enter your E-mail Address:");
        gridbag.setConstraints(senderLabel, gridcons);
        guiPane.add(senderLabel);
        
        // sender's email address text box
        gridcons.gridx = 1;
        gridcons.gridy = 9;
        senderField = new JTextField(20);
        gridbag.setConstraints(senderField, gridcons);
        guiPane.add(senderField);

        // Row 11
        // subject line for email label
        gridcons.gridx = 0;
        gridcons.gridy = 10;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 1;
        subjectLabel = new JLabel ("Enter a subject line for your e-mail:");
        gridbag.setConstraints(subjectLabel, gridcons);
        guiPane.add(subjectLabel);
        
        // subject line field
        gridcons.gridx = 1;
        gridcons.gridy = 10;
        subjectField = new JTextField(20);
        gridbag.setConstraints(subjectField, gridcons);
        guiPane.add(subjectField);

        // Row 12
        // comments label
        gridcons.gridx = 0;
        gridcons.gridy = 11;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 2;
        commentsLabel = new JLabel ("Add any additional comments below");
        commentsLabel.setBorder(BorderFactory.createEmptyBorder(30, 5, 5, 5));
        gridbag.setConstraints(commentsLabel, gridcons);
        guiPane.add(commentsLabel, SwingConstants.CENTER);

        // Row 13
        // comments text box
        gridcons.gridx = 0;
        gridcons.gridy = 12;
        gridcons.ipadx = 0; // make this box wide
        gridcons.ipady = 0; //       and tall
        commentsField = new JTextField(100);
        commentsField.setEditable(true);
        commentsField.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
        commentsPane = new JScrollPane(commentsField);
        commentsPane.setHorizontalScrollBarPolicy
            (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        commentsPane.setVerticalScrollBarPolicy
            (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        Dimension preferredSize2 = new Dimension (400, 200);
        commentsPane.setPreferredSize(preferredSize2);
        gridbag.setConstraints(commentsPane, gridcons);
        guiPane.add(commentsPane);
       

        // Row 14
        // place submit button
        gridcons.gridx = 0;
        gridcons.gridy = 13;
        gridcons.weightx = 0.5;
        gridcons.gridwidth = 2;
        submitButton = new JButton("Submit Results to Instructor");
        submitButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        gridbag.setConstraints(submitButton, gridcons);
        guiPane.add(submitButton, SwingConstants.CENTER);

    } // addSecondWidgets

    private synchronized void waitForClick () {
        try {
            // wait for user to enter size
            wait(500);
        } catch (InterruptedException e) {};
    }

    public String[] getData() {
        // retrieve information from boxes, making sure info has been entered
        while (!labAvailable&&!codefileAvailable&&!spcaseAvailable) {
            waitForClick();
        }
        String[] data = new String[3];
        data[0] = (""+labField.getText());
        data[1] = (""+codefileField.getText());
        data[2] = (""+spcaseField.getText());
        return data;
    } // getData()
    
    public void printResults(String text) {
        // place text in table box
        // add "Submit to Instructor" Button

        // Add the window elements for round 2
        addSecondWidgets ();
        tableField.setText(text);

        // Submit button
        submitButton.addActionListener(new submitAction 
             (sendToField, senderField, subjectField, tableField, commentsField ));
        
        // repack the table to be sure all elements look right
        guiFrame.pack();
    }

} // GUI1

// prepare information to be passed
class sendInfoAction implements ActionListener {
    GUI1 myGUI;

    sendInfoAction (GUI1 gui) {
        myGUI = gui;
    }

    public void actionPerformed (ActionEvent event) {
        myGUI.labAvailable = true;
        myGUI.codefileAvailable = true;
        myGUI.spcaseAvailable = true;
    }
}

// print results
    class submitAction implements ActionListener {
        
        JTextField mySendTo;
        JTextField mySender;
        JTextField mySubject;
        JTextField myResults;
        JTextField myComments;
        submitAction (JTextField sendTo, 
                      JTextField sender, JTextField subject, 
                      JTextField results, JTextField comments) {
            
            mySendTo = sendTo;
            mySender = sender;
            mySubject = subject;
            myResults = results;
            myComments = comments;
        }

        public void actionPerformed (ActionEvent event) {
            try {
            InstructorNotifier1 object = new InstructorNotifier1();
                object.sendEmail(mySendTo.getText(), 
                                 mySender.getText(), 
                                 mySubject.getText(), 
                                 myResults.getText()+'\n'+myComments.getText());
            } catch (IOException exc) {}
        }
    }

