/*******************************************************************************
 * Copyright (c) 2004, 2006 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui.pageflow.synchronization;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.jst.jsf.facesconfig.emf.DescriptionType;
import org.eclipse.jst.jsf.facesconfig.emf.DisplayNameType;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigFactory;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigPackage;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;
import org.eclipse.jst.jsf.facesconfig.emf.FromViewIdType;
import org.eclipse.jst.jsf.facesconfig.emf.IconType;
import org.eclipse.jst.jsf.facesconfig.emf.LargeIconType;
import org.eclipse.jst.jsf.facesconfig.emf.NavigationCaseType;
import org.eclipse.jst.jsf.facesconfig.emf.NavigationRuleType;
import org.eclipse.jst.jsf.facesconfig.emf.SmallIconType;
import org.eclipse.jst.jsf.facesconfig.emf.ToViewIdType;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.Pageflow;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowElement;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowFactory;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowLink;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowNode;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowPage;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.impl.PageReferenceElement;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.impl.ReferenceElement;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowModelManager;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowTransform;
import org.eclipse.jst.jsf.facesconfig.ui.util.WebrootUtil;

/**
 * Update and synchronize pageflow from faces-config or vice-versa.
 * 
 * @author hmeng
 * 
 */

public class FC2PFTransformer extends AdapterImpl {

	// For code debug.
	private static final boolean DEBUG = false;

	/**
	 * the first notification event type after the defaults
	 */
	public static final int MY_NOTIFICATION_TYPE = Notification.EVENT_TYPE_COUNT + 1;

	/**
	 * the first notification event type after MY_NOTIFICATION_TYPE
	 */
	public static final int MY_NOTIFICATION_TYPE1 = MY_NOTIFICATION_TYPE + 1;

	/**
	 * The listener is active.
	 */
	private boolean listenToNotify;

	/**
	 * Avoid redundent event.
	 */
	private boolean isInEvent;

	boolean pageflowChanged = false;

	/**
	 * Perform operations batched.
	 */
	boolean needBatchOperations = false;

	/**
	 * Catches
	 */
	private Map mapPaths2PF = new HashMap();

	private Map mapCases2Links = new HashMap();

	/**
	 * The pageflow model.
	 */
	private Pageflow pageflow;

	/**
	 * The faces-config model.
	 */
	FacesConfigType facesConfig;

	/**
	 * Default constructor
	 */
	public FC2PFTransformer() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param listenToNotify
	 */
	public void setListenToNotify(boolean listenToNotify) {
		this.listenToNotify = listenToNotify;
	}

	private void postEMFChanged() {
		startFCNotify();
		// Refresh all facesConfig?
		facesConfig.eNotify(new ENotificationImpl(
				(InternalEObject) facesConfig, Notification.REMOVE,
				FacesConfigPackage.FACES_CONFIG_TYPE__NAVIGATION_RULE, null,
				null));
		List rules;
		rules = facesConfig.getNavigationRule();
		for (int i = 0; i < rules.size(); i++) {
			((NavigationRuleType) rules.get(i)).eNotify(new ENotificationImpl(
					(InternalEObject) rules.get(i), Notification.REMOVE,
					FacesConfigPackage.NAVIGATION_RULE_TYPE__NAVIGATION_CASE,
					null, null));
		}
	}

	/**
	 * Set notify adapters.
	 * 
	 */
	private void startFCNotify() {
		TreeIterator iterator = facesConfig.eAllContents();
		while (iterator.hasNext()) {
			EObject object = (EObject) iterator.next();
			object.eSetDeliver(true);
		}
		facesConfig.eSetDeliver(true);
	}

	/**
	 * Set not notify adapters
	 * 
	 * @return
	 */
	private TreeIterator stopFCNotify() {
		TreeIterator iterator = facesConfig.eAllContents();
		// Stop the listener
		while (iterator.hasNext()) {
			EObject object = (EObject) iterator.next();
			object.eSetDeliver(false);
		}
		facesConfig.eSetDeliver(false);
		return iterator;
	}

	/**
	 * For performance issue, we are going to update DOM only after the EMF
	 * modifications are done.
	 */
	boolean isNeedBatchOperations() {
		return needBatchOperations;
	}

	/**
	 * @param enable
	 */
	public void setNeedBatchOperations(boolean enable) {
		this.needBatchOperations = enable;
		if (!enable) {
			isInEvent = true;
			postEMFChanged();
			isInEvent = false;
		} else {
			stopFCNotify();
		}
	}

