/*
   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.
*/


/**
 * Title:        slider<p>
 * Description:  <p>
 * Copyright:    Copyright (c) <p>
 * Company:      <p>
 * @author
 * @version 1.0
 */
package parser.slider;

import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.lang.Integer;
import java.awt.*;
import javax.swing.text.BadLocationException;
import parser.FSParser.*;
import taskModellingTool.*;
import domainModel.*;
import domainModel.gui.*;

//shijian 6-2-2001
import javax.swing.event.*;


/********************************************
 * An extended range slider with extra functionality for the parser
 */
public class Controller extends RangeSlider implements Scrollable {

  Parser parser;
  //private JTextArea textfield;
  //brasser change to textfield;
  private JTextField textfield;
  
  private JLabel part;
  
  //shijian 16-11-2001
  private int _originalPos = -1;		//original marker position
  
  ////Shijian 2001-1-23
  private XManager _xManager = FileManager.getXDM();     // grab the xmanager
  private DmManager _dMM=_xManager.getDmManager();	// default _dMM 
  private JDialog _owner;	// 
  
  float[] values;
  int[] tickmarks;
  //shijian
  //29-10-2001
  //String[] names = {"actor", "process", "actee", "phrase 1", "phrase 2", "phrase3"};
  String[] names;	// = {"actor", "process", "actee", "phrase 1", "phrase 2", "phrase3"};

  //JPopupMenu headPopup = new JPopupMenu();
  JMenuItem setHeadMItem = new JMenuItem();
  
  //shijian 2001-1-22
  JPopupMenu _actionMenu = new JPopupMenu();
  JMenuItem _actConcept = new JMenuItem("Edit Action Concept");
  JMenuItem _actInstance = new JMenuItem("Edit Action Instance");
  JMenuItem _enConcept = new JMenuItem("Edit Entity Concept");
  JMenuItem _enInstance = new JMenuItem("Edit Entity Instance");
  JMenuItem _actorConcept = new JMenuItem("Edit Actor Concept");
  JMenuItem _actorInstance = new JMenuItem("Edit Actor Instance");
  
  //shijian 
  //26-10-2001
  private DmRelation _dmRel = DmRelation.getInstance();
  TreeMap _consMenuitems=new TreeMap();	//pair of contituents and menuitems
  ArrayList constituents = new ArrayList();;

