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

import org.huihoo.god4j.editor.panels.JavaControlPanel;
import org.huihoo.god4j.editor.panels.JavaGroupPanel;
import org.huihoo.god4j.editor.panels.JavaPanel;
import org.huihoo.god4j.editor.panels.JavaTableControlPanel;
import org.huihoo.god4j.editor.panels.JavaTablePanel;
import org.huihoo.workflow.WorkflowComplexComponent;
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 XPDLCollection extends XPDLComponent
{
	/** The collection of elements. */
	public transient ArrayList component_elements = null;
	/**
	* Visually presents the collection of elements. The default panel is
	* instance of {@link XPDLTablePanel} class.
	*/
	protected transient JavaPanel controlledPanel;
	/**
	* The panel consisted of control buttons. It controls the process
	* of adding, deleting and modifying the elements of collection.
	* The default panel is instance of {@link XPDLTableControlPanel} class.
	*/
	protected transient JavaControlPanel controlPanel;

	/**
	* Create collection which is owned by specified owner.
	*
	* @param parent the program equivalence to an XPDL schema defined
	*                element that holds the XPDL schema collection presented
	*                by this class instance.
	*/
	public XPDLCollection(XPDLComplexComponent parent)
	{
		this(parent, null);
	}
	public XPDLCollection(XPDLComplexComponent parent, String name)
	{
		super(parent, name);
	}

	/** Adds new element to collection. */
	public void addComponent(XPDLCollectionComponent el)
	{
		component_elements.add(el);
	}
	/** Removes specified element from collection. */
	public void removeComponent(Object el)
	{
		component_elements.remove(el);
	}

	public XPDLComplexComponent getOwnerComponent()
	{
		return getParentComponent();
	}

	/** Returns the number of elements within collection. */
	public int size()
	{
		return component_elements.size();
	}
	/** Clears the collection. */
	public void clear()
	{
		component_elements.clear();
	}

	public XPDLCollectionComponent findComponent(int index)
	{
		try
		{
			return (XPDLCollectionComponent)component_elements.get(index);
		}
		catch (Exception ex)
		{
			return null;
		}
	}

	public XPDLCollectionComponent findComponent(String compID)
	{
		if (compID == null)
		{
			return null;
		}

		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent cetmp = (XPDLCollectionComponent) it.next();
			if (compID.equals(cetmp.getUUID()))
			{
				return cetmp;
			}
		}

		return null;
	}

	public XPDLCollectionComponent findComponent(String nameOrID, boolean isID)
	{
		if (nameOrID == null)
		{
			return null;
		}

		if (isID)
		{
			return findComponent(nameOrID);
		}

		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent cetmp = (XPDLCollectionComponent) it.next();
			if (nameOrID.equals(cetmp.getName()))
			{
				return cetmp;
			}
		}
		return null;
	}

	/**
	* Sets the collection and all contained elements to be read only or not.
	*/
	public void setReadOnly(boolean ro)
	{
		isReadOnly = ro;
		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLComponent el = (XPDLComponent) it.next();
			el.setReadOnly(ro);
		}
	}
	
	/**
	* Returns <tt>true</tt> if there is no elements within collection.
	*/
	public boolean isEmpty()
	{
		return size() == 0;
	}

	/** Returns the collection of all elements within collection. */
	public Collection toCollection()
	{
		return component_elements;
	}

	/**
	* Generates the new element that made collection. Derived classes
	* has to implement this method to create it's collection element.
	*/
	public XPDLCollectionComponent demoComponent()
	{
		return new XPDLCollectionComponent(this);
	}

	/**
	* Returns the ordinal numbers of elements not to be displayed
	* within table panel. The ordinal numbers of elements corresponds
	* to the inserting order within {@link XPDLComplexComp#initComponent}
	* method.
	* 
	* first index is 0,second is 1, and so on ...
	*/
	public int[] getInvisibleTableIndexes()
	{
		return null;
	}

	/**
	* Gets elements that can be choosed within table. Default
	* implementation returns all elements within collection.
	*/
	public Collection getTableComponents()
	{
		return component_elements;
	}

	/**
	* Gets elements that can be choosed within some combo box. Default
	* implementation returns all elements within collection.
	*/
	public Collection getComboxComponents()
	{
		return component_elements;
	}

	public JavaPanel getControlledPanel()
	{
		return controlledPanel;
	}
	public JavaPanel getControlPanel()
	{
		return controlPanel;
	}

	// First, the controlled panel must be created, and then the control panel
	public JavaPanel getJavaPanel()
	{
		controlledPanel = new JavaTablePanel(this, "", false, false);
		controlPanel = new JavaTableControlPanel(this, "", true, false);
		return new JavaGroupPanel(
			this,
			new JavaPanel[] { controlledPanel, controlPanel },
			getLabel(),
			JavaPanel.BOX_LAYOUT,
			false,
			true);
	}

	public Object getValue()
	{
		return String.valueOf(component_elements.size());
	}

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

	/**
	* Returns the name of the message defined within property file
	* that explains the reason why element marked as read only
	* can't be deleted.
	*/
	public String getReadOnlyMessageName(XPDLComplexComponent el)
	{
		return "WarningCannotDeleteReadOnlyElement";
	}
	/**
	* Returns the name of the message defined within property file
	* that explains the reason why element that is in use
	* can't be deleted.
	*/
	public String getInUseMessageName(XPDLComplexComponent el)
	{
		return "WarningCannotDeleteElementThatIsInUse";
	}

	// must make new collection that consists of the same elements as
	// previous one
	public Object clone()
	{
		XPDLCollection d = (XPDLCollection) super.clone();
		d.component_elements = new ArrayList();
		Iterator it = this.component_elements.iterator();
		while (it.hasNext())
		{
			XPDLComponent el = (XPDLComponent) it.next();
			d.component_elements.add(el.clone());
		}

		return d;
	}

	//==================================================================
	public void initComponent()
	{
		//	-----------------------------------------------
		super.initComponent();
		//	-----------------------------------------------	
		component_elements = new ArrayList();
	}

	public void structComponent()
	{
		//	-----------------------------------------------
		super.structComponent();
		//	-----------------------------------------------
	}

	public void loadComponent()
	{
		//	-----------------------------------------------
		super.loadComponent();
		//	-----------------------------------------------
	}

	protected void collectionLoadComponent()
	{
		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent el = (XPDLCollectionComponent) it.next();

			el.loadComponent();
		}
	}

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

		//	-----------------------------------------------
		super.saveComponent();
		//	-----------------------------------------------
		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent el = (XPDLCollectionComponent) it.next();

			el.saveComponent();
		}
	}

	public void saveComponent(WorkflowComponent workflow_component)
	{
		//	-----------------------------------------------
		super.saveComponent(workflow_component);
		//	-----------------------------------------------
		WorkflowComplexComponent xpdlElement = (WorkflowComplexComponent) workflow_component;

		Iterator it = component_elements.iterator();
		while (it.hasNext())
		{
			XPDLCollectionComponent el = (XPDLCollectionComponent) it.next();

			el.saveComponent(xpdlElement);
		}
	}

	//==================================================================

	/**
	* Some specific things to be done after element is created.
	* Default implementation is nothing to do, and derived classes
	* should implement it's specific actions.
	*/
	public void onElementCreated(XPDLComponent el)
	{
		return;
	}
	/**
	* Some specific things to be done after element is inserted.
	* into collection. Default implementation is nothing to do,
	* and derived classes should implement it's specific actions.
	*/
	public void onElementInserted(XPDLComponent el)
	{
		return;
	}
	/**
	* Some specific things to be done after element from collection
	* is modified. Default implementation is nothing to do, and derived
	* classes should implement it's specific actions.
	*/
	public void onElementModified(XPDLComponent el)
	{
		return;
	}
	/**
	* Some specific things to be done after element is deleted from
	* collection. Default implementation is nothing to do, and derived
	* classes should implement it's specific actions.
	*/
	public void onElementDeleted(XPDLComponent el)
	{
		return;
	}
	/**
	* Some specific things to be done after element is removed from
	* collection. Default implementation is nothing to do, and derived
	* classes should implement it's specific actions.
	*/
	public void onElementRemoved(XPDLComponent el)
	{
		return;
	}
	/**
	* Returns <tt>true</tt> if element can be inserted into collection.
	* Default implementation returns <tt>true</tt>, and derived classes
	* should implement it's specific check.
	*/
	public boolean canInsertElement(XPDLComponent el)
	{
		return true;
	}
	/**
	* Returns <tt>true</tt> if element can be removed from collection.
	* Default implementation returns <tt>true</tt>, and derived classes
	* should implement it's specific check.
	*/
	public boolean canRemoveElement(XPDLComponent el)
	{
		return true;
	}
	//==================================================================
}