//----------------------------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.tree;
//import org.huihoo.workflow.xpdl.participant.*;//import org.huihoo.workflow.xpdl.application.Application;//import org.huihoo.workflow.xpdl.data.DataField;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;

import org.huihoo.god4j.GOD4JFactory;
import org.huihoo.god4j.util.StringManager;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.huihoo.workflow.xpdl.WorkflowApplication;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.WorkflowParameter;
import org.huihoo.workflow.xpdl.WorkflowProcess;
import org.huihoo.workflow.xpdl.WorkflowTransition;
import org.huihoo.workflow.xpdl.activity.ActivityType;
public class NodeExplorerModel extends DefaultTreeModel
{
	private static StringManager sm = StringManager.getManager(ExplorerConstants.PACKAGE);

	private NodeExplorer nodeTree = null;

	private DefaultMutableTreeNode appsNode = null;
	private DefaultMutableTreeNode paramsNode = null;
	private DefaultMutableTreeNode processesNode = null;

	//designer Process TreeNode for search
	private Map processesMap = new HashMap();
	private Map nodesMap = new HashMap();

	public NodeExplorerModel(NodeExplorer nodeTree)
	{
		super(null);
		this.nodeTree = nodeTree;
		this.addTreeModelListener(new NodeExplorerModelListener(this.nodeTree));
	}
	public void loadDocument()
	{
		cleanNodeExplorerModel();

		WorkflowPackage pkg = GOD4JFactory.getGOD4J().getDocument();
		if (pkg != null)
		{
			DefaultMutableTreeNode pkgNode = new DefaultExplorerNode(ExplorerConstants.NODE_PACKAGE, pkg);
			this.setRoot(pkgNode);

			this.paramsNode =
				new DefaultExplorerNode(sm.getString("nodeTree.parametersLabel"), ExplorerConstants.NODE_PARAMETERS);
			this.insertNodeInto(paramsNode, pkgNode, pkgNode.getChildCount());

			List paramList = pkg.getWorkflowParameters();
			Iterator iterator = paramList.iterator();
			while (iterator.hasNext())
			{
				addWorkflowParameter((WorkflowParameter) iterator.next());
			}

			this.appsNode =
				new DefaultExplorerNode(sm.getString("nodeTree.applicationsLabel"), ExplorerConstants.NODE_APPLICATIONS);
			this.insertNodeInto(appsNode, pkgNode, pkgNode.getChildCount());
			List appList = pkg.getWorkflowApplications();
			iterator = appList.iterator();
			while (iterator.hasNext())
			{
				addWorkflowApplication((WorkflowApplication) iterator.next());
			}

			this.processesNode =
				new DefaultExplorerNode(sm.getString("nodeTree.processesLabel"), ExplorerConstants.NODE_PROCESSES);
			this.insertNodeInto(processesNode, pkgNode, pkgNode.getChildCount());

			//-----------------------------------------------------------
			//
			//-----------------------------------------------------------
			WorkflowProcess mainProc = pkg.getMainProcess();
			addWorkflowProcess(mainProc, false);

			List processList = pkg.getWorkflowProcesses();
			WorkflowProcess wfProc = null;
			for (int i = 0; i < processList.size(); ++i)
			{
				wfProc = (WorkflowProcess) processList.get(i);
				if (!wfProc.getUUID().equals(mainProc.getUUID()))
				{
					addWorkflowProcess(wfProc, true);
				}
			}
		}
	}
	public void addWorkflowParameter(WorkflowParameter parameter)
	{
		DefaultMutableTreeNode paramNode =  new DefaultExplorerNode(ExplorerConstants.NODE_PARAMETER, parameter);
		this.insertNodeInto(paramNode, paramsNode, paramsNode.getChildCount());
		nodesMap.put(parameter.getUUID(), paramNode);
	}
	public void addWorkflowApplication(WorkflowApplication application)
	{
		DefaultMutableTreeNode appNode = new DefaultExplorerNode(ExplorerConstants.NODE_APPLICATION, application);
		this.insertNodeInto(appNode, appsNode, appsNode.getChildCount());
		nodesMap.put(application.getUUID(), appNode);
	}
	public void addWorkflowActivity(WorkflowActivity activity)
	{
		ActivityType act_type = activity.getActivityType();
		int int_act_type = ExplorerConstants.NODE_ACTIVITY_BUSINESS;

		if (act_type != null)
		{
			if (ActivityType.ACTIVITY_BEGIN.equals(act_type))
			{
				int_act_type = ExplorerConstants.NODE_ACTIVITY_BEGIN;
			}
			else if (ActivityType.ACTIVITY_END.equals(act_type))
			{
				int_act_type = ExplorerConstants.NODE_ACTIVITY_END;
			}
			else if (ActivityType.ACTIVITY_ROUTE.equals(act_type))
			{
				int_act_type = ExplorerConstants.NODE_ACTIVITY_ROUTE;
			}
			else if (ActivityType.ACTIVITY_SUBFLOW.equals(act_type))
			{
				int_act_type = ExplorerConstants.NODE_ACTIVITY_SUBFLOW;
			}
		}

		DefaultMutableTreeNode actNode = new DefaultExplorerNode(int_act_type, activity);
		WorkflowProcessNodeObject processObject =
			(WorkflowProcessNodeObject) processesMap.get(activity.getWorkflowProcess().getUUID());
		DefaultMutableTreeNode activitysNode = processObject.activitysNode;
		this.insertNodeInto(actNode, activitysNode, activitysNode.getChildCount());
		nodesMap.put(activity.getUUID(), actNode);
	}
	public void addWorkflowTransition(WorkflowTransition transition)
	{
		DefaultMutableTreeNode transitionNode = new DefaultExplorerNode(ExplorerConstants.NODE_TRANSITION, transition);
		WorkflowProcessNodeObject processObject =
			(WorkflowProcessNodeObject) processesMap.get(transition.getWorkflowProcess().getUUID());
		DefaultMutableTreeNode transitionsNode = processObject.transitionsNode;
		this.insertNodeInto(transitionNode, transitionsNode, transitionsNode.getChildCount());
		nodesMap.put(transition.getUUID(), transitionNode);
	}
	public void addWorkflowProcess(WorkflowProcess process, boolean is_subprocess)
	{
		WorkflowProcessNodeObject processObject = new WorkflowProcessNodeObject(process, is_subprocess);
		processesMap.put(process.getUUID(), processObject);

		DefaultMutableTreeNode wpNode = new DefaultExplorerNode(ExplorerConstants.NODE_PROCESS, process);
		this.insertNodeInto(wpNode, processesNode, processesNode.getChildCount());
		nodesMap.put(process.getUUID(), wpNode);

		DefaultMutableTreeNode actsNode =
			new DefaultExplorerNode(sm.getString("nodeTree.activitiesLabel"), ExplorerConstants.NODE_ACTIVITIES);
		this.insertNodeInto(actsNode, wpNode, wpNode.getChildCount());
		processObject.activitysNode = actsNode;

		DefaultMutableTreeNode transitionNode =
			new DefaultExplorerNode(sm.getString("nodeTree.transitionsLabel"), ExplorerConstants.NODE_TRANSITIONS);
		this.insertNodeInto(transitionNode, wpNode, wpNode.getChildCount());
		processObject.transitionsNode = transitionNode;

		List actList = process.getWorkflowActivities();
		Iterator iterator = actList.iterator();
		while (iterator.hasNext())
		{
			addWorkflowActivity((WorkflowActivity) iterator.next());
		}

		List tranList = process.getWorkflowTransitions();
		iterator = tranList.iterator();
		while (iterator.hasNext())
		{
			addWorkflowTransition((WorkflowTransition) iterator.next());
		}

	}