	private void updateFacesRule(NavigationRuleType navigationRule,
			PageflowPage pageSource) {
		FacesConfigFactory factory = FacesConfigFactory.eINSTANCE;
		if (pageSource.getComment() != null) {
			DescriptionType description = factory.createDescriptionType();
			description.setTextContent(pageSource.getComment());
			navigationRule.getDescription().clear();
			navigationRule.getDescription().add(description);
		}
		// set the navigation rule's icon
		if (pageSource.getLargeicon() != null
				|| pageSource.getSmallicon() != null) {
			IconType icon = factory.createIconType();
			if (pageSource.getLargeicon() != null) {
				LargeIconType largeicon = factory.createLargeIconType();
				largeicon.setTextContent(pageSource.getLargeicon());
				icon.setLargeIcon(largeicon);
			}

			if (pageSource.getSmallicon() != null) {
				SmallIconType smallicon = factory.createSmallIconType();
				smallicon.setTextContent(pageSource.getSmallicon());
				icon.setSmallIcon(smallicon);
			}
			navigationRule.getIcon().clear();
			navigationRule.getIcon().add(icon);
		}
		if (pageSource.getName() != null) {
			DisplayNameType displayName = factory.createDisplayNameType();
			displayName.setTextContent(pageSource.getName());
			navigationRule.getDisplayName().clear();
			navigationRule.getDisplayName().add(displayName);
		}
	}

	/**
	 * TODO: If we cache the case's properties in a link, then we can restore
	 * them.
	 * 
	 * @param navigationCase
	 * @param link
	 */
    // TODO: not used, dead?
//	private void updateFacesCase(NavigationCaseType navigationCase,
//			PageflowLink link) {
//		FacesConfigFactory factory = FacesConfigFactory.eINSTANCE;
//		if (link.getComment() != null) {
//			DescriptionType description = factory.createDescriptionType();
//			description.setTextContent(link.getComment());
//			navigationCase.getDescription().clear();
//			navigationCase.getDescription().add(description);
//		}
//		// set the navigation rule's icon
//		if (link.getLargeicon() != null || link.getSmallicon() != null) {
//			IconType icon = factory.createIconType();
//			if (link.getLargeicon() != null) {
//				LargeIconType largeicon = factory.createLargeIconType();
//				largeicon.setTextContent(link.getLargeicon());
//				icon.setLargeIcon(largeicon);
//			}
//
//			if (link.getSmallicon() != null) {
//				SmallIconType smallicon = factory.createSmallIconType();
//				smallicon.setTextContent(link.getSmallicon());
//				icon.setSmallIcon(smallicon);
//			}
//			navigationCase.getIcon().clear();
//			navigationCase.getIcon().add(icon);
//		}
//		if (link.getFromaction() != null) {
//			FromActionType fromAction = factory.createFromActionType();
//			fromAction.setTextContent(link.getFromaction());
//			navigationCase.setFromAction(fromAction);
//		}
//		if (link.getOutcome() != null) {
//			FromOutcomeType fromOutcome = factory.createFromOutcomeType();
//			fromOutcome.setTextContent(link.getOutcome());
//			navigationCase.setFromOutcome(fromOutcome);
//		}
//	}

	private void createFacesCase(PageflowLink link, PageflowPage source,
			PageflowPage target_) {
		NavigationRuleType rule = FacesConfigFactory.eINSTANCE
				.createNavigationRuleType();
		FromViewIdType from = FacesConfigFactory.eINSTANCE
				.createFromViewIdType();
		from.setTextContent((source).getPath());
		rule.setFromViewId(from);
		NavigationCaseType navCase = FacesConfigFactory.eINSTANCE
				.createNavigationCaseType();
		ToViewIdType toView = FacesConfigFactory.eINSTANCE.createToViewIdType();
		toView.setTextContent((target_).getPath());
		navCase.setToViewId(toView);
		rule.getNavigationCase().add(navCase);
		facesConfig.getNavigationRule().add(rule);
		updateFacesRule(rule, source);
		source.getFCElements().add(from);
		target_.getFCElements().add(toView);
		link.getFCElements().add(navCase);
		mapCases2Links.put(navCase, link);
	}

