//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010 huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/god4j
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : god4j@lists.sourceforge.net 
 */
//----------------------------END  LICENSE-----------------------------
package org.huihoo.god4j.editor;
import java.io.Serializable;

import org.huihoo.god4j.editor.panels.JavaPanel;
import org.huihoo.god4j.util.StringManager;
import org.huihoo.workflow.WorkflowComponent;
/**
 * @author reic
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class XPDLComponent implements Serializable, Cloneable
{
	protected static StringManager sm = StringManager.getManager(EditorConstants.PACKAGE);

	//=============================================================
	private static int genEl = 0;
	//=============================================================	
	
	/**
	* Parent XPDLComplexComponent
	*/
	protected XPDLComplexComponent parent_component;

	/**
	* Equivalent for XPDL Component name. Used when writting
	* instance of this class to XPDL file.
	*/
	protected String name;
	/**
	* Language specific name of XPDL Component that is shown in
	* editing dialog.
	*/
	protected String labelName;
	/**
	* Supposed to contain the value for XPDL Component.
	* This is true for simple elements and attributes,
	* more complex elements uses it as they need.
	*/
	protected Object value;
	/**
	* Indicates if an element is required - corresponds
	* to the same XPDL Component definition.
	*/
	protected boolean isRequired = false;
	/** Used in dialogs to forbid editing of an element value. */
	protected boolean isReadOnly = false;

	public XPDLComponent(XPDLComplexComponent parent)
	{
		this(parent, null);
	}

	/**
	* Creates a new instance of element: sets the <code>name</code> member
	* to the specified one, and the <code>labelName</code> member to the
	* value read from property file under the key of previously set
	* <code>name</code> member.
	*
	* @param name The name of XPDL element that this class represents.
	*/
	public XPDLComponent(XPDLComplexComponent pparent, String pname)
	{
		this.parent_component = pparent;
		this.name = pname;

		if (this.name == null)
		{
			this.name = getClass().getName();
			int lastDot = this.name.lastIndexOf(".");
			if (lastDot >= 0)
			{
				this.name = this.name.substring(lastDot + 1);
			}
		}

		if (this.name.startsWith("XPDL") && !this.name.equals("XPDLVersion"))
		{
			this.name = this.name.substring("XPDL".length());
		}

		this.labelName = sm.getString(this.name + "Key");
		//System.out.println("Generated element no. " + (++genEl) + "," + this.name+"||"+this.name + "Key");

		value = new String();
	}

	/**
	* Sets the 'read only' property of element to the specified one.
	* This enables/disables editing of the element within dialog.
	* Some derived classes (especially class that represents complex
	* element) need to redefine this method.
	*
	* @param ro <tt>true</tt> if element will be 'read only',
	*           <tt>false</tt> otherwise.
	*/
	public void setReadOnly(boolean ro)
	{
		isReadOnly = ro;
	}
	/**
	* Returns the 'read only' status of element.
	* This indicates if the editing of element within dialog
	* is enabled or disabled.
	*
	* @return <tt>true</tt> if element is 'read only',
	*         <tt>false</tt> otherwise.
	*/
	public boolean isReadOnly()
	{
		return isReadOnly;
	}
	/**
	* Sets the 'required' property of the element.
	* If element is 'required', the dialog for editing
	* it's value can't be closed until the value is defined.
	*
	* @param r <tt>true</tt> if element will be 'required',
	*          <tt>false</tt> otherwise.
	*/
	public void setRequired(boolean r)
	{
		isRequired = r;
	}
	/**
	* Returns the 'required' property of the element.
	* If element is 'required', the dialog for editing
	* it's value can't be closed until the value is defined.
	*
	* @return <tt>true</tt> if element is 'required',
	*         <tt>false</tt> otherwise.
	*/
	public boolean isRequired()
	{
		return isRequired;
	}
	/**
	* Indicates if element is empty. Some derived classes
	* (especially class that represents complex element) need to
	* redefine this method.
	*
	* @return <tt>true</tt> if user haven't defined the element
	*         value within dialog, <tt>false</tt> otherwise.
	*/
	public boolean isEmpty()
	{
		return !(value != null && value.toString().length() > 0);
	}

	public boolean isInputValid(JavaPanel p)
	{
		return true;
	}

	public void setLabel(String lName)
	{
		labelName = lName;
	}
	/**
	* Returns the text for element 'name' presentation within
	* a dialog for editing element. This text is language
	* specific and is set reading a property file.
	*
	* @return The language specific presentation of element 'name'.
	*/
	public String getLabel()
	{
		return labelName;
	}

	/**
	* Sets the element value (in the sense of XPDL element).
	*
	* @param v The value to set.
	*/
	public void setValue(Object v)
	{
		value = v;
	}
	/**
	* Gets the element value. The value represents an XPDL
	* tag content for this element.
	*
	* @return The value of this element.
	*/
	public Object getValue()
	{
		return value;
	}

	/**
	* Returns the name of element.
	*
	* @return The 'name' attribute of element.
	*/
	public String getName()
	{
		return name;
	}

	public XPDLComplexComponent getParentComponent()
	{
		return parent_component;
	}

	public void setParentComponent(XPDLComplexComponent comp)
	{
		this.parent_component = comp;
	}

	public JavaPanel getJavaPanel()
	{
		return new JavaPanel();
	}

	//==================================================================
	/**
	* The classes that are derived from this class has to give its
	* definition for this method. It is used to insert all members
	* of those classes that are derived from XPDLComp
	* class (or classes that are derived from that class) into
	* one list, and the members that are derived from
	* XPDLAttribute class also to insert into other list.
	* Many methods of this class uses those lists:
	* <code>toXPDL</code> method uses them to properly write an element
	* tag to the XPDL file,
	* <code>fromXPDL</code> method uses them to properly read an element
	* tag from the XPDL file,
	* <code>getPanel</code> method uses them to properly display members
	* of this class,
	* <code>get</code> and <code>set</code> uses them to properly
	* retrieve/set the elements from list, ... and so on
	* <p>NOTE: The order of inserted elements is relevant for XPDL to be
	*          valid (members of classes derived from this class must be
	*          inserted into first mentioned list in the same order that
	*          they are within a corresponding tag for those classes
	*          within WfMC XPDL).
	*/	
	public void initComponent()
	{
	}

	public void structComponent()
	{
	}

	public void loadComponent()
	{
	}

	public void saveComponent()
	{
    if(isReadOnly())
    {
      return;
    }
	}

	public void saveComponent(WorkflowComponent workflow_component)
	{
	}
	
	//==================================================================

	public String toString()
	{
		if (value != null)
		{
			return value.toString();
		}
		else if (labelName != null)
		{
			return labelName;
		}

		return "";
	}

	public Object clone()
	{
		XPDLComponent d = null;
		try
		{
			//System.out.println("Cloning XPDLELement "+name);
			d = (XPDLComponent) super.clone();
			d.name = new String(this.name);
			if (this.labelName != null)
			{
				d.labelName = new String(this.labelName);
			}
			else
			{
				d.labelName = null;
			}
			if (value instanceof XPDLComponent)
			{
				d.value = ((XPDLComponent) value).clone();
			}
			else
			{
				if (this.value != null)
				{
					d.value = new String(this.value.toString());
				}
				else
				{
					this.value = null;
				}
			}
			d.isRequired = this.isRequired;
			d.isReadOnly = this.isReadOnly;
		}
		catch (CloneNotSupportedException e)
		{
			// Won't happen because we implement Cloneable
			throw new Error(e.toString());
		}

		d.parent_component = this.parent_component;
	
		return d;
	}
}