//----------------------------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.StringTokenizer;
import java.util.Vector;

import org.huihoo.workflow.event.WorkEventListener;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.huihoo.workflow.xpdl.WorkflowProcess;
import org.huihoo.workflow.xpdl.WorkflowTransition;
import org.huihoo.workflow.xpdl.XPDLGlobals;
import org.huihoo.workflow.xpdl.activity.ActivityType;
import org.huihoo.workflow.xpdl.activity.Implementation;
import org.huihoo.workflow.xpdl.activity.JoinType;
import org.huihoo.workflow.xpdl.activity.NoImplementation;
import org.huihoo.workflow.xpdl.activity.PerformerMode;
import org.huihoo.workflow.xpdl.activity.PerformerType;
import org.huihoo.workflow.xpdl.activity.SplitType;
import org.huihoo.workflow.xpdl.activity.ToolImplementation;
import org.huihoo.workflow.xpdl.activity.ToolSet;
import org.huihoo.workflow.xpdl.util.Duration;

public class WorkflowActivityImpl extends WorkflowActivity
{
	protected ActivityType activityType = ActivityType.ACTIVITY_BUSINESS;
	
	protected WorkflowProcess workflowProcess;
	protected List inTransitions = new ArrayList();
	protected List validInTransitions = new ArrayList();
	
	protected List outTransitions = new ArrayList();
	protected List validOutTransitions = new ArrayList();
	
	protected PerformerType performerType = PerformerType.PERFORMER_AUTOMATION;
	protected PerformerMode performerMode = PerformerMode.WHOLE_SELECTION;
	
	protected JoinType joinType = JoinType.JOIN_UNKNOWN;
	protected SplitType splitType = SplitType.SPLIT_UNKNOWN;

	protected Duration duration;
	
	//store uuid(@link uuid of WorkflowParticipant) in list 
	protected List performers = new ArrayList(0);
	protected Implementation implementation;
	
	protected String listenerClassName;
	protected Vector listeners = new Vector();
	
	public WorkflowActivityImpl()
	{
		this(null,null);
	}
	public WorkflowActivityImpl(String uuid_, String name)
	{
		this(uuid_, name, null);
	}
	public WorkflowActivityImpl(String uuid_, String name, String description)
	{
		super(uuid_, name, description);
		
	}
	public Duration getDuration()
	{
		return (this.duration);
	}
	public void setDuration(Duration duration_)
	{
		this.duration = duration_;
	}
	public void setDuration(String duration_)
	{
		this.duration = new Duration(duration_);
	}
	public WorkflowProcess getWorkflowProcess()
	{
		return (this.workflowProcess);
	}
	public void setWorkflowProcess(WorkflowProcess workflowProcess_)
	{
		this.workflowProcess = workflowProcess_;
	}
	public List getIncomingTransitions()
	{
		return (this.inTransitions);
	}
	
	public List getValidIncomingTransitions()
	{
		return (this.validInTransitions);
	}
	
	public void addIncomingTransition(WorkflowTransition transition)
	{
		if (transition != null && !this.inTransitions.contains(transition))
		{
			this.inTransitions.add(transition);
			if(!transition.isHidden())
			{
				this.validInTransitions.add(transition);
			}
		}
	}
	
	public WorkflowTransition removeIncomingTransition(WorkflowTransition transition)
	{
		this.inTransitions.remove(transition);
		if(!transition.isHidden())
		{
			this.validInTransitions.remove(transition);
		}
		return transition;
	}


	public List getOutgoingTransitions()
	{
		return (this.outTransitions);
	}
	
	public List getValidOutgoingTransitions()
	{
		return (this.validOutTransitions);
	}
	
	public void addOutgoingTransition(WorkflowTransition transition)
	{
		if (transition != null && !this.outTransitions.contains(transition))
		{
			this.outTransitions.add(transition);
			if(!transition.isHidden())
			{
				this.validOutTransitions.add(transition);
			}
		}
	}
	public WorkflowTransition removeOutgoingTransition(WorkflowTransition transition)
	{
		this.outTransitions.remove(transition);
		if(!transition.isHidden())
		{
			this.validOutTransitions.remove(transition);
		}
		return transition;
	}