	private void removePageflowPage(PageflowPage source) {
		Assert.isTrue(source.getOutlinks().size() == 0
				&& source.getInlinks().size() == 0);
		pageflow.getNodes().remove(source);
	}

	void removeCase(NavigationCaseType navCase) {
		NavigationRuleType rule = (NavigationRuleType) navCase.eContainer();
		(rule).getNavigationCase().remove(navCase);
		if (rule.getNavigationCase().size() == 0) {
			facesConfig.getNavigationRule().remove(rule);
		}
	}

	/**
	 * Remove a link in pageflow model.
	 * 
	 * @param pLink
	 */
	private void removeLink(PageflowLink pLink) {
		// Link
		PageflowPage source = (PageflowPage) pLink.getSource();
		PageflowPage target_ = (PageflowPage) pLink.getTarget();
		pLink.getPageflow().getLinks().remove(pLink);
		source.getOutlinks().remove(pLink);
		target_.getInlinks().remove(pLink);
		// Navigation case
		pLink.getFCElements().clear();
		cleanPage(source);
		cleanPage(target_);
	}

	/**
	 * Remove a link in pageflow model.
	 * 
	 * @param pLink
	 */
	void changePFLinkStart(PageflowLink pLink, String newValue) {
		PageflowPage newPage = null;
		if ((newPage = getValidPFPageInCache(newValue)) != null) {
			if (newValue.equals(((PageflowPage) pLink.getSource()).getPath())) {
				return;
			}
		} else if ((newPage = TransformUtil.findPage(newValue, pageflow)) == null) {
			return;
		}

		// remove old case
		NavigationCaseType caseType = (NavigationCaseType) pLink
				.getFCElements().getData().get(0);
		//NavigationRuleType rule = (NavigationRuleType) caseType.eContainer();
		removeCase(caseType);

		// create new rule / case
		NavigationCaseType newCase = FacesConfigFactory.eINSTANCE
				.createNavigationCaseType();
		ToViewIdType toView = FacesConfigFactory.eINSTANCE.createToViewIdType();
		toView.setTextContent(caseType.getToViewId().getTextContent());
		newCase.setToViewId(toView);

		NavigationRuleType newRule = FacesConfigFactory.eINSTANCE
				.createNavigationRuleType();
		FromViewIdType fromView = FacesConfigFactory.eINSTANCE
				.createFromViewIdType();
		fromView.setTextContent(newValue);
		newRule.setFromViewId(fromView);
		newRule.getNavigationCase().add(newCase);
		facesConfig.getNavigationRule().add(newRule);

		// update
		// updateNode(rule, newRule);
		updateNode(caseType, newCase);

		pLink.getFCElements().clear();
		pLink.getFCElements().add(newCase);
		pLink.setSource(newPage);

		updatePageflowElements(pageflow, newCase);
	}

	private void updateNode(EObject old, EObject newOne) {
		if (old instanceof NavigationRuleType) {
			((NavigationRuleType) newOne).getDescription().clear();
			((NavigationRuleType) newOne).getDescription().addAll(
					((NavigationRuleType) old).getDescription());
			((NavigationRuleType) newOne).getDisplayName().clear();
			((NavigationRuleType) newOne).getDisplayName().addAll(
					((NavigationRuleType) old).getDisplayName());
			((NavigationRuleType) newOne).getDescription().clear();
			((NavigationRuleType) newOne).getIcon().clear();
			((NavigationRuleType) newOne).getIcon().addAll(
					((NavigationRuleType) old).getIcon());
		} else if (old instanceof NavigationCaseType) {
			((NavigationCaseType) newOne).getDescription().clear();
			((NavigationCaseType) newOne).getDescription().addAll(
					((NavigationCaseType) old).getDescription());
			((NavigationCaseType) newOne).getDisplayName().clear();
			((NavigationCaseType) newOne).getDisplayName().addAll(
					((NavigationCaseType) old).getDisplayName());
			((NavigationCaseType) newOne).getDescription().clear();
			((NavigationCaseType) newOne).getIcon().clear();
			((NavigationCaseType) newOne).getIcon().addAll(
					((NavigationCaseType) old).getIcon());
			((NavigationCaseType) newOne)
					.setFromAction(((NavigationCaseType) old).getFromAction());
			((NavigationCaseType) newOne)
					.setFromOutcome(((NavigationCaseType) old).getFromOutcome());
		}
	}

