/*******************************************************************************
 * 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 = "*";
		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");
				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");
					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");
				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;
	}
}