  // constructor
  public Controller(String n, float min, float max) {
    super(n,min,max);
    this.setAutoscrolls(true);
    setHeadMItem.setText("Set Head");
    setHeadMItem.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        setHeadMItem_actionPerformed(e);
      }
    });
    //_actionMenu.add(setHeadMItem);
    
    //shijian 2001-1-22
    _actConcept.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        _actConcept_actionPerformed(e);
      }
    });
    
    //shijian 2001-2-7
    _actInstance.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        _actInstance_actionPerformed(e);
      }
    });
    
    //_actionMenu.add(_actConcept);
    _enConcept.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        _enConcept_actionPerformed(e);
      }
    });
    //_actionMenu.add(_enConcept);    
    _enInstance.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        _enInstance_actionPerformed(e);
      }
    });
    //_actionMenu.add(_enInstance);
    _actorConcept.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        _actorConcept_actionPerformed(e);
      }
    });
    //_actionMenu.add(_enConcept);    
    _actorInstance.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        _actorInstance_actionPerformed(e);
      }
    });
    //_actionMenu.add(_enInstance);
    
    //26-10-2001
    //shijian
    // put action relations as popup menuitem, so that
    // constituents can be set
    String actionRelations[] = _dmRel.getAllActionRelations();
    String process= "process";
    constituents.add(process);
    for (int i =0; i<actionRelations.length; i++){
      constituents.add(actionRelations[i]);
    }
    String cons;
    JMenuItem actMenuitem; 
    //add the rest action relations 
    for (int i =0; i<constituents.size(); i++){
      cons =(String)constituents.get(i);
      actMenuitem =new JMenuItem("Set "+ cons);
      _consMenuitems.put(cons, actMenuitem) ;
      actMenuitem.addActionListener(new java.awt.event.ActionListener() {
	public void actionPerformed(ActionEvent e) {
	  setConstituent_actionPerformed(e);
	}
      });
    }
    //29-10-2001
    names = new String[actionRelations.length+1];
    names[0] = process;
    for (int i =0; i<actionRelations.length; i++){
      constituents.add(actionRelations[i]);
      names[i+1] = actionRelations[i];
    }

  }

  public void setValues(float sv, float vdo, float ppone, float pptwo, float ppthree, float ppfour) {
    super.setValues(sv, vdo, ppone, pptwo, ppthree, ppfour);
    values = new float[6];
    values[0] = sv;
    values[1] = vdo;
    values[2] = ppone;
    values[3] = pptwo;
    values[4] = ppthree;
    values[5] = ppfour;
  }

  public void setParser(Parser inParser) {
    parser = inParser;
  }

  // sets the associated text field
  //brasser change to textfield
  public void setTextField(JTextField field) {
    this.textfield = field;
    
    textfield.addKeyListener(new KeyAdapter() {

      public void keyPressed(KeyEvent ke) {

        //calls the popup menu
	/*  if (ke.getModifiers() == ke.CTRL_MASK && ke.getKeyCode() == ke.VK_P) {
	    try {
            parser.parse(textfield.getText(0, textfield.getCaretPosition()));
            Vector v = parser.possibleTransitions();
            Vector nouns = new Vector();
            Vector verbs = new Vector();
            Vector trans = new Vector();
            for (int i = 0; i < v.size(); i++) {
	    if (v.elementAt(i).equals("noun")) {
	    nouns.add("nouns");
	    nouns.add("button");
	    nouns.add("model");
	    nouns.add("mouse");
	    nouns.add("user");
	    v.set(i, nouns);
	    }
	    else if (v.elementAt(i).equals("verb")) {
	    verbs.add("verbs");
	    verbs.add("click");
	    verbs.add("save");
	    v.set(i, verbs);
	    }
	    else if (v.elementAt(i).equals("\"at\"")) {
	    trans.add("transitions");
	    trans.add("at");
	    trans.add("from");
	    trans.add("to");
	    trans.add("using");
	    v.set(i, trans);
	    }
	    else {
	    //v.setElementAt(new Vector(), i);
	    }
            }

	    //            System.err.println(v);
            PopupWordlist pul = new PopupWordlist(textfield, v);
            Rectangle r = textfield.modelToView(textfield.getCaretPosition());
            Point p = textfield.getLocationOnScreen();
            pul.show(textfield, (int)p.getX()+(int)r.getX()+10, (int)p.getY()+(int)r.getY()+20);
	    } catch (BadLocationException ble) {}
	    }
	    else if (ke.getKeyCode() == ke.VK_ENTER) {
	    ke.consume();
	    }
	    //makes sure that everything scrolls properly
	    else if (ke.getKeyCode() == ke.VK_DELETE || ke.getKeyCode() == ke.VK_BACK_SPACE) {
	    try {
            Rectangle r = textfield.modelToView(textfield.getCaretPosition());
            r.setBounds((int)r.getX() - 10, 0, 0, 0);
            scrollRectToVisible(r);
	    } catch (BadLocationException ble) {}
	    }
	    else
	    try {
            Rectangle r = textfield.modelToView(textfield.getCaretPosition());
            r.setBounds((int)r.getX(), 0, 10, 0);
            scrollRectToVisible(r);
	    } catch (BadLocationException ble) {}
	    */  }

      public void keyReleased(KeyEvent ke) {
	// updateTicks();
	// to prevent wordnet errors, there are only lookups after space is pressed.
	// this has to do with the way jwnl handles morphology. brasser 2001-6-14
	if (ke.getKeyCode() == KeyEvent.VK_SPACE)
	  _textfieldTextChanged(ke);	

      }
    });

    textfield.addMouseListener(new PopupListener());
  }

  //shijian 6-2-2001
  //add textlistener to the textfiled to parser the text
  //everytime the text is changed
  public void _textfieldTextChanged(KeyEvent  e) {
    reParse();
  }
  
  private void reParse(){
  	
    // makes sure the view matches the model
    parser.parse(getTextField().getText());
    //    System.out.println("-----------\new semantics: "+ getTextField().getText());
    // set the CNL string
    //getTextField().setText(parser.cnlString());
    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();
    }
    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;

    setValues(markers[0]-1, markers[1]-1, markers[2]-1, markers[3]-1, markers[4]-1, markers[5]-1);
    setDescriptions();
  }
  
  
  public void setLabel(JLabel name) {
    part = name;
  }

  //brasser change to textfield
  public JTextField getTextField() {
    return this.textfield;
  }

  // updates the ticks that the sliders snap to
  public void updateTicks() {
    String st = textfield.getText();
    Vector v = new Vector();
    int i = 0;
    int size = textfield.getColumns();//st.length() -1;

    while (i != -1) {
      v.add(new Float(i));
      i = st.indexOf(" ", i+1);
    }
    v.add(new Float(st.length()));

    tickmarks = new int[v.size()];
    for(int x = 0; x < tickmarks.length; x++) {
      tickmarks[x] = ((Number)v.elementAt(x)).intValue() - 1;
    }
  }

  //snaps knobs to tickmarks 
  public void mouseReleased(MouseEvent e) {
    super.mouseReleased(e);

    if (_originalPos < 0) return;
		
    //new marker position
    int newPosition = textfield.viewToModel(new Point(e.getX(),5));
    //    System.out.println("mouse released at: " + newPosition);
		
    Constituent consttt;
    ConstituentTable currentTable =parser.getCurrentTable();
	    
    /* // trace prints
    System.out.println("CNL string: " + parser.cnlString());
    System.out.println("Starting mouseReleased with this table:");
    System.out.println(currentTable);
    */

    String constttName;
    int conStart, conEnd;
    for (int i = 0; i < currentTable.getConstituents().size(); i++) {  
      consttt = (Constituent)(currentTable.getConstituents().elementAt(i));
      constttName = consttt.name();
      conStart=consttt.startPosition();
      conEnd=consttt.endPosition();
	
      if (conEnd == _originalPos){
	if (conStart < newPosition){
	  consttt.setEndPosition(newPosition);
	  parser.resolveHeadConflicts(constttName,conStart,newPosition);
	  parser.resolveConsConflicts(constttName,conStart,newPosition); // added - kvlinden, 11jan2002
	} 
	else // The slider will prevent this case from happening.
	  return; 
      }
	      			
      if (conStart == _originalPos){
	if (conEnd > newPosition){
	  consttt.setStartPosition(newPosition);
	  parser.resolveHeadConflicts(constttName,newPosition,conEnd);
	  parser.resolveConsConflicts(constttName,newPosition,conEnd); // added - kvlinden, 11jan2002
	} 
	else // The slider will prevent this one as well (see previous else).
	  return;
      }
      		
      /* // trace prints
      System.out.println("CNL string: " + parser.cnlString());
      System.out.println("Just dealt with constituent: " + constttName);
      System.out.println(currentTable);
      */
    }
		
    //reset marker original position
    _originalPos = -1;	
		
    updateView();
		
    /*
    // This code implements the "snapping behavior".  When
    // you slide a constituent boundary around on the slider and then release
    // it, the system will move it from where you dropped it to the nearest
    // space.  
    // It appears that someone removed this code, and it's not clear to me
    // why, so I've put it back in.  It seems like this should mess the system
    // up, but for some reason it works as best as I can tell - kvlinden, 11jan2002
    float[] oldValues = values;
    values = super.getAllValues();
    //	for (int i = 0; i < values.length; i++)
    //	    System.err.println(values[i]);
    float svpos = values[0];
    float vdopos = values[1];
    float pponepos = values[2];
    float pptwopos = values[3];
    float ppthreepos = values[4];
    float ppfourpos = values[5];

    float dif = 100;
    float oldDif = dif;
    int index = 0;
    for (int i = 0; i < tickmarks.length; i++) {
      dif = Math.abs(svpos - tickmarks[i]);
      if (dif < oldDif) {
	index = i;
      }
      oldDif = dif;
    }

    svpos = (float)tickmarks[index];

    dif = 100;
    oldDif = dif;
    index = 0;
    for (int i = 0; i < tickmarks.length; i++) {
      dif = Math.abs(vdopos - tickmarks[i]);
      if (dif < oldDif) {
	index = i;
      }
      oldDif = dif;
    }

    vdopos = (float)tickmarks[index];
    int vdoindex = index;

    dif = 100;
    oldDif = dif;
    index = 0;
    for (int i = 0; i < tickmarks.length; i++) {
      dif = Math.abs(pponepos - tickmarks[i]);
      if (dif < oldDif) {
	index = i;
      }
      oldDif = dif;
    }

    pponepos = (float)tickmarks[index];

    dif = 100;
    oldDif = dif;
    index = 0;
    for (int i = 0; i < tickmarks.length; i++) {
      dif = Math.abs(pptwopos - tickmarks[i]);
      if (dif < oldDif) {
	index = i;
      }
      oldDif = dif;
    }

    pptwopos = (float)tickmarks[index];

    dif = 100;
    oldDif = dif;
    index = 0;
    for (int i = 0; i < tickmarks.length; i++) {
      dif = Math.abs(ppthreepos - tickmarks[i]);
      if (dif < oldDif) {
	index = i;
      }
      oldDif = dif;
    }

    ppthreepos = (float)tickmarks[index];

    dif = 100;
    oldDif = dif;
    index = 0;
    for (int i = 0; i < tickmarks.length; i++) {
      dif = Math.abs(ppfourpos - tickmarks[i]);
      if (dif < oldDif) {
	index = i;
      }
      oldDif = dif;
    }

    ppfourpos = (float)tickmarks[index];

    //if (svpos == vdopos)
    //  vdopos = (float)tickmarks[vdoindex + 1];

    values[0] = svpos;
    values[1] = vdopos;
    values[2] = pponepos;
    values[3] = pptwopos;
    values[4] = ppthreepos;
    values[5] = ppfourpos;

    for (int i = 0; i < 6; i++) {
      if (oldValues[i] - values[i] != 0) {
	// Needed because the parser starts the adjunct constituents
	// after their preposition, not at the start of the preposition.
	int extra = 2;  
	int extra2 = 2;   // handles a special case, see below.
	if (i > 1 && values[i] < textfield.getText().trim().length()-1) { // trim off the trailing blanks - kvlinden, 25oct2001
	  try {
	    String str = textfield.getText((int)values[i] + 2, textfield.getText().indexOf(" ", (int)values[i]+2) - ((int)values[i] + 2));
	    if (str.equals("using")) { 
	      names[i+1] = "instrument";
	      extra += 6;
	    }
	    // support for with added - kvlinden, 24oct2001
	    if (str.equals("with")) { 
	      names[i+1] = "instrument";
	      extra += 5;
	    }
	    else if (str.equals("at")) {
	      names[i+1] = "location";
	      extra += 3;
	    }
	    else if (str.equals("from")) {
	      names[i+1] = "source";
	      extra += 5;
	    }
	    else {
	      values[i] = oldValues[i];
	    }
	  } catch (BadLocationException ble) {}
	}

	if (values[0] == values[1]) {
	  values[0] = oldValues[0];
	  values[1] = oldValues[1];
	}

	//System.out.println("moving " + names[i] + " using values[i]: " + values[i]);

	if ((i >= 1) && (values[i-1] == -1))
	  // When the previous constituent doesn't exist, we need to
	  // set the start of the current constituent at 0 rather than -1.
	  // Usually this is for the process.
	  // - kvlinden/mbrass48, 9aug2000
	  extra2 -= 1; 

	if (i != 0)
	  parser.moveConstituent(names[i], new Integer((int)values[i-1]+extra2), new Integer((int)values[i]+1));
	else {
	  // handles the agent constituent, a special case
	  if (values[i] == -1) {
	    // Handles the null agent case 
	    // Here the boundaries should be -1, -1, rather than 0, 0.
	    // - kvlinden/mbrass48, 9aug2000
	    parser.moveConstituent(names[i], new Integer(-1), new Integer(-1));
	    extra -= 1;  // same as above, except this is for the agent
	  }
	  else
	    parser.moveConstituent(names[i], new Integer(0), new Integer((int)values[i]+1));
	}

	parser.moveConstituent(names[i+1], new Integer((int)values[i]+extra), 
			       new Integer((int)values[i+1]+1));

	for (int j = 0; j < headArray.length-1; j+=2) {
	  if (headArray[j] < values[i] && headArray[j] > oldValues[i]) {
	    parser.changeHead(names[i+1], new Integer(-1), new Integer(-1));
	    headArray[j+1] = headArray[j] = -1;
	  }
	  else if (headArray[j] > values[i] && headArray[j] < oldValues[i]) {
	    parser.changeHead(names[i], new Integer(-1), new Integer(-1));
	    headArray[j+1] = headArray[j] = -1;
	  }
	}
      }
    }

    //	System.err.println("");
    //	System.err.println("");
    //	parser.printConstituentTable();
    //super.setValues(svpos, vdopos, pponepos, pptwopos, ppthreepos, ppfourpos);
    super.setValues(values[0], values[1], values[2], values[3], values[4], values[5]);

    */

    System.out.println(currentTable);

  }

  //assures that dragging a slider off the screen scrolls the screen
  public void mouseDragged(MouseEvent e) {
    super.mouseDragged(e);
    int x = e.getPoint().x;
    if (x > -this.GRIP_WIDTH && x < 3500) {
      Rectangle r = new Rectangle(x, 0, 10, 0);
      scrollRectToVisible(r);
    }}


  //sets labels for the various parts (e.g. patient, process...)
  public void mouseMoved(MouseEvent e) {
    int x = textfield.viewToModel(new Point(e.getX(),5));
    
    //shijian
    //29-10-2001
    String consName;
    Constituent consttt;
    int conStart, conEnd;

    for (int i =0; i<constituents.size(); i++){
      consName =(String)constituents.get(i);
      consttt = (Constituent)(parser.getCurrentTable().
			      getConstituents().elementAt(parser.getCurrentTable().
							  name2Index(consName)));
      conStart = consttt.startPosition();
      conEnd = consttt.endPosition();
      if (x >= conStart && x <= conEnd) {
	setLabelText(consName);
	break;
      }
    }
    /*    
	  if (values != null) {
	  for (int i = 0; i < values.length-1; i++) {
	  if (values[i] < x && x < values[i+1]) {
          setLabelText(names[i+1]);
	  }
	  }
	  if (values[0] > x)
	  setLabelText(names[0]);
	  }
	  */   
  }

  public void mouseExited(MouseEvent e) {
    part.setText("");
  }

  //sets the text of the label, if it has changed
  private void setLabelText(String text) {
    if (!part.getText().equals(text)) {
      part.setText(text);
    }
  }


  //*****************Scrollable Functions***************
  public Dimension getPreferredScrollableViewportSize() {
    return this.getPreferredScrollableViewportSize();
  }

  public int getScrollableUnitIncrement(Rectangle visibleRect,
					int orientation,
					int direction) {
    return direction;
  }

  public int getScrollableBlockIncrement(Rectangle visibleRect,
					 int orientation,
					 int direction) {
    return direction;
  }

  public boolean getScrollableTracksViewportWidth() {
    return false;
  }

  public boolean getScrollableTracksViewportHeight() {
    return true;
  }

  class PopupListener extends MouseAdapter {
    public void mousePressed(MouseEvent e) {
    	
      //shijian 2001-1-22
      //if "process", show Action concept menuItem
      // else show entity concept popup menu 
      int start = textfield.getSelectionStart();
      int end = textfield.getSelectionEnd();
      //shijian
      //26-10-2001
      if (start != end){
	if (_actionMenu.getComponentCount() == 0){
	  //add set head menuitem
	  _actionMenu.add(setHeadMItem);
	  _actionMenu.add(new JSeparator());
	  Iterator it = _consMenuitems.keySet().iterator();
	  String name;
	  while(it.hasNext()){
	    name = (String) it.next();
	    _actionMenu.add((JMenuItem)_consMenuitems.get(name)); 
	  }
	}
      }
      else {
	_actionMenu.removeAll();
      }
	        		
	        		
	 
      /*
    	for (int i = 0; i < 5; i++) {
	if (start <= values[i+1] && start >= values[i]) {
	//parser.changeHead(names[i+1], new Integer(start), new Integer(end));
	//	headArray[(i*2)+3] = end;
	//	headArray[i*2+2] = start;

	//if it is a process, display action menu
	if (names[i+1] == names[1]){
	_actionMenu.removeAll();
	_actionMenu.add(setHeadMItem);    
	_actionMenu.add(_actConcept);
	_actionMenu.add(_actInstance);

	//	        	   System.out.println("\n selected word:if" + names[i+1]+ 
	//        				" " +textfield.getSelectedText() );

	}
	else if (names[i+1] == names[2]) {
	_actionMenu.removeAll();
	_actionMenu.add(setHeadMItem);    
	_actionMenu.add(_enConcept);    
	_actionMenu.add(_enInstance); 
	        		

	}else {
	_actionMenu.removeAll();
	_actionMenu.add(setHeadMItem);    
	        	
	}
	}
	else if (i == 0 && start <= values[i]) {
	parser.changeHead(names[0], new Integer(start), new Integer(end));
	headArray[1] = end;
	headArray[0] = start;

	if (names[i] == names[0]) {
	_actionMenu.removeAll();
	_actionMenu.add(setHeadMItem);    
	_actionMenu.add(_actorConcept);    
	_actionMenu.add(_actorInstance);    
	//	        		System.out.println("\n selected word:if2" + names[i]+ 
	//        				" " +textfield.getSelectedText() );

	}else {
	_actionMenu.removeAll();
	_actionMenu.add(setHeadMItem);    
	//        		System.out.println("\n selected word:else2" + names[0]+ 
	//        			 	" " +textfield.getSelectedText() );
	}
	        	

	}
	
	}
	*/
	    
  maybeShowPopup(e);
	    
    }

    public void mouseReleased(MouseEvent e) {
      maybeShowPopup(e);
    }

    private void maybeShowPopup(MouseEvent e) {
      if (e.isPopupTrigger()) {
        _actionMenu.show(e.getComponent(),
			 e.getX(), e.getY());
      }
    }

    }

  void setHeadMItem_actionPerformed(ActionEvent e) {
  	
    int start = textfield.getSelectionStart();
    int end = textfield.getSelectionEnd();
    //shijian
    //26-10-2001
    String consName;
    Constituent consttt;
    int conStart, conEnd;
    for (int i =0; i<constituents.size(); i++){
      consName =(String)constituents.get(i);
      consttt = (Constituent)(parser.getCurrentTable().
			      getConstituents().elementAt(parser.getCurrentTable().
							  name2Index(consName)));
      conStart = consttt.startPosition();
      conEnd = consttt.endPosition();
      if (start >= conStart && end <= conEnd) {
        parser.changeHead(consName, new Integer(start), new Integer(end));
        headArray[(i*2)+1] = end;
        headArray[i*2] = start;
        break;
      }
    }
    repaint();

    /*
      for (int i = 0; i < 5; i++) {
      if (start <= values[i+1] && start >= values[i]) {
      parser.changeHead(names[i+1], new Integer(start), new Integer(end));
      headArray[(i*2)+3] = end;
      headArray[i*2+2] = start;
        
      //shijian 1001-1-22
      //        System.out.println("\n selected word:" + names[i+1]+ 
      //        		" " +textfield.getSelectedText() );

        
      }
      else if (i == 0 && start <= values[i]) {
      parser.changeHead(names[0], new Integer(start), new Integer(end));
      headArray[1] = end;
      headArray[0] = start;
        
      //shijian 1001-1-22
      //        System.out.println("\n selected word:" + names[0]+
      //					 " " +textfield.getSelectedText() );


      }

      }

      //    parser.printConstituentTable();
      repaint();
      */
  }

  //initializes the descriptions
  void setDescriptions() {
    for (int i = 2; i < 6; i++) {
      try {
	//	System.out.println("dealing with i: " + i + " values[i]: " + values[i]);
        if (values[i] < textfield.getText().trim().length()-1) { // trim off the trailing blanks - kvlinden, 25oct2001
          String str = textfield.getText((int)values[i] + 2, 
					 textfield.getText().indexOf(" ", (int)values[i]+2) - ((int)values[i] + 2));
          //shijian
          //29-10-2001
          /*
	    if (str.equals("using") || str.equals("with")) {  // support for with added - kvlinden, 24oct2001
            names[i+1] = "instrument";
	    }
	    else if (str.equals("at")) {
            names[i+1] = "location";
	    }
	    else if (str.equals("from")) {
            names[i+1] = "source";
	    }
	    */
        }
      } catch (BadLocationException ble) {}
    }
  }

  
  //shijian 2001-1-22
  void _actConcept_actionPerformed(ActionEvent e) {
    //  		System.out.println("\n Action concept menuitem selected"); 
    String actConName = textfield.getSelectedText();
    DmConcept actCon = null;		//_dMM.getAConcept(actConName);
    //get actee instace from action instance first
    String actInsName = textfield.getText().toLowerCase().trim(); 
    ActionInstance actIns = _dMM.getAInstanceByName(actInsName);
    if ( actIns != null) {
      actCon = actIns.getConceptOf();
    }else
      actCon = _dMM.getAConcept(actConName);


    if (actCon == null){
      actCon = new DmConcept(actConName,ConceptType.getDefaultActionType());
      _dMM.addConcept(actCon);
      _dMM.addEnglishV((EnglishVerb)actCon.getCard(DmConcept._ENGLISH));
    }
		
    AConceptEdit ad = new AConceptEdit(MainFrame.getMainFrame(),
				       "Edit Action Concept",actCon);
    //    	if (ad.isOKButton())
    //    		System.out.println("\n YEs, it is OK " );
    	
    if (_owner != null)
      _owner.repaint();
	      
    _actionMenu.removeAll();

  }

  //shijian 2001-2-7
  void _actInstance_actionPerformed(ActionEvent e) {
    //  		System.out.println("\n Action Instance menuitem selected"); 
    String actInsName = textfield.getText().toLowerCase().trim();
    ActionInstance actIns = _dMM.getAInstanceByName(actInsName);
    if ( actIns != null) {
      AInstanceEdit ad = new AInstanceEdit(MainFrame.getMainFrame(),
					   "Edit Action Instance",actIns);
      //		 	if (ad.isOKButton())
      //		 		System.out.println("\n YEs, it is OK " );
    }
		
    if (_owner != null)
      _owner.repaint();
	      
    _actionMenu.removeAll();

  }

  void _enConcept_actionPerformed(ActionEvent e) {
    //  		System.out.println("\n entity concept menuitem selected"); 
    String enConName = textfield.getSelectedText();
    DmConcept enCon = null; 	//_dMM.getEConceptAny(enConName);
    //get actee instace from action instance first
    EntityInstance enIns = null; // = _dMM.getEInstanceByName(enInsName);
    String actInsName = textfield.getText().toLowerCase().trim();
    ActionInstance actIns = _dMM.getAInstanceByName(actInsName);
    if ( actIns != null) {
      enIns = ((EntityInstance)actIns.getActionRelations().
	       get(DmRelation.getActee()));
    }else
      enIns =  _dMM.getEInstanceByName(enConName);
			
    if ( enIns != null) 
      enCon = enIns.getConceptOf();

    if (enCon == null){
      enCon = new DmConcept(enConName,ConceptType.getDefaultEntityType());
      _dMM.addConcept(enCon);
      _dMM.addEnglishN((EnglishNoun)enCon.getCard(DmConcept._ENGLISH));
    }
		
    EConceptEdit ad = new EConceptEdit(MainFrame.getMainFrame(),
				       "Edit Entity Concept",enCon);
    //    	if (ad.isOKButton())
    //    		System.out.println("\n YEs, it is OK " );
    if (_owner != null)
      _owner.repaint();
  }
  
  void _enInstance_actionPerformed(ActionEvent e) {
    //  		System.out.println("\n entity instance menuitem selected");
    String enInsName = textfield.getSelectedText();
    EntityInstance enIns = null; // = _dMM.getEInstanceByName(enInsName);
    //get actee instace from action instance first
    String actInsName = textfield.getText().toLowerCase().trim();
    ActionInstance actIns = _dMM.getAInstanceByName(actInsName);
    if ( actIns != null) {
      enIns = ((EntityInstance)actIns.getActionRelations().
	       get(DmRelation.getActee()));
    }else
      enIns =  _dMM.getEInstanceByName(enInsName);

    if (enIns == null){
			
      DmConcept enCon = _dMM.getEConceptAny(enInsName);
      if (enCon == null){
	enCon = new DmConcept(enInsName,ConceptType.getDefaultEntityType());
	_dMM.addConcept(enCon);
	_dMM.addEnglishN((EnglishNoun)enCon.getCard(DmConcept._ENGLISH));
      }
		
      enIns = new EntityInstance(enInsName,enCon);
      _dMM.addEInstance(enIns);
    }
    EInstanceEdit id = new EInstanceEdit(MainFrame.getMainFrame(),
					 "Edit Entity Instance",enIns);
    if (id.isOKButton()){
      //    		System.out.println("\n YEs, it is OK " );
      // change selected text to new name	
      //brasser change to textfield
      textfield.replaceSelection(id.getName()); //, 
      //textfield.getSelectionStart(),
      //textfield.getSelectionEnd()	);
    			
      reParse();

    }
    if (_owner != null)
      _owner.repaint();
	      
    _actionMenu.removeAll();
  }

  void _actorConcept_actionPerformed(ActionEvent e) {
    //  		System.out.println("\n entity concept menuitem selected"); 
    String enConName = textfield.getSelectedText();
    DmConcept enCon = null; 	//_dMM.getEConceptAny(enConName);
    //get actee instace from action instance first
    EntityInstance enIns = null; // = _dMM.getEInstanceByName(enInsName);
    String actInsName = textfield.getText().toLowerCase().trim();
    ActionInstance actIns = _dMM.getAInstanceByName(actInsName);
    if ( actIns != null) {
      enIns = ((EntityInstance)actIns.getActionRelations().
	       get(DmRelation.getActor()));
    }else
      enIns =  _dMM.getEInstanceByName(enConName);
			
    if ( enIns != null) 
      enCon = enIns.getConceptOf();

    if (enCon == null){
      enCon = new DmConcept(enConName,ConceptType.getDefaultEntityType());
      _dMM.addConcept(enCon);
      _dMM.addEnglishN((EnglishNoun)enCon.getCard(DmConcept._ENGLISH));
    }
		
    EConceptEdit ad = new EConceptEdit(MainFrame.getMainFrame(),
				       "Edit Entity Concept",enCon);
    //    	if (ad.isOKButton())
    //    		System.out.println("\n YEs, it is OK " );
    		
    if (_owner != null)
      _owner.repaint();
	      
    _actionMenu.removeAll();
  }
  
  void _actorInstance_actionPerformed(ActionEvent e) {
    //  		System.out.println("\n entity instance menuitem selected");
    String enInsName = textfield.getSelectedText();
    EntityInstance enIns = null; // = _dMM.getEInstanceByName(enInsName);
    //get actee instace from action instance first
    String actInsName = textfield.getText().toLowerCase().trim();
    ActionInstance actIns = _dMM.getAInstanceByName(actInsName);
    if ( actIns != null) {
      enIns = ((EntityInstance)actIns.getActionRelations().
	       get(DmRelation.getActor()));
    }else
      enIns =  _dMM.getEInstanceByName(enInsName);

    if (enIns == null){
			
      DmConcept enCon = _dMM.getEConceptAny(enInsName);
      if (enCon == null){
	enCon = new DmConcept(enInsName,ConceptType.getDefaultEntityType());
	_dMM.addConcept(enCon);
	_dMM.addEnglishN((EnglishNoun)enCon.getCard(DmConcept._ENGLISH));
      }
		
      enIns = new EntityInstance(enInsName,enCon);
      _dMM.addEInstance(enIns);
    }
    EInstanceEdit id = new EInstanceEdit(MainFrame.getMainFrame(),
					 "Edit Entity Instance",enIns);
    if (id.isOKButton()){
      //    		System.out.println("\n YEs, it is OK " );
      // change selected text to new name	
      //brasser change to textfield
      textfield.replaceSelection(id.getName()); //, 
      //textfield.getSelectionStart(),
      //textfield.getSelectionEnd()	);

    }
    if (_owner != null)
      _owner.repaint();
	   
    _actionMenu.removeAll();

  }
 
  public void setOwner(JDialog owner){
    _owner = owner;
  }
	
    
  //26-10-2001
  //shijian
  // put action relations as popup menuitem, so that
  // constituents can be set
  private void setConstituent_actionPerformed(ActionEvent e){
    int start = textfield.getSelectionStart();
    int end = textfield.getSelectionEnd();
    //"unhappy".substring(2) returns "happy"
    String constituent = e.getActionCommand();
    constituent= constituent.substring(4);
	
    parser.moveConstituent(constituent, 
			   new Integer(start), 
			   new	Integer (end));
		
    //1-11-2001
    parser.resolveHeadConflicts(constituent,start,end);
    parser.resolveConsConflicts(constituent,start,end);

    updateView();
    //System.out.println("selected: "+constituent);
  }
  // makes sure the view matches the model
  private void updateView() {
    // set the CNL string
    //getTextField().setText(parser.cnlString());
    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();
    }
    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;

    setValues(markers[0]-1, markers[1]-1, markers[2]-1, markers[3]-1, markers[4]-1, markers[5]-1);
    setDescriptions();
  }
  //shijian
  //16-11-2001
  /** MouseListener method for moving slider */
  public void mousePressed(MouseEvent e) {
    super.mousePressed(e);
    if (super.pressedOnMarker()){
      int x = textfield.viewToModel(new Point(e.getX(),5));
      _originalPos = x;
      System.out.println("mouse pressed at: " + x);
    }
    
  }
  }