	void changePFLinkEnd(PageflowLink pLink, String newValue) {
		PageflowPage newPage = null;
		if ((newPage = getValidPFPageInCache(newValue)) != null) {
			if (newValue.equals(((PageflowPage) pLink.getSource()).getPath())) {
				return;
			}
		} else if ((newPage = TransformUtil.findPage(newValue, pageflow)) == null) {
			return;
		}

		// remove old case
		NavigationCaseType caseType = (NavigationCaseType) pLink
				.getFCElements().getData().get(0);
		ToViewIdType toView = caseType.getToViewId(); // FacesConfigFactory.eINSTANCE.createToViewIdType();
		if (toView == null) {
			toView = FacesConfigFactory.eINSTANCE.createToViewIdType();
		}
		toView.setTextContent(newValue);
		caseType.setToViewId(toView);

		pLink.setTarget(newPage);

		updatePageflowElements(pageflow, caseType);
	}

	void removeLink(NavigationCaseType caseType) {
		PageflowLink link = (PageflowLink) mapCases2Links.get(caseType);
		if (link != null) {
			removeLink(link);
		}
	}

	void addLink(PageflowPage source, PageflowPage target_, PageflowLink value) {
		if (source != null && target_ != null && value != null) {
			createFacesCase(value, source, target_);
		}
	}

	private void cleanPage(PageflowPage source) {
		if (source.getInlinks().size() == 0 && source.getOutlinks().size() == 0) {
			removePageflowPage(source);
		}
		source.update();
	}

	void refreshPFAdapter(EObject object) {
		TreeIterator content = object.eAllContents();
		while (content.hasNext()) {
			Object next = content.next();
			adapt((EObject) next);
		}
		adapt(object);
	}

	void refreshFCAdapter(EObject object) {
		List rules = facesConfig.getNavigationRule();
		if (rules != null) {
			for (int i = 0; i < rules.size(); i++) {
				NavigationRuleType rule = (NavigationRuleType) rules.get(i);
				adapt(rule);
				TreeIterator children = rule.eAllContents();
				while (children.hasNext()) {
					adapt((EObject) children.next());
				}
			}
		}
		adapt(facesConfig);
	}

	/**
	 * @param facesConfig
	 */
	public void setFacesConfig(FacesConfigType facesConfig) {
		this.facesConfig = facesConfig;
		refreshFCAdapter(facesConfig);
	}

	/**
	 * @param pageflow
	 */
	public void setPageflow(Pageflow pageflow) {
		this.pageflow = pageflow;
		pageflow.eAdapters().add(this);
		refreshPFAdapter(pageflow);
	}

	/**
	 * Install compatible synchronization adapter for particular object.
	 * 
	 * @param object
	 */
	public void adapt(EObject object) {
		if (object != null && !isAdapted(object)) {
			if (object instanceof PageflowElement) {
				object.eAdapters().add(new PF2FCSynchronizer(this));
			} else {
				object.eAdapters().add(new FC2PFSynchronizer(this));
			}
		}
	}

	/**
	 * Remove the synchronization adapter.
	 * 
	 * @param object
	 */
	public void unAdapt(EObject object) {
		Iterator adapters = object.eAdapters().iterator();
		while (adapters.hasNext()) {
			Object adapter = adapters.next();
			if (adapter instanceof FC2PFSynchronizer
					|| adapter instanceof PF2FCSynchronizer) {
				adapters.remove();
			}
		}
	}

