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

import org.huihoo.god4j.GOD4JFactory;
import org.huihoo.god4j.editor.XPDLCollection;
import org.huihoo.god4j.editor.XPDLCollectionComponent;
import org.huihoo.god4j.editor.XPDLComplexComponent;
import org.huihoo.god4j.editor.XPDLComponent;
import org.huihoo.god4j.editor.elements.XPDLDataField;
import org.huihoo.god4j.editor.elements.XPDLPackage;
import org.huihoo.god4j.editor.elements.XPDLProcess;
import org.huihoo.workflow.WorkflowComponent;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.WorkflowParameter;
/**
* Represents a WfMC DTD element that has the similar name.
* This class is a collection of class <b>DataField</b> instances.
*
* @see XPDL
*/
public class XPDLDataFields extends XPDLCollection
{
	/**
	* Creates a new instance of the class.
	*
	* @param refPackage The class instance which member is this class instance.
	*/
	public XPDLDataFields(XPDLComplexComponent parent)
	{
		super(parent, "DataFields");
	}
	/**
	* Generates a new element of the class which instances
	* are members of collection of this class.
	*
	* return The generated instance of class that makes collection.
	*/
	public XPDLCollectionComponent demoComponent()
	{
		XPDLDataField a = new XPDLDataField(this, null);
		a.initComponent();
		a.structComponent();
		a.loadComponent();

		return a;
	}
	/**
	* Returns all DataFields:
	* <ul>
	* <li> If DataFields instance is defined at the the process level,
	*      it gives all of it's data fields plus the ones defined at the package
	*      level.
	* <li> If DataFields instance is defined at the the package level,
	*      it gives all of it's data fields.
	* </ul>
	*/
	public Collection getTableComponents()
	{
		ArrayList allDFs = new ArrayList();
		if (parent_component instanceof XPDLPackage)
		{
			allDFs.addAll(component_elements);
		}
		return allDFs;
	}
	/**
	* <ul>
	* <li> If DataFields instance is defined at the the process level,
	*      it gives all of it's data fields plus the ones defined at the package
	*      level (except the ones that have the ID identical to some DataField at
	*      the process level), plus all formal parameters of process .
	* <li> If DataFields instance is defined at the the package level,
	*      it gives all of it's data fields.
	* </ul>
	*/
	public Collection getComboxComponents()
	{
		ArrayList chos = new ArrayList();
		chos.addAll(component_elements);
		return chos;
	}
	/**
	* Returns a data field with specified ID.
	*
	* @param  ID The 'Id' attribute of wanted instance of
	*         DataField element defined within collection.
	* @return The instance of DataField element that
	*         have the specified ID as an 'Id' attribute
	*         if it exist among all defined data fields within
	*         collection, if it doesn't exist, <tt>null</tt> is
	*         returned.
	*/
	public XPDLDataField getXPDLDataField(String ID)
	{
		return (XPDLDataField) super.findComponent(ID);
	}
	/**
	* Checks if specified data field can be removed. DataField can be
	* removed only if it is not used anywhere.
	*/
	public boolean canRemoveElement(XPDLComponent el)
	{
		boolean remove = true;
		XPDLDataField toRemove=(XPDLDataField)el;
		if (parent_component instanceof XPDLPackage)
		{
			XPDLProcesses wps = (XPDLProcesses) ((XPDLPackage) parent_component).get("WorkflowProcesses");
			Iterator it = wps.toCollection().iterator();
			while (it.hasNext())
			{
				XPDLProcess wp = (XPDLProcess) it.next();
				XPDLActivities acts = (XPDLActivities) wp.get("Activities");
				remove = acts.canRemoveDataFieldOrFormalParameter(toRemove);
				if (!remove)
				{
					break;
				}
				XPDLTransitions ts = (XPDLTransitions) wp.get("Transitions");
				remove = ts.canRemoveDataFieldOrFormalParameter(toRemove);
				if (!remove)
				{
					break;
				}
			}
		}
		return remove;
	}