	public SplitType getSplitType()
	{
		return (this.splitType);
	}
	public void setSplitType(SplitType splitType_)
	{
		this.splitType = splitType_;
	}
	public void setSplitType(String splitType_)
	{
		this.splitType = SplitType.parse(splitType_);
	}
	public JoinType getJoinType()
	{
		return (this.joinType);
	}
	public void setJoinType(JoinType joinType_)
	{
		this.joinType = joinType_;
	}
	public void setJoinType(String joinType_)
	{
		this.joinType = JoinType.parse(joinType_);
	}
	public ActivityType getActivityType()
	{
		return activityType;
	}
	public void setActivityType(ActivityType activityType)
	{
		this.activityType = activityType;
	}
	public void setActivityType(String activityType)
	{
		this.activityType = ActivityType.parse(activityType);
	}
	public Implementation getImplementation()
	{
		if (this.implementation == null)
		{
			this.implementation = new NoImplementation();
		}
		return (this.implementation);
	}
	public void setImplementation(Implementation impl)
	{
		this.implementation = impl;
	}
	public void parsePerformers(String performers_)
	{
		//to add code here
		if (performers_ == null || performers_.length() == 0)
		{
			return;
		}

		this.performers.clear();

		StringTokenizer token = new StringTokenizer(performers_, XPDLGlobals.PERFORMER_SEPARATOR);
		while (token.hasMoreTokens())
		{
			this.performers.add(token.nextToken());
		}
	}
	public List getPerformers()
	{
		return (this.performers);
	}

	public synchronized void addPerformer(String performerID)
	{
		if (this.performers == null)
		{
			this.performers = new ArrayList();
		}

		if (!performers.contains(performerID))
		{
			performers.add(performerID);
		}
	}

	public synchronized String removePerformer(String performerID)
	{
		if (performers != null && performers.contains(performerID))
		{
			performers.remove(performerID);
		}

		return null;
	}

	public PerformerType getPerformerType()
	{
		return (this.performerType);
	}
	public void setPerformerType(PerformerType performerType_)
	{
		this.performerType = performerType_;
	}
	
	public PerformerMode getPerformerMode()
	{
		return (this.performerMode);
	}
	public void setPerformerMode(PerformerMode performerMode_)
	{
		this.performerMode = performerMode_;
	}
	
	public synchronized void addWorkListener(WorkEventListener listener)
	{
		listeners.addElement(listener);
	}
	public synchronized void removeWorkListener(WorkEventListener listener)
	{
		listeners.removeElement(listener);
	}
	public synchronized WorkEventListener[] getWorkListeners()
	{
		WorkEventListener[] lns = null;
		Vector listeners_copy = null;
		synchronized (listeners)
		{
			listeners_copy = (Vector) listeners.clone();
		}
		int sizeLNS = listeners_copy.size();
		if (sizeLNS > 0)
		{
			lns = new WorkEventListener[sizeLNS];
			for (int i = 0; i < sizeLNS; ++i)
			{
				lns[i] = (WorkEventListener) listeners_copy.elementAt(i);
			}
		}
		else
		{
			lns = new WorkEventListener[0];
		}
		return lns;
	}

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

	//-----------------------------------------------only used by XPDLParser
	//@see XPDLParserFile
	public void addToolImplementation(ToolImplementation toolImpl)
	{
		if (toolImpl == null)
		{
			return;
		}

		if (implementation instanceof ToolImplementation)
		{
			ToolImplementation temp = (ToolImplementation) implementation;
			implementation = new ToolSet();
			ToolSet toolSet = (ToolSet) implementation;
			toolSet.addToolKit(temp);
			toolSet.addToolKit(toolImpl);
		}
		else if (implementation instanceof ToolSet)
		{
			ToolSet toolSet = (ToolSet) implementation;
			toolSet.addToolKit(toolImpl);
		}
		else
		{
			implementation = new ToolSet();
			ToolSet toolSet = (ToolSet) implementation;
			toolSet.addToolKit(toolImpl);
		}

	}

	public String getTagName()
	{
		return "Activity";
	}
	
	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();
	}
}
