//----------------------------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.elements;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.huihoo.god4j.editor.XPDLAttribute;
import org.huihoo.god4j.editor.XPDLCollection;
import org.huihoo.god4j.editor.XPDLCollectionComponent;
import org.huihoo.god4j.editor.XPDLComponent;
import org.huihoo.god4j.editor.elements.atoms.XPDLBasicType;
import org.huihoo.god4j.editor.elements.atoms.XPDLDataType;
import org.huihoo.god4j.editor.elements.atoms.XPDLDataTypes;
import org.huihoo.god4j.editor.elements.atoms.XPDLDescription;
import org.huihoo.god4j.util.UUID;
import org.huihoo.workflow.WorkflowComponent;
import org.huihoo.workflow.xpdl.parameter.FormalParameter;
import org.huihoo.workflow.xpdl.util.TypeDefinition;
/**
* Represents a WfMC DTD element that has the similar name.
*
* @see XPDL
*/
public class XPDLFormalParameter extends XPDLCollectionComponent
{
	private XPDLDataType refDataType;
	private XPDLDescription refDescription = null; // min=0
	private XPDLAttribute attrIndex = null;
	// default="IN"
	private XPDLAttribute attrMode = null;

	/**
	* Creates a new instance of the class.
	*
	* @param fps  The reference to collection of formal parameters where
	*             this instance will be put into.
	* @param p    The package which elements holds instance of
	*             of this class.
	*/
	public XPDLFormalParameter(XPDLCollection myCollection, FormalParameter fparam)
	{
		super(myCollection,"FormalParameter");
		setWorkflowComponent(fparam);

	}

	public String toString()
	{
		return super.toString();
	}
	/**
	* Overrides parent method to display data type details for BasicType and
	* for DeclaredType.
	*/
	public Collection findChildrenValues()
	{
		java.util.List l = new ArrayList();
		Iterator it = complexChildren.iterator();
		while (it.hasNext())
		{
			XPDLComponent el = (XPDLComponent) it.next();
			if (el instanceof XPDLAttribute)
			{
				l.add(el.toString());
			}
			else if (el instanceof XPDLDataType)
			{
				XPDLDataType dt = (XPDLDataType) el;
				XPDLDataTypes dtt = dt.getDataTypes();
				Object type = dtt.getValue();
				if (type instanceof XPDLBasicType)
				{
					l.add(el.getValue() + " - " +  ((XPDLBasicType) type).getValue());
				}

				else
				{
					l.add(el.getValue());
				}
			}
			else
			{
				l.add(el.getValue());
			}
		}
		return l;
	}
	//==================================================================
	/**
	* 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()
	{
		//	-----------------------------------------------
		super.initComponent();
		//	-----------------------------------------------	
		attrIndex = new XPDLAttribute( this,"Index");
		attrIndex.initComponent();

		// default="IN"
		attrMode = new XPDLAttribute(this,"Mode",  new String[] { "", "IN", "OUT", "INOUT" }, 1);
		attrMode.initComponent();
				
		refDataType = new XPDLDataType(this);
		refDataType.initComponent();
		refDataType.setRequired(true);

		refDescription = new XPDLDescription(this); // min=0
		refDescription.initComponent();
	}

	public void structComponent()
	{
		//	-----------------------------------------------
		super.structComponent();
		//	-----------------------------------------------
		attrIndex.structComponent();
		attrMode.structComponent();
		
		refDataType.structComponent();
		refDescription.structComponent();
		
		complexChildren.add(attrIndex);
		complexChildren.add(attrMode);
		complexChildren.add(refDataType);
		complexChildren.add(refDescription);

		attributes.add(attrIndex);
		attributes.add(attrMode);
	}
	
	/**
	* Supposed to be overriden by derived classes to implement
	* element specific reading from an XPDL Model. This implementation
	* satisfies only "simple" elements.
	*/
	public void loadComponent()
	{
		//	-----------------------------------------------
		super.loadComponent();
		//	-----------------------------------------------
		attrIndex.loadComponent();
		attrMode.loadComponent();
		
		refDataType.loadComponent();
		refDescription.loadComponent();
		
		WorkflowComponent workflow_component = getWorkflowComponent();
		if (workflow_component != null && (workflow_component instanceof FormalParameter))
		{	
			FormalParameter fparam_P=(FormalParameter)getWorkflowComponent();
			attrId.setValue(fparam_P.getUUID());
			attrIndex.setValue(""+fparam_P.getIndex());
			attrMode.setValue(fparam_P.getMode().getMode());
			
			XPDLBasicType basicType=new XPDLBasicType(refDataType.getDataTypes());
			basicType.initComponent();
			basicType.loadComponent();
			basicType.setValue(TypeDefinition.javaToXPDL(fparam_P.getType()));
			refDataType.setValue(basicType);
		}
		else
		{
			attrId.setValue(UUID.generate());
		}
	}

	/**
	* Supposed to be overriden by derived classes to implement
	* element specific writting to an XPDL Model.
	*
	*/
	public void saveComponent()
	{
    if(isReadOnly())
    {
      return;
    }
    
		//	-----------------------------------------------
		super.saveComponent();
		//	-----------------------------------------------
		attrIndex.saveComponent();
		attrMode.saveComponent();
		
		refDataType.saveComponent();
		refDescription.saveComponent();
		
		WorkflowComponent workflow_component = getWorkflowComponent();
		if (workflow_component != null && (workflow_component instanceof FormalParameter))
		{
			FormalParameter fparam_P=(FormalParameter)getWorkflowComponent();
			fparam_P.setUUID(attrId.toString());
			fparam_P.setIndex(Integer.parseInt(attrIndex.toString()));			
			fparam_P.setMode(attrMode.toString());
			
			Object obj=refDataType.getValue();
			if((obj!=null) && ( obj instanceof XPDLBasicType))
			{
				fparam_P.setType(TypeDefinition.XPDLToJava(((XPDLBasicType)obj).getValue().toString()));
			}
		}
	}

	public void saveComponent(WorkflowComponent workflow_component)
	{
		//	-----------------------------------------------
		super.saveComponent(workflow_component);
		//	-----------------------------------------------
		
		attrIndex.saveComponent(workflow_component);
		attrMode.saveComponent(workflow_component);
		
		refDataType.saveComponent(workflow_component);
		refDescription.saveComponent(workflow_component);
		
		if (workflow_component != null && (workflow_component instanceof FormalParameter))
		{
			FormalParameter fparam_P=(FormalParameter)workflow_component;
			fparam_P.setUUID(attrId.toString());
			fparam_P.setIndex(Integer.parseInt(attrIndex.toString()));
			fparam_P.setMode(attrMode.toString());
			
			Object obj=refDataType.getValue();
			if((obj!=null) && ( obj instanceof XPDLBasicType))
			{
				fparam_P.setType(TypeDefinition.XPDLToJava(((XPDLBasicType)obj).getValue().toString()));
			}
		}
	}
	//==================================================================
}