	public String getReadOnlyMessageName(XPDLComplexComponent el)
	{
		return "WarningWorkflowRelevantDataDefinedAtPackageLevelCannotBeDeletedFromProcessLevel";
	}
	public String getInUseMessageName(XPDLComplexComponent el)
	{
		return "WarningCannotDeleteWorkflowRelevantDataThatIsInUse";
	}

	public int[] getInvisibleTableIndexes()
	{
		int[] itfo = new int[3];
		itfo[0] = 3;
		itfo[1] = 4;
		itfo[2] = 5;
		return itfo;
	}
	//==================================================================
	public void initComponent()
	{
		//	-----------------------------------------------
		super.initComponent();
		//	-----------------------------------------------	
	}
	public void structComponent()
	{
		//	-----------------------------------------------
		super.structComponent();
		//	-----------------------------------------------
	}

	public void loadComponent()
	{
		//	-----------------------------------------------
		super.loadComponent();
		//	-----------------------------------------------
		XPDLPackage pkg = (XPDLPackage) parent_component;
		WorkflowPackage wpkg = (WorkflowPackage) pkg.getWorkflowComponent();

		if (wpkg == null)
		{
			//	-----------------------------------------------
			collectionLoadComponent();
			//	-----------------------------------------------
			return;
		}
		List params = wpkg.getWorkflowParameters();

		//1. remove all missing WorkflowParameter
		List element_clones = (List) component_elements.clone();
		Iterator it = element_clones.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent el = (XPDLCollectionComponent) it.next();
			if (el instanceof XPDLDataField)
			{
				if (wpkg.findWorkflowParameter(el.getUUID()) == null)
				{
					removeComponent(el);
				}
			}
		}

		//2. add all newly WorkflowParameter
		for (int i = 0; i < params.size(); ++i)
		{
			WorkflowParameter param = (WorkflowParameter) params.get(i);
			XPDLCollectionComponent el = findComponent(param.getUUID());
			if (el == null)
			{
				XPDLDataField xpDF = new XPDLDataField(this, param);
				xpDF.initComponent();
				xpDF.structComponent();

				addComponent(xpDF);
			}
		}

		//	-----------------------------------------------
		collectionLoadComponent();
		//	-----------------------------------------------
	}

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

		//	-----------------------------------------------
		super.saveComponent();
		//	-----------------------------------------------
		WorkflowComponent workflow_component = getOwnerComponent().getWorkflowComponent();

		if ((workflow_component == null) || !(workflow_component instanceof WorkflowPackage))
		{
			return;
		}

		WorkflowPackage wfPackage = (WorkflowPackage) workflow_component;
		wfPackage.getWorkflowParameters().clear();

		while (true)
		{
			List wfParams = wfPackage.getWorkflowParameters();
			int i = 0;

			for (i = 0; i < wfParams.size(); ++i)
			{
				WorkflowParameter wfParam = (WorkflowParameter) wfParams.get(i);
				XPDLDataField xpParam = (XPDLDataField) findComponent(wfParam.getUUID());
				if (xpParam != null)
				{
					continue;
				}
				GOD4JFactory.getGOD4J().getExplorerPanel().getNodeExplorer().removeWorkflowParameter(wfParam);
				wfParams.remove(i);
				break;
			}

			if (i == wfParams.size())
			{
				break;
			}
		}

		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent el = (XPDLCollectionComponent) it.next();
			if ((el instanceof XPDLDataField))
			{
				XPDLDataField xpParam = (XPDLDataField) el;
				WorkflowParameter wfParam = (WorkflowParameter) wfPackage.findWorkflowParameter(el.getUUID());
				if (wfParam != null)
				{
					continue;
				}

				WorkflowParameter wfParamImpl = new WorkflowParameter();
				xpParam.saveComponent(wfParamImpl);
				xpParam.setWorkflowComponent(wfParamImpl);
				wfPackage.addWorkflowParameter(wfParamImpl);
				GOD4JFactory.getGOD4J().getExplorerPanel().getNodeExplorer().addWorkflowParameter(wfParamImpl);
			}
		}
	}
	//==================================================================s
}
