/*---------------------------------------------------------------------------
File:         			FSAtoRegExpAskDialog.java
Package:                        JFLAP Version 3.1
Author:			        Ted Hung
                                
Description of Contents:	Contains class FSAtoRegExpAskDialog.
				
--------------------------------------------------------------------------*/

/* 
 * Susan H. Rodger, Magda Procopiuc, Octavian Procopiuc, Eric Gramond, Ted Hung
 * Computer Science Department
 * Duke University
 * August 1999
 * Supported by National Science Foundation DUE-9596002, DUE-9555084,
 *  and DUE-9752583
 *
 * Copyright (c) 1999
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the author.  The name of the author may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

package flap;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

//
//
// FSAtoRegExpAskDialog
//
//
public class FSAtoRegExpAskDialog extends SourceWindow implements ActionListener
{
   //user interface controls
   private Button checkbutton;
   private Button showbutton;
   private Button continuebutton;
   private Canvas paintcanvas;

   //vectors of input text fields
   private Vector nodefield_i;
   private Vector nodefield_j;
   private Vector nodefield_k;

   //vector of RegExpNodes that hold the correct answers
   private Vector answers;

   private Desktop desk;

   public FSAtoRegExpAskDialog(MainMenu mainmenu, Desktop d) 
      throws BadInputException 
   {
      super(mainmenu, mainmenu.isApplet);
      desk = d;

      setTitle("Regular Expression Input Window");

      nodefield_i = new Vector();
      nodefield_j = new Vector();
      nodefield_k = new Vector();
      answers = new Vector();

      setLayout(new BorderLayout(0,0));

      Panel temppanel = new Panel(new GridLayout(2,1));
      temppanel.add(new Label("Input the starting values for the conversion:",
	 Label.CENTER));
      temppanel.add(new Label("(q0 = 0, q1 = 1, q2 = 2, ..., qn = n)", 
	 Label.CENTER));
      add(temppanel, "North");

      //add enough inputs for all of the final states
      State aState = null;
      int numfinal = 0;
      temppanel = new Panel();
      for(Enumeration e = d.theStates.elements(); e.hasMoreElements(); )
      {
	 aState = (State) e.nextElement();
	 if(aState.isFinal)
	 {
	    ++numfinal;
	    Panel p1 = new Panel(new FlowLayout(FlowLayout.CENTER, 0, 0));
	    TextField tempfield;
	    p1.add(new FSAtoRegExpCanvas(aState.id));
	    p1.add(new Label(":  R("));
	    p1.add(tempfield = new TextField("", 3));
	    nodefield_i.addElement(tempfield);
	    p1.add(new Label(" , "));
	    p1.add(tempfield = new TextField("", 3));
	    nodefield_j.addElement(tempfield);
	    p1.add(new Label(" , "));
	    p1.add(tempfield = new TextField("", 3));
	    nodefield_k.addElement(tempfield);
	    p1.add(new Label(" )"));
	    temppanel.add(p1);
	    answers.addElement(new RegExpNode(d.initialState.id,
	       aState.id, d.currentId, 0));
	 }
      }

      if(numfinal == 0)
      {
	 throw new BadInputException("No Final State defined");
      }

      temppanel.setLayout(new GridLayout(numfinal, 1));
      add(temppanel, "Center");

      temppanel = new Panel(new FlowLayout());
      temppanel.add(checkbutton = new Button("Check Answer"));
      temppanel.add(showbutton = new Button("Show Answer"));
      temppanel.add(continuebutton = new Button("Continue..."));
      add(temppanel, "South");

      checkbutton.addActionListener(this);
      showbutton.addActionListener(this);
      continuebutton.addActionListener(this);

      this.pack();
      this.setResizable(false);

      this.addWindowListener(
	 new WindowAdapter()
	 {
	    public void windowClosing(WindowEvent e)
	    {
	       FSAtoRegExpAskDialog.this.ContinueConversion();
	    }
	 }
      );
   }

   public void actionPerformed(ActionEvent h)
   {
      if(h.getSource() == checkbutton)
      {
	 Vector errors = checkCorrect();
	 String message;
	 if(errors.isEmpty())
	 {
	    message = "Your starting expression";
	    if(nodefield_i.size() > 1)
	    {
	       message = message + "s are";
	    }
	    else
	    {
	       message = message + " is";
	    }

	    OKDialog dg = new OKDialog(
		  message + " CORRECT",
		  this, "Regular Expression Conversion");
	    dg.show();
	 }
	 else
	 {
	    message = "INCORRECT starting expression\n";

	    message = message + " for the following final states: \n";

	    for(Enumeration e = errors.elements(); e.hasMoreElements(); )
	    {
	       message = message + "q" + 
		  ((Integer) e.nextElement()).toString() + ", ";
	    }
	    message = message.substring(0, message.length() - 2);

	    OKDialog dg = new OKDialog(message,
	       this, "Regular Expression Conversion");
	    dg.show();
	 }
      }
      else if(h.getSource() == showbutton)
      {
	 for(int x = 0; x < nodefield_i.size(); ++x)
	 {
	    ((TextField) nodefield_i.elementAt(x)).setText(
	       Integer.toString(((RegExpNode) answers.elementAt(x)).i));
	    ((TextField) nodefield_j.elementAt(x)).setText(
	       Integer.toString(((RegExpNode) answers.elementAt(x)).j));
	    ((TextField) nodefield_k.elementAt(x)).setText(
	       Integer.toString(((RegExpNode) answers.elementAt(x)).k));
	 }
      }
      else if(h.getSource() == continuebutton)
      {
	 ContinueConversion();
      }
   }

   /**
    *  checks whether the user input is correct and returns the
    *  final states for which the input is incorrect
    */
   public Vector checkCorrect()
   {
      boolean correct = true;
      boolean checkval;
      Vector errors = new Vector();

      for(int x = 0; x < nodefield_i.size(); ++x)
      {
	 checkval = answers.elementAt(x).toString().equals(
	    "R(" +
	    ((TextField) nodefield_i.elementAt(x)).getText() +
	    ", " +
	    ((TextField) nodefield_j.elementAt(x)).getText() +
	    ", " +
	    ((TextField) nodefield_k.elementAt(x)).getText() +
	    ")");

	 if(checkval == false)
	 {
	    errors.addElement(new Integer(x));
	 }
	 correct = correct && checkval;
      }
      return errors;
   }

   /**
    * Continues with the rest of the FSA to Regular Expression conversion
    * if the answer is right
    */
   public boolean ContinueConversion()
   {
      Vector errors = checkCorrect();
      if(errors.isEmpty())
      {
	 startThread("quit");
	 try
	 {
	    FSAtoRegExpWindow conv = new FSAtoRegExpWindow(
	       FSAtoRegExpAskDialog.this.mainmenu, desk);
	    conv.setLocation(
	       (Toolkit.getDefaultToolkit().getScreenSize().width - conv.getSize().width) / 2,
	       (Toolkit.getDefaultToolkit().getScreenSize().height - conv.getSize().height) / 2);
	    conv.show();
	 }
	 catch (BadInputException bad)
	 {
	    OKDialog dg = new OKDialog(bad.getMessage(),
	       FSAtoRegExpAskDialog.this, 
	       "Regular Expression error.");
	    dg.show();
	 }
	 return true;
      }
      else
      {
	 OKDialog dg = new OKDialog("Your starting expression(s) is incorrect",
	    this, "Regular Expression Conversion");
	 dg.show();
	 return false;
      }
   }

    /* 
     * starts a functionThread with the given function inside
     */
  public void  startThread(String functionName)
  {
     FunctionThread ft;
     Class source;

     try 
     {
	source = this.getClass();
	ft = new FunctionThread(source.getMethod(functionName, new Class[0]), this, new Object[0]);
	ft.start();
     }
     catch(NoSuchMethodException h)
     {
	System.out.println("no " + functionName + " method found.");
     }
  }
}

  