	/**
	 * @param object
	 * @return true if this transformer adapts object
	 */
	public boolean isAdapted(EObject object) {
		if (object != null) {
			Iterator adapters = object.eAdapters().iterator();
			while (adapters.hasNext()) {
				Object adapter = adapters.next();
				if (adapter instanceof FC2PFSynchronizer
						|| adapter instanceof PF2FCSynchronizer) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * clear the internal maps
	 */
	public void clearCaches() {
		mapPaths2PF.clear();
		mapCases2Links.clear();
	}

	/**
	 * dispose of this object.
	 */
	public void dispose() {
		clearCaches();
		Pageflow pageFlow = getPageflow();
		
		if (pageFlow != null)
		{
		    pageFlow.dispose();
		}
	}

	public Notifier getTarget() {
		return null;
	}

	public boolean isAdapterForType(Object type) {
		return false;
	}

	public void setTarget(Notifier newTarget) {
	    // do nothing
	}

	/**
	 * @param caseType
	 * @return the from view id in caseType
	 */
	public static FromViewIdType getSource(NavigationCaseType caseType) {
		if (caseType.eContainer() instanceof NavigationRuleType) {
			NavigationRuleType rule = (NavigationRuleType) caseType
					.eContainer();
			return rule.getFromViewId();
		}
		return null;
	}

	private PageflowPage getOrCreateStartPage(NavigationCaseType navCase) {// FromViewIdType
		PageflowPage startPageflowNode = null;
		String path = "*"; //$NON-NLS-1$
		NavigationRuleType rule = (NavigationRuleType) navCase.eContainer();
		FromViewIdType source = getSource(navCase);
		if (source != null) {
			path = source.getTextContent();
		}
		if (getValidPFPageInCache(path) == null) {
			startPageflowNode = TransformUtil.findPage(path, pageflow);

			if (startPageflowNode == null) {
				// not exist or is "*"
				if (DEBUG)
					System.out.println("Create new start page"); //$NON-NLS-1$
				startPageflowNode = createPFPage(path);
				pageflowChanged = true;
			}
			mapPaths2PF.put(path, startPageflowNode);
			PageflowTransform.getInstance().updatePageflowSourcePage(
					startPageflowNode, rule);
		} else {
			startPageflowNode = (PageflowPage) mapPaths2PF.get(path);
		}
		if (source != null) {
			ReferenceElement element = new PageReferenceElement(
					startPageflowNode);
			element.add(source);
			startPageflowNode
					.setReferenceLink(element.resolveReferenceString());
			startPageflowNode.getFCElements().add(source);
		}
		return startPageflowNode;
	}

	/**
	 * Search for an existing pageflow page matching to navigation case's
	 * target, if there is no such page existing, create one.
	 * 
	 * @param navCase
	 * @return
	 */
	private PageflowPage getOrCreateEndPage(NavigationCaseType navCase) {
		PageflowPage endPageflowNode = null;
		ToViewIdType target_ = navCase.getToViewId();
		if (target_ != null) {
			String path = target_.getTextContent();
			if (getValidPFPageInCache(path) == null) {
				endPageflowNode = TransformUtil.findPage(path, pageflow);
				if (endPageflowNode == null) {
					endPageflowNode = createPFPage(path);
					if (DEBUG)
						System.out.println("Create new end page"); //$NON-NLS-1$
					pageflowChanged = true;
				}
				mapPaths2PF.put(path, endPageflowNode);
				PageflowTransform.getInstance().updatePageflowTargetPage(
						endPageflowNode, navCase);
			} else {
				endPageflowNode = (PageflowPage) mapPaths2PF.get(path);
			}
			if (target_ != null) {
				ReferenceElement element = new PageReferenceElement(
						endPageflowNode);
				element.add(target_);
				endPageflowNode.setReferenceLink(element
						.resolveReferenceString());
				endPageflowNode.getFCElements().add(target_);
			}
		}
		return endPageflowNode;
	}

	/**
	 * Return a valid cached pageflow node.
	 * 
	 * @param key
	 * @return
	 */
	private PageflowPage getValidPFPageInCache(Object key) {
		EObject element = (EObject) mapPaths2PF.get(key);
		if (!TransformUtil.isValidPageflowElement(element)
				|| !(element instanceof PageflowPage)
				|| !((PageflowPage) element).getPath().equals(key)) {
			mapPaths2PF.remove(key);
			element = null;
		}
		return (PageflowPage) element;
	}

	/**
	 * Return a valid cached pageflow link.
	 * 
	 * @param caseType
	 * @return
	 */
	private PageflowLink getValidPFLinkInCache(EObject caseType) {
		PageflowLink link = (PageflowLink) mapCases2Links.get(caseType);
		if (!TransformUtil.isValidLink(link)) {
			mapCases2Links.remove(caseType);
			link = null;
		}
		return link;

	}

	/**
	 * Update pageflow model elements against faces-config navigation case.
	 * @param pageflow_ 
	 * @param caseFC 
	 * @return true if the pageflow was changed
	 */
	public boolean updatePageflowElements(Pageflow pageflow_,
			NavigationCaseType caseFC) {
		this.pageflowChanged = false;
		this.pageflow = pageflow_;
		ToViewIdType target_ = caseFC.getToViewId();
		if (target_ == null) {
			return false;
		}

		PageflowPage start = null, end = null;
		// start page
		start = getOrCreateStartPage(caseFC);
		String action = null;
		// action
		if (caseFC.getFromAction() != null) {
			action = caseFC.getFromAction().getTextContent();
		}
		// from outcome
		String fromOutCome = null;
		if (caseFC.getFromOutcome() != null) {
			fromOutCome = caseFC.getFromOutcome().getTextContent();
		}
		// end page
		end = getOrCreateEndPage(caseFC);
		// link
		// Is there a link in pageflow model?
		PageflowLink link = null;
		if ((link = findUnmappedLink(start, end, caseFC)) == null) {
			if (end != null) {
				if (DEBUG)
					System.out.println("Create new link"); //$NON-NLS-1$
				link = createPFLink(start, end, action, fromOutCome);
				pageflowChanged = true;
			}
		}
		if (link != null) {
			link.getFCElements().clear();
			link.getFCElements().add(caseFC);
			mapCases2Links.put(caseFC, link);
		}
		adapt(start);
		adapt(end);
		adapt(caseFC);
		adapt(link);
		return pageflowChanged;
	}

	private boolean cleanPageflowNavigationRule(Pageflow pageflow_) {
		boolean dirty = false;
		List links = pageflow_.getLinks();
		Iterator linksIterator = links.iterator();
		while (linksIterator.hasNext()) {
			PageflowLink link = (PageflowLink) linksIterator.next();
			if (link.getFCElements().isEmpty()) {
				linksIterator.remove();
				if (link.getSource() != null) {
					link.getSource().getOutlinks().remove(link);
				}
				if (link.getTarget() != null) {
					link.getTarget().getInlinks().remove(link);
				}
				dirty = true;
			}
		}
		return dirty;
	}

	/**
	 * merge the two navigation rules list between pageflow and face-config
	 * file. merge rule: 1. if the from-view-id, from-action, and from-outcome
	 * are same, they are the same navigation case, then the navigation case in
	 * face-config file should be updated by one in the pageflow. 2. otherwise
	 * the new navigation case should be created.
	 * 
	 * FIXME: Not merge, only update page flow from faces-config.
	 * 
	 * @param rulesFC -
	 *            navigation rules in faces-config.
	 * @param navigationRulesInPageflow -
	 *            navigation rules in pageflow model.
	 * 
	 * @return boolean - whether add a new rule or not.
	 */
	private boolean updateNavigationRulesInPageflowFromFacesConfig(List rulesFC) {
		boolean isNew = false;
		// if the faces-config file is empty, the links should be removed.
		if (rulesFC == null || rulesFC.isEmpty()) {
			for (Iterator iterLink = pageflow.getLinks().iterator(); iterLink
					.hasNext();) {
				PageflowLink link = (PageflowLink) iterLink.next();
				link.getSource().getOutlinks().remove(link);
				link.getTarget().getInlinks().remove(link);
			}
			pageflow.getLinks().clear();
		} else {
			// Rule - Cases
			for (Iterator iterRulesFC = rulesFC.iterator(); iterRulesFC
					.hasNext();) {
				NavigationRuleType ruleFC = (NavigationRuleType) iterRulesFC
						.next();

				List casesFC = ruleFC.getNavigationCase();
				for (Iterator iterCasesFC = casesFC.iterator(); iterCasesFC
						.hasNext();) {
					NavigationCaseType navigationCaseFC = (NavigationCaseType) iterCasesFC
							.next();
					isNew |= updatePageflowElements(pageflow, navigationCaseFC);
				}
			}
		}
		isNew |= cleanPageflowNavigationRule(pageflow);
		return isNew;
	}

	/**
	 * Find a pageflow link that is not linked to a faces-config element. Since
	 * user might edit faces-config file with other editor, so the path is not
	 * always valid, here we still try to match link and navigation case. TODO:
	 * should we always resolve mapping from referenceLink on PageflowElement?
	 */
	private PageflowLink findUnmappedLink(PageflowPage start, PageflowPage end,
			NavigationCaseType caseFC) {
		List links = start.getOutlinks();
		for (int i = 0, n = links.size(); i < n; i++) {
			PageflowLink link = (PageflowLink) links.get(i);
			if (link.getSource() == start && link.getTarget() == end) {
				link.update();
				if (link.getFCElements().isEmpty()
						|| link.getFCElements().getData().get(0) == caseFC) {
					return link;
				}
			}
		}
		return null;
	}

	/**
	 * create a new PFLink object according to fromOutcome attribute
	 * 
	 * @param fromOutcome -
	 *            PFLink's fromOutcome attribute
	 * @return - new PFLink object
	 */
	public PageflowLink createPFLink(String fromOutcome) {
		PageflowLink link = null;
		link = PageflowModelManager.getFactory().createPFLink();
		if (fromOutcome != null && fromOutcome.length() > 0) {
			link.setOutcome(fromOutcome.trim());
		}
		pageflow.getLinks().add(link);
		return link;
	}

	/**
	 * create a new PFLink object according to fromOutcome attribute
	 * @param start 
	 * @param target_ 
	 * @param action 
	 * 
	 * @param fromOutcome -
	 *            PFLink's fromOutcome attribute
	 * @return - new PFLink object
	 */
	public PageflowLink createPFLink(PageflowNode start, PageflowNode target_,
			String action, String fromOutcome) {
		Assert.isTrue(start != null && target_ != null);
		PageflowLink link = null;
		link = createPFLink(fromOutcome);
		link.setFromaction(action);
		link.setSource(start);
		link.setTarget(target_);
		start.getOutlinks().add(link);
		target_.getInlinks().add(link);
		return link;
	}

	/**
	 * Create a new PFPage according to from-view-id
	 * 
	 * @param fromViewID -
	 *            page's from-view-id
	 * @return the page flow page
	 */
	public PageflowPage createPFPage(String fromViewID) {
		PageflowPage page = PageflowFactory.eINSTANCE.createPFPage();
		if (fromViewID != null && fromViewID.length() > 0) {
			page.setPath(fromViewID.trim());
			page.setName(WebrootUtil.getPageNameFromWebPath(fromViewID.trim()));
		}
		this.pageflow.getNodes().add(page);
		return page;
	}

	/**
	 * update pageflow model according to the face-config model
	 * 
	 * @author sfshi
	 * @return true if new rules were added
	 */
	public boolean updatePageflowModelFromEMF() {
		if (pageflow != null && facesConfig != null) {
			List navigationRulesInFacesconfig = facesConfig.getNavigationRule();
			clearCaches();
			// if add new one, we can relayout the current pageflow.
			return updateNavigationRulesInPageflowFromFacesConfig(navigationRulesInFacesconfig);
		}
		return false;
	}

	void refreshLink(NavigationCaseType caseType) {
		PageflowLink link = getValidPFLinkInCache(caseType);
		if (link != null) {
			removeLink(link);
		}
		// update pageflow
		if (TransformUtil.isValidFacesConfigElement(caseType)) {
			updatePageflowElements(pageflow, caseType);
		}
	}

	public void notifyChanged(Notification msg) {
		int type = msg.getEventType();
		switch (type) {
		case MY_NOTIFICATION_TYPE:
			setNeedBatchOperations(true);
			break;
		case MY_NOTIFICATION_TYPE1:
			setNeedBatchOperations(false);
		}
	}

	/**
	 * @return true if is listening to notifications and not
	 * currently in an event
	 */
	public boolean isListenToNotify() {
		return listenToNotify && !isInEvent;
	}

	/**
	 * @return true if in event
	 */
//	public boolean isInEvent() {
//		return isInEvent;
//	}

	/**
	 * @param isInEvent
	 */
	public void setInEvent(boolean isInEvent) {
		this.isInEvent = isInEvent;
	}

	/**
	 * @return the faces config model
	 */
	public FacesConfigType getFacesConfig() {
		return facesConfig;
	}

	/**
	 * @return the root page flow
	 */
	public Pageflow getPageflow() {
		return pageflow;
	}

	/**
	 * @param value
	 * @return a new fromViewId with the text content set to value
	 */
	public static FromViewIdType createRLFromViewID(String value) {
		FromViewIdType fromView = FacesConfigFactory.eINSTANCE
				.createFromViewIdType();
		fromView.setTextContent(value);
		return fromView;
	}

	/**
	 * @param value
	 * @return a new to view with the text content set to value
	 */
	public static ToViewIdType createFCToViewID(String value) {
		ToViewIdType toView = FacesConfigFactory.eINSTANCE.createToViewIdType();
		toView.setTextContent(value);
		return toView;
	}
}
