/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package parser.slider;

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

import parser.FSParser.*;
import domainModel.*;
import taskModellingTool.*;


/***********************************
 * Provides an interface to the slider and all that goes with it
 */
public class ParseFrame extends JDialog 
{

  DmManager _dmManager;   // kvlinden
  //EditionDialog _editionDialog;   // shijian 19-1-2001
  private GenericComponent _gc = null;   // shijian 20-4-2001
  //shijian 1-11-2001
  // for linking tasks
  private GenericComponent _gcPrevious = null;   
  private GenericComponent _gcCurrent = null;   

  ActionInstance _ai= null;	//2001-3-23
  private boolean _ok = false;
  
  Parser parser;
  boolean returnCode;

  JPanel contentPane;
  JPanel parsePanel = new JPanel();
  JButton parseButton = new JButton();
  Component component1;
  Box box1;
  //brasser change to textfield
  JTextField jTextField1 = new JTextField();
  JScrollPane mainScrollPane = new JScrollPane();
  Controller rs = new Controller("", 0.0f, 500.0f);
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel bottomPanel = new JPanel();
  FlowLayout flowLayout1 = new FlowLayout();
  BorderLayout borderLayout2 = new BorderLayout();
  JPanel labelPanel = new JPanel();
  JLabel description = new JLabel();
  JPanel controlPanel = new JPanel();
  JButton cancelButton = new JButton();
  JButton OKButton = new JButton();
  JCheckBox linkBox = new JCheckBox("Link"); //brasser 2001-6-21
  

  //brasser 2001-6-21
  //the interface will change based upon the mode(s) the parser is called in
  public static int DOMAIN_MODE = 0;   //save only domain model information
  public static int TASK_MODE = 1;     //save task and domain model information
  
  public static int SINGLE_MODE = 0;   //interface closes after one sentence, update on ok
  public static int REPEAT_MODE = 1;   //keep the interface up, update on enter
  
  private int modelMode = DOMAIN_MODE;     //default mode is to only change domain info 
  private int interfaceMode = SINGLE_MODE; //default is to be in single use mode
  
  private boolean linking = true;      //link constructed tasks together
  
  private String prevSentence = null; //keep track of the sentence just entered
  
  
  //TapeRecorder_TM_Manager taskManager; //task manager may have problems when we integrate with Tamot
  //I added a function to NewManager, and am using that //brasser

