/*---------------------------------------------------------------------------
File:         			MinimizeTreeState.java
Package:                        JFLAP Version 2.0
Author:				Magda & Octavian Procopiuc V1.0 07/15/96
                                Eric Gramond V2.0 07/22/97 
 
Description of Contents:	Contains class MinimizeTreeState.
				
--------------------------------------------------------------------------*/

/* 
 * Susan H. Rodger, Magda Procopiuc, Octavian Procopiuc, Eric Gramond
 * Computer Science Department
 * Duke University
 * June 1998
 * Supported by National Science Foundation DUE-9596002 and DUE-9555084.
 *
 * Copyright (c) 1998
 * 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.util.*;
import	java.awt.*;
import  java.awt.event.*;

/**
 * This class implements a state of a machine.
 *
 * The painting of a state is done in the Desktop class.
 *
 * @see		flap.Desktop
 * @author	Magda & Octavian Procopiuc
 * @version	1.0 15 July 1996
 */

public class MinimizeTreeState extends State {

  String splittingLetter;
  Point splitLabelStart;
  Point splitLabelEnd;

  public MinimizeTreeState (int id, Point p) {
    super(id, false, p);
    splittingLetter = new String("");
  }

  /**
    * Constructs a new State with the specified label, isFinal flag,
    * and position.
    */
  public MinimizeTreeState (int id, int x, int y) {
    super(id, false, x, y);
    splittingLetter = new String("");
  }

  /**
    * Construct a new, uninitialized, state.
    * Used when reading a machine from a file.
    */
  public MinimizeTreeState() {
    this(-1, -1, -1);
  }

  public MinimizeTreeState(MinimizeTreeState s) {
    super((State) s);
    splittingLetter = new String(s.splittingLetter);
  }

  /**
   * Paints the label of a State.
   * the label is actually put in the center of the State instead of slightly below.
   */
  public void paintDfaLabel(Graphics g, State selectedState) {
    int emptyDfaLabelWidth = Params.emptyDfaLabelWidth;
    int	   cx;
    Vector sublabels = getTokenizedLabel();
    FontMetrics fm = g.getFontMetrics();
    int promptLength = (this == selectedState) ? fm.stringWidth("_") : 0;
    Color tc = ((this == selectedState) ? Params._t_selectedcolor: Params._t_normalcolor);



    Point pl = new Point(p); 
    pl.x -=  (int) ((fm.stringWidth(label) + (2*emptyDfaLabelWidth) + promptLength)/2);
    pl.y -=  (int) ( Params._t_height/2 );

    labelStart = new Point(pl);
    labelEnd = new Point(pl.x+fm.stringWidth(label) + (2*emptyDfaLabelWidth) +
			   promptLength , pl.y+ Params._t_height);

    g.setColor(Params._t_interiorcolor);
    g.fillRect(pl.x, pl.y, labelEnd.x - pl.x, labelEnd.y - pl.y);   
    g.setColor(tc);
    g.drawRect(pl.x, pl.y, labelEnd.x- pl.x, labelEnd.y - pl.y);
        
    int h = fm.getAscent();
    int yStrBase = (int) (pl.y - 2 + (Params._t_height + h)/2);
    if (this != selectedState)
      g.drawString(label, pl.x+ emptyDfaLabelWidth, yStrBase); 
    else {
      cx = pl.x + emptyDfaLabelWidth;
      promptLength = 0;
      g.setColor(Params._t_normalcolor);
      for (int i=0; i< sublabels.size(); i++) {
	if (selectedSublabel == i)  {
	  promptLength = fm.stringWidth("_"); 
	  g.setColor(Params._t_selectedcolor);
	  g.drawString(( (String) sublabels.elementAt(i))+"_", cx, yStrBase);
	  cx += fm.stringWidth(( (String) sublabels.elementAt(i)) + "_");
	  g.setColor(Params._t_normalcolor);
	} else {
	  g.drawString( ((String) sublabels.elementAt(i)), cx, yStrBase);
	  cx += fm.stringWidth((String) sublabels.elementAt(i));
	}
	if(i < sublabels.size() -1) {
	  g.drawString(",", cx, yStrBase);
	  cx += fm.stringWidth(",");
	}
      }
    }

  }


