// File: VertPanel.java
// Classes: VertPanel
// Author: Kedar Patankar

package EDU.neu.ccs.demeter.tools.apstudio.graphedit;

import java.awt.Panel;
import java.awt.TextField;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Point;

import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;

import EDU.neu.ccs.demeter.tools.apstudio.ui.PropsGridLayout;

import EDU.neu.ccs.demeter.Ident;

/* Purpose : Property sheet for Concrete as well as Alternation Vertex. This displays as well allows to modify 
the properties 
*/

public class VertPanel extends Panel implements ActionListener,FocusListener
{
	public static final int PACKAGE =0;
	public static final int PUBLIC =1;
	public static final int FINAL =2;
	public static final int PUBLICNFINAL =3;

	private Editor _editor;
	private PropertyWindow _pw;
	private String _before,_after,_className;
	private String _scopeIdentifier,_vertexType,_parseType; // not implemented
	private int _xLoc,_yLoc,_width,_height;
	private TextField _beforeText, _afterText, _classNameText,_xLocText,_yLocText,_widthText,_heightText;
	private Choice _scopeIdentifierChoice,_vertexTypeChoice,_parseChoice; // not implemented

	private UVertex _vertex;

	public VertPanel(Editor editor, PropertyWindow parent)
	{
		_editor = editor;
		_pw = parent;
		setLayout(new PropsGridLayout(5,5));
		
		TextField nameLabel,scopeLabel,parseLabel,typeLabel,beforeLabel,afterLabel,xLabel,yLabel,widthLabel,heightLabel;

		nameLabel = new TextField("Vertex Name");
		scopeLabel = new TextField("ScopeIdentifier");
		parseLabel = new TextField("ParseMethod");
		typeLabel = new TextField("VertexType");
		beforeLabel = new TextField("Syntax:Before");
		afterLabel= new TextField("Syntax:After");
		xLabel = new TextField("X Location");
		yLabel = new TextField("Y Location");
		widthLabel = new TextField("Width");
		heightLabel = new TextField("Height");

		nameLabel.setEditable(false);
		scopeLabel.setEditable(false);
		parseLabel.setEditable(false);
		typeLabel.setEditable(false);
		beforeLabel.setEditable(false);
		afterLabel.setEditable(false);
		xLabel.setEditable(false);
		yLabel.setEditable(false);
		widthLabel.setEditable(false);
		heightLabel.setEditable(false);

		_classNameText = new TextField();
		_classNameText.addActionListener(this);
		_classNameText.addFocusListener(this);

		_scopeIdentifierChoice = new Choice();
		_scopeIdentifierChoice.addItem("Package");
		_scopeIdentifierChoice.addItem("Public");
		_scopeIdentifierChoice.addItem("Final");
		_scopeIdentifierChoice.addItem("Public and Final");
		_scopeIdentifierChoice.setEnabled(false);


		_vertexTypeChoice = new Choice();
		_vertexTypeChoice.addItem("Construction");
		_vertexTypeChoice.addItem("Alternation");
		_vertexTypeChoice.setEnabled(false);

		_parseChoice = new Choice();
		_parseChoice.addItem("Yes");
		_parseChoice.addItem("No");
		_parseChoice.setEnabled(false);

		_beforeText = new TextField();
		_afterText = new TextField();
		_beforeText.addActionListener(this);
		_afterText.addActionListener(this);
		_beforeText.addFocusListener(this);
		_afterText.addFocusListener(this);

		_xLocText = new TextField();
		_yLocText = new TextField();
		_widthText = new TextField();
		_heightText = new TextField();
		_xLocText.setEditable(false);
		_yLocText.setEditable(false);
		_widthText.setEditable(false);
		_heightText.setEditable(false);

		add(nameLabel);
		add(_classNameText);
		add(scopeLabel);
		add(_scopeIdentifierChoice);
		add(parseLabel);
		add(_parseChoice);
		add(typeLabel);
		add(_vertexTypeChoice);
		add(beforeLabel);
		add(_beforeText);
		add(afterLabel);
		add(_afterText);
		add(xLabel);
		add(_xLocText);
		add(yLabel);
		add(_yLocText);
		add(widthLabel);
		add(_widthText);
		add(heightLabel);
		add(_heightText);
		setBackground(Color.lightGray);
	}

// Display the values for the first time. This method shows construction vertex
	public void setValues(UConstVertex u,Point location,Point size)
	{
		_vertex =u;

		_className = u.get_vertexname().get_name().toString();
		_classNameText.setText(_className);

		_scopeIdentifierChoice.select(0);

		_parseChoice.select(0);

		_vertexTypeChoice.select(0);

		_beforeText.setEditable(true);
		_afterText.setEditable(true);

		_before =null;
		String before;
		if(u.get_beFore()!=null)
		{
			_before =u.get_beFore().get_syntax();
			before = u.get_beFore().get_syntax();
		}
		else
			before="";
		_beforeText.setText(before);

		_after = null;
		String after;
		if(u.get_afTer()!=null)
		{
			_after = u.get_afTer().get_syntax();
			after = u.get_afTer().get_syntax();
		}
		else
			after="";
		_afterText.setText(after);

		Integer xLoc = new Integer(location.x);
		_xLocText.setText(xLoc.toString());
		Integer yLoc = new Integer(location.y);
		_yLocText.setText(yLoc.toString());
		Integer width = new Integer(size.x);
		_widthText.setText(width.toString());
		Integer height = new Integer(size.x);
		_heightText.setText(height.toString());
	}
	
// Display the values for the first time. This method shows alternation vertex
	public void setValues(UAltVertex u,Point location,Point size)
	{
		_vertex =u;

		_className = u.get_vertexname().get_name().toString();
		_classNameText.setText(_className);

		_scopeIdentifierChoice.select(0);

		_parseChoice.select(1);

		_vertexTypeChoice.select(1);

		String before="Not Applicable";
		_beforeText.setText(before);
		_beforeText.setEditable(false);

		String after="Not Applicable";
		_afterText.setText(after);
		_afterText.setEditable(false);

		Integer xLoc = new Integer(location.x);
		_xLocText.setText(xLoc.toString());
		Integer yLoc = new Integer(location.y);
		_yLocText.setText(yLoc.toString());
		Integer width = new Integer(size.x);
		_widthText.setText(width.toString());
		Integer height = new Integer(size.x);
		_heightText.setText(height.toString());
	}

// Event handling. Need to consider only ActionEvent and FocusEvent
// All changes are made only when user presses enter key and the new value is appropriate.
// If the focus is lost before hitting enter key old value is restored.
	public void actionPerformed(ActionEvent event)
	{
		Object source = event.getSource();
		if(source == _classNameText)
		{
			String newName = _classNameText.getText().trim();
			// Check if the class name is left blank
			if(newName.length()<=0)
			{
				_pw.showMessage("Name is compulsory");
				return;
			}
			if(newName.equals(_className))   // User didn't make any change to the name
			{
				_pw.setDefaultMessage();
				return;
			}
			// Check if the class name is valid class name
			ClassName cn;
			try{cn = ClassName.parse(newName);}
			catch(RuntimeException pe)
			{
				_pw.showMessage("Not a valid class name.");
				_classNameText.select(0,newName.length());
				_classNameText.requestFocus();
				return;
			}
			// Check if new value is parsable but results in inconsistency e.g. space in between
			if(!newName.equals(cn.get_name().toString()))
			{
				_pw.showMessage("Parser interpreted differently.");
				_classNameText.select(0,newName.length());
				_classNameText.requestFocus();
				return;
			}
			// Check if the new name is already used
			boolean duplicate = false;
			duplicate = _editor.curDocument().net().checkThisOut(newName);
			if(duplicate)
			{
				_pw.showMessage("Name is already present");
				_classNameText.select(0,newName.length());
				_classNameText.requestFocus();
				return;
			}
			// All set make the changes

			_className = newName;
			_vertex.set_label(_editor.curDocument(),_className);
			_vertex.get_persp().get_figure().set_label(_className,_editor.curDocument());
			_editor.curDocument().damaged(_vertex.get_persp());
		_editor.curDocument().cdNeedsSaving(true);
		}
		else
		if(source == _beforeText) // modifying the before syntax
		{
			String newBefore = _beforeText.getText().trim();
			String oldBefore;
			if(_before == null)
				oldBefore = "";
			else
				oldBefore = _before;

			if(oldBefore.equals(newBefore))
				return;

			if(newBefore.equals(""))
			{
				_before =null;
				((UConstVertex)_vertex).set_beforeSyntax(null);
			}
			else
			{
				_before = newBefore;
				((UConstVertex)_vertex).set_beforeSyntax(_before);
			}
		_editor.curDocument().cdNeedsSaving(true);
		}
		else
		{ 
			// modifying the after syntax
			String newAfter = _afterText.getText().trim();
			String oldAfter;
			if(_after == null)
				oldAfter = "";
			else
				oldAfter = _after;

			if(oldAfter.equals(newAfter))
				return;


			if(newAfter.equals(""))
			{
				_after=null;
				((UConstVertex)_vertex).set_afterSyntax(null);
			}
			else
			{
				_after = newAfter;
				((UConstVertex)_vertex).set_afterSyntax(_after);
			}
		_editor.curDocument().cdNeedsSaving(true);
		}
		_pw.setDefaultMessage();
	}

	public void focusGained(FocusEvent event){}
	public void focusLost(FocusEvent event)
	{
		Object source = event.getSource();
		if(source == _classNameText)
			_classNameText.setText(_className);
		else
		if(source == _beforeText) // modifying the before syntax
		{
			if(_before == null)
				_beforeText.setText("");
			else
				_afterText.setText(_before);
		}
		else
		if(source == _afterText) // modifying the after syntax
		{
			if(_after == null)
				_afterText.setText("");
			else
				_afterText.setText(_after);
		}

	}

} /* end class VertPanel */

