//----------------------------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.XPDLApplication;
import org.huihoo.god4j.editor.elements.XPDLPackage;
import org.huihoo.god4j.editor.elements.XPDLProcess;
import org.huihoo.workflow.WorkflowComponent;
import org.huihoo.workflow.impl.xpdl.WorkflowApplicationImpl;
import org.huihoo.workflow.xpdl.WorkflowApplication;
import org.huihoo.workflow.xpdl.WorkflowPackage;
/**
* Represents a WfMC DTD element that has the similar name.
* This class is a collection of class <b>Application</b> instances.
*
* @see XPDL
*/
public class XPDLApplications extends XPDLCollection
{
	/**
	* Creates a new instance of the class.
	*
	* @param xpackage The class instance which member
	*                          is this class instance.
	*/
	public XPDLApplications(XPDLComplexComponent parent)
	{
		super( parent,"Applications");
	}

	/**
	* 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()
	{
		XPDLApplication a = new XPDLApplication(this, null);
		a.initComponent();
		a.structComponent();
		a.loadComponent();
		
		return a;
	}
	/**
	* It is overriden to give the caller all Applications:
	* <ul>
	* <li> If Applications instance is defined at the the workflow process level,
	*      it gives all of it's applications plus the ones defined at the package
	*      level (including all applications from externaly referenced packages).
	* <li> If Applications instance is defined at the the package level,
	*      it gives all of it's applications plus the ones from externaly
	*      referenced packages).
	* </ul>
	*/
	public Collection getTableComponents()
	{
		ArrayList allApps = new ArrayList();
		allApps.addAll(component_elements);

		return allApps;
	}
	/**
	* It is overriden to give the caller all Applications except the ones
	* with same Ids as applications on lower level:
	* <ul>
	* <li> If Applications instance is defined at the the workflow process level,
	*      it gives all of it's applications plus the ones defined at the package
	*      level (including all applications from externaly referenced packages).
	* <li> If Applications instance is defined at the the package level,
	*      it gives all of it's applications plus the ones from externaly
	*      referenced packages).
	* </ul>
	*/
	public Collection getComboxComponents()
	{
		ArrayList chos = new ArrayList();
		chos.addAll(component_elements);

		return chos;
	}
	public XPDLApplication getXPDLApplication(String ID)
	{
		return  (XPDLApplication) super.findComponent(ID);
	}
	/**
	* Checks if specified application can be removed. Application can be
	* removed only if it is not used anywhere.
	*/
	public boolean canRemoveElement(XPDLComponent el)
	{
		if (!component_elements.contains(el))
		{
			return false;
		}
		XPDLApplication toRemove = (XPDLApplication) el;
		return canRemoveApplication(toRemove);
	}
	public boolean canRemoveApplication(XPDLApplication toRemove)
	{
		boolean remove = true;
		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.canRemoveApplication(toRemove);
				if (!remove)
				{
					break;
				}
			}
		}
		return remove;
	}

	public String getReadOnlyMessageName(XPDLComplexComponent el)
	{
		if (!component_elements.contains(el))
		{
			if (parent_component instanceof XPDLPackage)
			{
				return "WarningCannotDeleteExternalApplication";
			}
		}
		return "";
	}
	public String getInUseMessageName(XPDLComplexComponent el)
	{
		return "WarningCannotDeleteApplicationThatIsInUse";
	}

	public int[] getInvisibleTableIndexes()
	{
		int[] itfo = new int[3];
		itfo[0] = 2;
		itfo[1] = 3;
		itfo[2] = 4;
		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 apps = wpkg.getWorkflowApplications();

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

		//2. add all newly WorkflowApplication
		for (int i = 0; i < apps.size(); ++i)
		{
			WorkflowApplication ap = (WorkflowApplication) apps.get(i);
			XPDLCollectionComponent el = findComponent(ap.getUUID());
			if (el == null)
			{
				XPDLApplication xpApp = new XPDLApplication(this, ap);
				xpApp.initComponent();
				xpApp.structComponent();

				addComponent(xpApp);
			}
		}
		//	-----------------------------------------------
		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;

		while (true)
		{
			List wfApps = wfPackage.getWorkflowApplications();
			int i = 0;

			for (i = 0; i < wfApps.size(); ++i)
			{
				WorkflowApplication wfApp = (WorkflowApplication) wfApps.get(i);
				XPDLApplication xpApp = (XPDLApplication) findComponent(wfApp.getUUID());
				if (xpApp != null)
				{
					continue;
				}
				
				GOD4JFactory.getGOD4J().getExplorerPanel().getNodeExplorer().removeWorkflowApplication(wfApp);
				wfApps.remove(i);
				break;
			}

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

		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent el = (XPDLCollectionComponent) it.next();
			if ((el instanceof XPDLApplication))
			{
				XPDLApplication xpApp = (XPDLApplication) el;
				WorkflowApplication wfApp = (WorkflowApplication) wfPackage.findWorkflowApplication(el.getUUID());
				if (wfApp != null)
				{
					continue;
				}

				WorkflowApplicationImpl wfAppImpl = new WorkflowApplicationImpl();
				xpApp.saveComponent(wfAppImpl);
				xpApp.setWorkflowComponent(wfAppImpl);
				wfPackage.addWorkflowApplication(wfAppImpl);
				GOD4JFactory.getGOD4J().getExplorerPanel().getNodeExplorer().addWorkflowApplication(wfAppImpl);
			}
		}
	}

	//==================================================================
}
