//----------------------------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/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE-----------------------------
package org.huihoo.workflow.coreImpl.xpdl;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.huihoo.workflow.event.CaseEventListener;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.WorkflowProcess;
import org.huihoo.workflow.xpdl.WorkflowProcessHeader;
import org.huihoo.workflow.xpdl.WorkflowTransition;

public class WorkflowProcessImpl extends WorkflowProcess
{
	protected boolean expired;

	protected WorkflowPackage workflowPackage;
	protected WorkflowProcessHeader processHeader;

	protected List transitions = new ArrayList();
	protected List activities = new ArrayList();

	protected Vector listeners = new Vector();
	protected String listenerClassName;

	public WorkflowProcessImpl()
	{
		super();
	}
	public WorkflowProcessImpl(String uuid_, String name_)
	{
		super(uuid_, name_);
	}
	public WorkflowProcessImpl(String uuid_, String name_, String description_)
	{
		super(uuid_, name_, description_);
	}

	public WorkflowPackage getWorkflowPackage()
	{
		return (this.workflowPackage);
	}

	public void setWorkflowPackage(WorkflowPackage workflowPackage_)
	{
		this.workflowPackage = workflowPackage_;
	}

	public List getActivities()
	{
		return (this.activities);
	}

	public List getTransitions()
	{
		return (this.transitions);
	}

	public WorkflowProcessHeader getProcessHeader()
	{
		if (this.processHeader == null)
		{
			this.processHeader = new WorkflowProcessHeaderImpl();
		}
		return (this.processHeader);
	}

	public void setProcessHeader(WorkflowProcessHeader processHeader_)
	{
		this.processHeader = processHeader_;
	}

	public boolean isExpired()
	{
		return (this.expired);
	}

	public void setExpired(boolean expired_)
	{
		this.expired = expired_;
	}

	public WorkflowActivity findActivity(String activityId)
	{
		if (activityId == null)
		{
			return null;
		}

		int size = activities.size();
		for (int i = 0; i < size; ++i)
		{
			WorkflowActivity target = (WorkflowActivity) activities.get(i);
			if (target.getUUID().equals(activityId))
			{
				return target;
			}
		}
		return null;
	}

	public WorkflowActivity findActivity(String activityNameOrID, boolean findByUUID)
	{
		if (activityNameOrID == null)
		{
			return null;
		}

		if (findByUUID)
		{
			return findActivity(activityNameOrID);
		}

		int size = activities.size();
		for (int i = 0; i < size; ++i)
		{
			WorkflowActivity target = (WorkflowActivity) activities.get(i);
			if (activityNameOrID.equals(target.getName()))
			{
				return target;
			}
		}
		return null;
	}

	public WorkflowTransition findTransition(String transitionId)
	{
		if (transitionId == null)
		{
			return null;
		}

		int size = transitions.size();
		for (int i = 0; i < size; ++i)
		{
			WorkflowTransition target = (WorkflowTransition) transitions.get(i);
			if (transitionId.equals(target.getUUID()))
			{
				return target;
			}
		}
		return null;
	}

	public WorkflowTransition findTransition(String transitionNameOrID, boolean findByUUID)
	{
		if (transitionNameOrID == null)
		{
			return null;
		}

		if (findByUUID)
		{
			return findTransition(transitionNameOrID);
		}

		int size = transitions.size();
		for (int i = 0; i < size; ++i)
		{
			WorkflowTransition target = (WorkflowTransition) transitions.get(i);
			if (transitionNameOrID.equals(target.getName()))
			{
				return target;
			}
		}
		return null;
	}

	public WorkflowTransition findTransition(WorkflowActivity fromActivity, WorkflowActivity toActivity)
	{
		WorkflowTransition target = null;
		WorkflowActivity from = null;
		WorkflowActivity to = null;

		for (int i = 0; i < transitions.size(); ++i)
		{
			target = (WorkflowTransition) transitions.get(i);
			from = target.getFromActivity();
			to = target.getToActivity();

			if (from.equals(fromActivity) && to.equals(toActivity))
			{
				return target;
			}
		}
		return null;
	}

	public void addActivity(WorkflowActivity activity)
	{
		if (activities.contains(activity))
		{
			return;
		}
		activity.setWorkflowProcess(this);
		this.activities.add(activity);
	}

	public WorkflowActivity removeActivity(WorkflowActivity activity)
	{
		if (!activities.contains(activity))
		{
			return null;
		}

		activities.remove(activity);
		activity.setWorkflowProcess(null);
		return activity;
	}

	public void addTransition(WorkflowTransition transition)
	{
		if (transitions.contains(transition))
		{
			return;
		}
		transition.setWorkflowProcess(this);
		this.transitions.add(transition);
	}

	public WorkflowTransition removeTransition(WorkflowTransition transition)
	{
		if (!transitions.contains(transition))
		{
			return null;
		}

		transitions.remove(transition);
		transition.setWorkflowProcess(null);
		return transition;
	}

	public synchronized void addCaseListener(CaseEventListener listener)
	{
		listeners.addElement(listener);
	}

	public synchronized void removeCaseListener(CaseEventListener listener)
	{
		listeners.removeElement(listener);
	}

	public synchronized CaseEventListener[] getCaseListeners()
	{
		CaseEventListener[] lns = null;
		Vector listeners_copy = null;

		synchronized (listeners)
		{
			listeners_copy = (Vector) listeners.clone();
		}

		int sizeLNS = listeners_copy.size();
		if (sizeLNS > 0)
		{
			lns = new CaseEventListener[sizeLNS];

			for (int i = 0; i < sizeLNS; ++i)
			{
				lns[i] = (CaseEventListener) listeners_copy.elementAt(i);
			}
		}
		else
		{
			lns = new CaseEventListener[0];
		}
		return lns;
	}

	public String getListenerClassName()
	{
		return listenerClassName;
	}
	public void setListenerClassName(String className)
	{
		listenerClassName = className;
	}

	public String getTagName()
	{
		return "WorkflowProcess";
	}
	
	public String toString()
	{
		StringBuffer sb = new StringBuffer();
		
		sb.append("[");
		sb.append(getTagName()+":");
		sb.append("[uuid=");
		sb.append(uuid==null ? "?" : uuid);
		sb.append("],");
		sb.append("[name=");
		sb.append(name==null ? "?" : name);
		sb.append("]");
		sb.append("]");
		
		return sb.toString();
	}
}