	public WorkflowProcessNodeObject findWorkflowProcessNodeObject(String processID)
	{
		return (WorkflowProcessNodeObject) processesMap.get(processID);
	}

	public void setSelectionNode(String objUUID)
	{
		DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) nodesMap.get(objUUID);
		if (this.getPathToRoot(treeNode) == null)
		{
			return;
		}
		TreePath path = new TreePath(this.getPathToRoot(treeNode));
		if (!nodeTree.isPathSelected(path))
		{
			nodeTree.scrollPathToVisible(path);
			nodeTree.setSelectionPath(path);
		}
		else
		{
			GOD4JFactory.getGOD4J().setEventTrigger(null);
		}
	}

	public void removeWorkflowParameter(WorkflowParameter parameter)
	{
		MutableTreeNode node = (MutableTreeNode) nodesMap.get(parameter.getUUID());
		if (node != null)
		{
			removeNodeFromParent(node);
		}
		nodesMap.remove(parameter.getUUID());
	}
	public void removeWorkflowApplication(WorkflowApplication application)
	{
		MutableTreeNode node = (MutableTreeNode) nodesMap.get(application.getUUID());
		if (node != null)
		{
			removeNodeFromParent(node);
		}
		nodesMap.remove(application.getUUID());
	}
	public void removeWorkflowActivity(WorkflowActivity activity)
	{
		MutableTreeNode node = (MutableTreeNode) nodesMap.get(activity.getUUID());
		if (node != null)
		{
			removeNodeFromParent(node);
		}
		nodesMap.remove(activity.getUUID());
	}
	public void removeWorkflowTransition(WorkflowTransition transition)
	{
		MutableTreeNode node = (MutableTreeNode) nodesMap.get(transition.getUUID());
		if (node != null)
		{
			removeNodeFromParent(node);
		}
		nodesMap.remove(transition.getUUID());
	}

	public void removeWorkflowProcess(WorkflowProcess process)
	{
		MutableTreeNode node = (MutableTreeNode) nodesMap.get(process.getUUID());
		if (node != null)
		{
			removeNodeFromParent(node);
		}
		nodesMap.remove(process.getUUID());
	}

	protected void cleanNodeExplorerModel()
	{
		processesMap.clear();
		nodesMap.clear();

		this.setRoot(null);
	}
}