  void paintSplittingLetter(Graphics g, State splitState) {

    if(transitions.size() == 0)
      return;

     int emptyWidth = Params.emptyDfaLabelWidth;
     int y = p.y+17;
     int x = p.x;
     FontMetrics fm = g.getFontMetrics();
     Color tc = ((this == splitState) ? Params._t_selectedcolor: Params._t_normalcolor);
     x-= emptyWidth + (int) (fm.stringWidth(splittingLetter)/2);
     Point start = new Point(x,y);
     Point end = new Point(fm.stringWidth(splittingLetter) + 2*emptyWidth, Params._t_height);
     splitLabelStart = new Point(start);
     splitLabelEnd = new Point(end);
     splitLabelEnd.x += start.x;
     splitLabelEnd.y += start.y;
     

     g.setColor(Params._t_interiorcolor);
     g.fillRect(start.x, start.y, end.x, end.y);
     g.setColor(tc);
     g.drawRect(start.x, start.y, end.x, end.y);

     int h = fm.getAscent();
     g.drawString(splittingLetter, x+emptyWidth, y - 2+(Params._t_height+h)/2); 
     
  }

  /** 
    * handles keyEvents on StateDfalabels for the Desktop
    */
  public boolean processDfaKey(int key, KeyEvent e) {
    
    Vector sublabels =  getTokenizedLabel();
    String aString;
    boolean modified = false;

    if (selectedSublabel > sublabels.size()-1)
      selectedSublabel = 0;

    aString = (String) sublabels.elementAt(selectedSublabel);

    if ((!e.isActionKey()) && key >= (int) '0' && key <= (int) '9') {
      aString += (char) key;
      sublabels.setElementAt(aString, selectedSublabel);
      modified = true;
    }
    else if (key == 8 || key == 127||
                e.getKeyCode() == KeyEvent.VK_DELETE ||
		e.getKeyCode() == KeyEvent.VK_BACK_SPACE /*||
                key == 65288 || key == 65535*/) {	 //Backspace or Delete
      if(aString.length() > 0) {
	aString = aString.substring(0, aString.length()-1);
	sublabels.setElementAt(aString, selectedSublabel);
	modified = true;
      }
      else if(sublabels.size() > 1){
	sublabels.removeElement(aString);
	if(selectedSublabel > 0) 
	  selectedSublabel--;
      }
      
    } else if (key == KeyEvent.VK_RIGHT || (key == '\t' && e.getModifiers() == 0) &&
	       (sublabels.size() > 1)) {
      selectedSublabel = (++selectedSublabel) % (sublabels.size());
    } else if ((sublabels.size() > 1) && (key == KeyEvent.VK_LEFT || 
	       (key == '\t' && e.getModifiers() == InputEvent.SHIFT_MASK))) {
      selectedSublabel = (--selectedSublabel + sublabels.size()) % (sublabels.size());
    } else if(key == (int) ',') {
      sublabels.addElement("");
      selectedSublabel = (sublabels.size()-1);
      modified = true;
    }
    setLabel(sublabels);
    return modified;
 }

  /** 
    * handles keyEvents on StateDfalabels for the Desktop
    */
  public boolean processSplitKey(int key, KeyEvent e) {
    
    String aString;
    boolean modified = false;

    if ((!e.isActionKey()) && (key != 8) && (key != 127))
    {
      splittingLetter = new String(""+new Character((char) key));
    } else if (key == 8 || key == 127) {	 //Backspace or Delete
      splittingLetter = "";
    }
    return modified;
 }

}