  //Construct the frame
  public ParseFrame() {
    //shijian 2001-1-23
    super();//

    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
	

    rs.setTextField(jTextField1);
    rs.setLabel(description);
	
    OKButton.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        OKButton_actionPerformed(e);
      }
    });
  }

  //Construct the frame
  public ParseFrame(Frame owner) {
    //shijian 2001-1-23
    super(owner, true);//create a modal dialog
  	 
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }

    rs.setTextField(jTextField1);
    rs.setLabel(description);

    OKButton.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        OKButton_actionPerformed(e);
      }
    });

  }
  
  //constructor allowing us to set the modes
  //brasser
  public ParseFrame(Frame owner, int mode1, int mode2) {
  	
    super(owner, true);//create a modal dialog
	 
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }

    rs.setTextField(jTextField1);
    rs.setLabel(description);
	
    modelMode = mode1;
    interfaceMode = mode2;
	
    if (modelMode == TASK_MODE || interfaceMode == REPEAT_MODE) {
      //shijian
      //1-11-2001
      // reparse after every typing
      // submitting with return
      jTextField1.addKeyListener(new java.awt.event.KeyListener() {

	public void keyPressed(KeyEvent e) {
	}
	public void keyTyped(KeyEvent e) {
	}
	public void keyReleased(KeyEvent e) {
	  reParse();	
	}
      });

      //if we are repeating, we need to add things after every return
      jTextField1.addActionListener(new java.awt.event.ActionListener() {

	public void actionPerformed(ActionEvent e) {
	  parseTextField_actionPerformed();
	}
      });
	
      OKButton.addActionListener(new java.awt.event.ActionListener() {

	public void actionPerformed(ActionEvent e) {
	  OKButton_ContMode();
	}
      });
		
      parsePanel.add(linkBox); //only for repeating interface
			
    }
    else {
      OKButton.addActionListener(new java.awt.event.ActionListener() {

	public void actionPerformed(ActionEvent e) {
	  OKButton_actionPerformed(e);
	}
      });
    }

  }

  //Component initialization
  private void jbInit() throws Exception  {
  	
    //shijian 2001-1-23
    rs.setOwner(this);
    contentPane = (JPanel) this.getContentPane();
    component1 = Box.createVerticalStrut(8);
    box1 = Box.createVerticalBox();
    contentPane.setLayout(borderLayout1);
    this.setSize(new Dimension(500, 170));
    //shijian 2001-1-23
    //this.setTitle("Edit");
    this.setTitle("Edit Semantics");
	 
    parseButton.setText("Parse");
    parseButton.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        parseButton_actionPerformed(e);
      }
    });
    jTextField1.setColumns(500);
    jTextField1.setFont(new java.awt.Font("Monospaced", 0, 12));
    mainScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    mainScrollPane.getHorizontalScrollBar().setUnitIncrement(10);
    mainScrollPane.setPreferredSize(new Dimension(400, 65));
    parsePanel.setLayout(flowLayout1);
    bottomPanel.setLayout(borderLayout2);
    cancelButton.setText("Cancel");
    cancelButton.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        cancelButton_actionPerformed(e);
      }
    });
    OKButton.setText("OK");
    contentPane.add(parsePanel, BorderLayout.CENTER);
    parsePanel.add(mainScrollPane, null);
    mainScrollPane.getViewport().add(box1, null);
    box1.add(jTextField1, null);
    box1.add(component1, null);
    box1.add(rs, null);
    
    //shijian 2001-4-3
    //parsePanel.add(parseButton, null);
    linkBox.setSelected(linking);  //brasser 2001-6-21
    linkBox.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent e) {
	if (e.getStateChange() == ItemEvent.SELECTED) {
	  linking = true;
	} else {
	  linking = false;
	}
      }
    });
	
    contentPane.add(bottomPanel, BorderLayout.SOUTH);
    bottomPanel.add(labelPanel, BorderLayout.NORTH);
    labelPanel.add(description, null);
    bottomPanel.add(controlPanel, BorderLayout.CENTER);
    controlPanel.add(OKButton, null);
    controlPanel.add(cancelButton, null);

  }



  //Overridden so we can exit when window is closed
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      System.exit(0);
    }
  }

  public void run(Parser inParser, DmManager dmManager,
		  String title, GenericComponent gc)	//EditionDialog ed)
  {
    _dmManager = dmManager;
    _gc = gc;
    
    //taskManager = new TapeRecorder_TM_Manager(true); //brasser
	
    this.setTitle(title);
    
    parser = inParser;
    rs.setParser(parser);
    resetView();

    // allow the user to mess with the interface
    setVisible(true);
    requestFocus();
  }
  
  //explicit setting of the taskManager //brasser
  /*public void run(Parser inParser, DmManager dmManager,
    String title, GenericComponent gc, TapeRecorder_TM_Manager tm)
    {
    _dmManager = dmManager;
    _gc = gc;
	
    taskManager = tm;
    
    this.setTitle(title);
    
    parser = inParser;
    rs.setParser(parser);
    resetView();

    // allow the user to mess with the interface
    setVisible(true);
    requestFocus();
    }*/

  void OKButton_actionPerformed(ActionEvent e) {

    //shijian: 27-2-2001
    //make sure there at least 3 words in the semantics
	 
    //parser.printConstituentTable(); 
	 
    String newSeman= rs.getTextField().getText();
    StringTokenizer stk = new StringTokenizer(newSeman);
    if (stk.countTokens() < 3){
      String mes =  "Enter at least 3 words, please!";
      JOptionPane.showMessageDialog(MainFrame.getMainFrame(),
				    mes, "Warning",JOptionPane.WARNING_MESSAGE);
      return;
    	
    }
    
    //shijian 
    //30-10-2001
    //remove action instance if existing
    ActionInstance aiTemp = _dmManager.getAInstanceByName(newSeman);
    if (aiTemp != null)
      _dmManager.removeAiAndEi(aiTemp);
		
		
    _ai = parser.createDM(_gc);
    setVisible(false);
    _ok = true;
	
    return;
    /*    
	  //shijian 18-1-2001
	  //update task semantics
	  if (ai != null && _editionDialog != null){
	  //_editionDialog.setSemantics(ai.getID());
	  //System.err.println("semantics is " +ai.getID());
	  _task.setSemantics(ai.getID());
	  }
	  else 
	  System.err.println("semantics for TASK " +
	  " is not created!!");
    
	  // print out the current list of concepts & instances
	  // This is for testing only - kvlinden, 8jan2001
	  Collection testConcepts = _dmManager.getConceptAll();
	  Collection testActionInstances = _dmManager.getAInstanceAll();
	  Collection testEntityInstances = _dmManager.getEInstanceAll();
	  System.out.println("-----------\nthe concepts:");
	  _dmManager.printConcept(testConcepts);
	  System.out.println("-----------\nthe action instances");
	  _dmManager.printAInstance(testActionInstances);
	  System.out.println("-----------\nthe entity instances");
	  _dmManager.printEInstance(testEntityInstances);
	  System.out.println("-----------");
	  */

    //    FileManager.saveXML(File f)
  }

  void cancelButton_actionPerformed(ActionEvent e) {
    setVisible(false);
    _ok= false;
  }

  void parseButton_actionPerformed(ActionEvent e) {
    reParse();
  }

  public void reParse(){

    returnCode = parser.parse(rs.getTextField().getText());
    //shijian
    //5-11-2001
    //stop displaying "parser error" 
    //as contineous parsing is cons=ducted
    /*
      if (returnCode == false)
      description.setText("Parsing Error");
      */
    resetView();
  }
  
  
  // makes sure the view matches the model
  private void resetView() {
    // set the CNL string
    rs.getTextField().setText(parser.cnlString());
    rs.updateTicks();

    // set the head markers
    int heads[] = new int[parser.constituents().size() * 2 + 2];
    for (int i = 0; i < parser.constituents().size(); i++) {
      heads[i*2] = ((Constituent)(parser.constituents().elementAt(i))).headPosition();
      heads[(i*2)+1] = ((Constituent)(parser.constituents().elementAt(i))).headPosition() +
	((Constituent)(parser.constituents().elementAt(i))).headLength();
    }
    rs.setHeads(heads);

    // set the constituent markers/sliders
    float markers[] = new float[parser.constituents().size()];
    

    for (int i = 0; i < parser.constituents().size() - 1; i++) {
      markers[i] = ((Constituent)(parser.constituents().elementAt(i))).endPosition();
    	
      if (markers[i] == -1)
	markers[i] = parser.cnlString().length();
			

    }

    if (((Constituent)(parser.constituents().elementAt(0))).endPosition() == -1)
      markers[0] = 0;

    rs.setValues(markers[0]-1, markers[1]-1, markers[2]-1, markers[3]-1, markers[4]-1, markers[5]-1);
    rs.setDescriptions();
  }
  
  //shijian 2001-3-23
  public ActionInstance getAI(){
    return _ai;
  }
  
  //shijian 2001-3-29
  public boolean isOK(){
    return _ok;
  }
  	
	
  /************************************************************************
   *New functions to implement the multimode behavior of the parser
   *Brasser 2001-6-18
   *
   ************************************************************************/	
	
	//shijian 22-1-2002
  //called only if we are in continuous, task mode
  //creates the domain and task model information	
  private void parseTextField_actionPerformed() {

    String newSeman= rs.getTextField().getText();
	
    //shijian
    //1-11-2001
    //if there is no text, 
    if (newSeman.length() == 0) {
      setVisible(false);
      _ok= true;
      return;
    }
    _gc=parser.createTM(_gc);
    rs.getTextField().setText("");
    if (_gcPrevious != null && _gc != null &&
	linkBox.isSelected()){
      //create link between the coms
      //System.out.println("-----------ok create links");

      NewManager.newLink(_gcPrevious.getName(), 
			 _gc.getName());
    }
		
	
    if (_gc != null)
      _gcPrevious = _gc;
    /*
      //if there is no text, the return acts like the ok button
      if (newSeman.length() == 0) {
      OKButton_ContMode();
      return;
      }
	 
      reParse();
      parser.createTM(_gc);
      rs.getTextField().setText("");
      */
    /* //brasser 2001-7-13
       //create a task
       Task t = NewManager.newTask(-1,-1, newSeman);
	
       //this assures that the name will be correct for linking purposes
       newSeman = t.getName();
	
	
       //If we are in link mode and there was a previous sentence, add a sequential link
       if (linking) {
       if (prevSentence != null)
       NewManager.newLink(prevSentence,newSeman);		
       }
	
       //remember the previous sentence for linking purposes
       prevSentence = newSeman;
       
	
  }*/
  
  /*
  //called only if we are in continuous, task mode
  //creates the domain and task model information	
  private void parseTextField_actionPerformed() {

    String newSeman= rs.getTextField().getText();
	
    //shijian
    //1-11-2001
    //if there is no text, 
    if (newSeman.length() == 0) {
      setVisible(false);
      _ok= true;
      return;
    }
    _gc=parser.createTM();
    rs.getTextField().setText("");
    if (_gcPrevious != null && _gc != null &&
	linkBox.isSelected()){
      //create link between the coms
      //System.out.println("-----------ok create links");

      NewManager.newLink(_gcPrevious.getName(), 
			 _gc.getName());
    }
		
	
    if (_gc != null)
      _gcPrevious = _gc;
   */ /*
      //if there is no text, the return acts like the ok button
      if (newSeman.length() == 0) {
      OKButton_ContMode();
      return;
      }
	 
      reParse();
      parser.createTM(_gc);
      rs.getTextField().setText("");
      */
    /* //brasser 2001-7-13
       //create a task
       Task t = NewManager.newTask(-1,-1, newSeman);
	
       //this assures that the name will be correct for linking purposes
       newSeman = t.getName();
	
	
       //If we are in link mode and there was a previous sentence, add a sequential link
       if (linking) {
       if (prevSentence != null)
       NewManager.newLink(prevSentence,newSeman);		
       }
	
       //remember the previous sentence for linking purposes
       prevSentence = newSeman;
       */
	
  }
  
  //called only in continuous, task mode
  private void OKButton_ContMode() {

    //shijian
    //1-11-2001
    parseTextField_actionPerformed();
  	
  	
    setVisible(false);
    _ok= true;
  }

}
