package org.eclipse.epf.library.edit.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.MethodElementSetPropertyCommand;
import org.eclipse.epf.library.edit.uma.ExtendReferenceMap;
import org.eclipse.epf.library.edit.uma.MethodElementExt;
import org.eclipse.epf.library.edit.uma.MethodElementExt.WorkProductStateExt;
import org.eclipse.epf.uma.Constraint;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject.ExtendObject;
import org.eclipse.epf.uma.util.UmaUtil;
import org.w3c.dom.Element;

public class MethodElementPropUtil {
	
	public static final String infoSeperator = "/"; 							//$NON-NLS-1$
	
	public static final String CONSTRAINT_WPStates = "constraint_wpStates";		//$NON-NLS-1$
	public static final String Package_supporting = "pakage_supporting";		//$NON-NLS-1$
	public static final String Me_references = "me_references";					//$NON-NLS-1$

	private static MethodElementPropUtil methodElementPropUtil = new MethodElementPropUtil();
	public static MethodElementPropUtil getMethodElementPropUtil(IActionManager actionManager) {
		return new MethodElementPropUtil(actionManager);
	}
	
	public static MethodElementPropUtil getMethodElementPropUtil() {
		return methodElementPropUtil;
	}
	
	private IActionManager actionManager;
	
	protected MethodElementPropUtil() {		
	}
	
	protected MethodElementPropUtil(IActionManager actionManager) {
		this.actionManager = actionManager;
	}	
	
	public IActionManager getActionManager() {
		return actionManager;
	}
	
	public String getStringValue(MethodElement element, String propName) {		
		MethodElementProperty prop = MethodElementPropertyHelper.getProperty(element, propName);
		if (prop == null) {
			return null;
		}
		return prop.getValue();
	}
	
	public void setStringValue(MethodElement element, String propName, String value) {	
		setProperty(element, propName, value);
	}
	
	public boolean isSupporting(ContentPackage pkg) {
		 Boolean value = getBooleanValue(pkg, Package_supporting);
		 return value == null ? false : value.booleanValue();
	}
	
	public boolean ancestorIsSupporting(ContentPackage pkg) {
		EObject parent = pkg.eContainer();
		while(parent != null) {
			if (parent instanceof MethodPlugin) { 
				return ((MethodPlugin) parent).isSupporting();
			}
			if (parent instanceof ContentPackage && isSupporting((ContentPackage) parent)) {
				return true;
			}
			parent = parent.eContainer();
		}
		return false;
	}
		
	public void updatePackageSupportingBits(Collection<? extends MethodPackage> pkgs, boolean supporting) {
		for (MethodPackage mpkg : pkgs) {
			if (! (mpkg instanceof ContentPackage)) {
				continue;
			}
			ContentPackage pkg = (ContentPackage) mpkg;
			boolean pkgIsSupporting = isSupporting(pkg);
			if (pkgIsSupporting && supporting) {
				continue;	
			}
			if (pkgIsSupporting != supporting) {
				setBooleanValue(pkg, Package_supporting, supporting);
			}
			updatePackageSupportingBits(pkg.getChildPackages(), supporting);
		}
	}
	
	public void setSupporting(ContentPackage pkg, boolean value) {
		 setBooleanValue(pkg, Package_supporting, value);
	}
	
	protected Boolean getBooleanValue(MethodElement element, String propName) {		
		MethodElementProperty prop = MethodElementPropertyHelper.getProperty(element, propName);
		if (prop == null) {
			return null;
		}
		String value = prop.getValue();
		return Boolean.parseBoolean(value);
	}
	
	protected void setBooleanValue(MethodElement element, String propName, boolean value) {	
		String strValue = value ? Boolean.TRUE.toString() : Boolean.FALSE.toString();
		setProperty(element, propName, strValue);
	}
	
	protected Integer getIntValue(MethodElement element, String propName) {		
		MethodElementProperty prop = MethodElementPropertyHelper.getProperty(element, propName);
		if (prop == null) {
			return null;			
		}
		String value = prop.getValue();
		return Integer.parseInt(value);
	}
	
	protected void setIntValue(MethodElement element, String propName, int value) {	
		String strValue = Integer.toString(value);
		setProperty(element, propName, strValue);
	}
	
	private void setProperty(MethodElement e, String propName, String propValue) {
		if (getActionManager() == null) {
			MethodElementPropertyHelper.setProperty(e, propName, propValue);
		} else {
			MethodElementSetPropertyCommand cmd = new MethodElementSetPropertyCommand(
					e, propName, propValue);
			getActionManager().execute(cmd);
		}
	}
	
	protected void removeProperty(MethodElement e, String propName) {
		MethodElementPropertyHelper.removeProperty(e, propName);
	}
	
	public MethodElementExt getExtendObject(MethodElement element, boolean create) {
		if (element == null) {
			return null;
		}
		MultiResourceEObject mobj = (MultiResourceEObject) element;		
		ExtendObject obj = mobj.getExtendObject();
		if (create && !(obj instanceof MethodElementExt)) {
			obj = createExtendObject(element);
			mobj.setExtendObject(obj);
		}
		return (MethodElementExt) obj;
	}
	
	public Map<Object, Object> getExtendedPropertyMap(MethodElement element, boolean create) {
		MethodElementExt ext = getExtendObject(element, create);
		return ext == null ? null : ext.getExtendedPropertyMap(create);
	}
	
	protected MethodElementExt createExtendObject(MethodElement element) {
		if (isWorkProductState(element)) {
			return new WorkProductStateExt((Constraint) element);
		}
		return new MethodElementExt(element);
	}
	
	public boolean isWorkProductState(MethodElement element) {
		if (!(element instanceof Constraint)) {
			return false;
		}
		Constraint c = (Constraint) element;
		return ConstraintManager.Plugin_wpState.equals(c.getName());
	}
	
	public void addReferenceInfo(MethodElement owner, MethodElement reference, String propName, String refName) {
		String oldValue = getStringValue(owner, propName);
		String newValue = reference.getGuid().concat(infoSeperator).concat(refName);

		if (oldValue != null && oldValue.length() > 0) {			
			String[] infos = oldValue.split(infoSeperator); 
			
			int sz = infos.length / 2; 		
			for (int i = 0; i < sz; i++) {
				int i1 = i*2;
				int i2 = i1 + 1;
				String iGuid = infos[i1];
				String iFeature = infos[i2];
				if (iGuid.equals(reference.getGuid()) && iFeature.equals(refName)) {
					return;
				} 
			}
			
			newValue = oldValue.concat(infoSeperator).concat(newValue);
		}				
		setStringValue(owner, propName, newValue);
	}
	
	public void removeReferenceInfo(MethodElement owner, MethodElement reference, String propName, String refName) {
		String oldValue = getStringValue(owner, propName);
		if (oldValue == null || oldValue.length() == 0) {
			return;
		}
		boolean removed = false;
		String newValue = ""; //$NON-NLS-1$

		if (oldValue != null && oldValue.length() > 0) {			
			String[] infos = oldValue.split(infoSeperator); 
			
			int sz = infos.length / 2; 		
			for (int i = 0; i < sz; i++) {
				int i1 = i*2;
				int i2 = i1 + 1;
				String iGuid = infos[i1];
				String iFeature = infos[i2];
				if (iGuid.equals(reference.getGuid()) && iFeature.equals(refName)) {
					removed = true;		
				} else {
					if (newValue.length() > 0) {
						newValue = newValue.concat(infoSeperator);
					}
					newValue = newValue.concat(iGuid.concat(infoSeperator).concat(iFeature));
				}
			}

		}
		
		if (removed) {
			setStringValue(owner, propName, newValue);
		}

	}
	
	public List<? extends MethodElement> extractElements(MethodElement propertyOwner, String propName, String refName,
			Set<? extends MethodElement> validSet) {
		List<MethodElement> elements = new ArrayList<MethodElement>();
		
		String value = getStringValue(propertyOwner, propName);
		if (value == null || value.length() == 0) {
			return elements;
		}
		
		String[] infos = value.split(infoSeperator);
		if (infos == null || infos.length == 0) {
			return elements;
		}
		
		boolean modified = false;
		String newValue = ""; //$NON-NLS-1$
		int sz = infos.length / 2; 		
		for (int i = 0; i < sz; i++) {
			int i1 = i*2;
			int i2 = i1 + 1;
			String iGuid = infos[i1];
			String iRefName = infos[i2];			
			if (refName.equals(iRefName)) {
				MethodElement element = LibraryEditUtil.getInstance().getMethodElement(iGuid);
				if (element != null && validSet.contains(element)) {
					elements.add(element);
					if (newValue.length() > 0) {
						newValue = newValue.concat(infoSeperator);
					}
					newValue = newValue.concat(iGuid.concat(infoSeperator).concat(iRefName));
				} else {
					modified = true;
				}
			} else {
				if (newValue.length() > 0) {
					newValue = newValue.concat(infoSeperator);
				}
				newValue = newValue.concat(iGuid.concat(infoSeperator).concat(iRefName));
			}
		}		
		if (modified) {
			setStringValue(propertyOwner, propName, newValue);
		}
		
		return elements;
	}

	public boolean isTransientElement(MethodElement element) {
		MethodElementExt extObj = getExtendObject(element, false);
		return extObj == null ? false : extObj.isTransientElement();
	}

	public void setTransientElement(MethodElement element,
			boolean transientElement) {
		if (!transientElement && getExtendObject(element, false) == null) {
			return;
		}
		MethodElementExt extObj = getExtendObject(element, true);
		extObj.setTransientElement(transientElement);

	}
	
	//-> For work product state objects
	public void addToAssignedToWps(WorkProduct wp, Constraint state) {
		if (! isWorkProductState(state)) {
			return;
		}
		MethodElementExt extObj = getExtendObject(state, true);
		if (! (extObj instanceof WorkProductStateExt)) {
			return;
		}
		((WorkProductStateExt) extObj).addToAssignedToWps(wp);
	}
	
	public void removeFromAssignedToWps(WorkProduct wp, Constraint state) {
		MethodElementExt extObj = getExtendObject(state, false);
		if (! (extObj instanceof WorkProductStateExt)) {
			return;
		}
		((WorkProductStateExt) extObj).removeFromAssignedToWps(wp);
	}
	
	public List<WorkProduct> getAssignedToWorkProducts(Constraint state) {
		MethodPlugin plugin = UmaUtil.getMethodPlugin(state);
		if (plugin != null) {
			MethodPluginPropUtil.getMethodPluginPropUtil().loadWpStates(plugin);
		}	
		
		MethodElementExt extObj = getExtendObject(state, false);
		if (! (extObj instanceof WorkProductStateExt)) {
			return Collections.EMPTY_LIST;
		}
		return ((WorkProductStateExt) extObj).getAssignedToWorkProducts();
	}
	//<- For work product state objects
	
	//Get elements stored as guids in the property specified by propName
	protected Set<? extends MethodElement> getElements(MethodElement owner, String propName, EClass type) {
		Set<MethodElement> elements = new HashSet<MethodElement>();
		if (owner == null) {
			return elements;
		}
		
		String value = getStringValue(owner, propName);
		String[] guids = value == null || value.trim().length() == 0 ? null : value.split(infoSeperator);

		if (guids == null || guids.length == 0) {
			return elements;
		}

		for (int i = 0; i < guids.length; i++) {
			MethodElement element = LibraryEditUtil.getInstance()
					.getMethodElement(guids[i]);
			if (element != null && (type == null || type.isSuperTypeOf(element.eClass()))) {
				elements.add(element);
			}
		}

		return elements;

	}
	
	//Store elements as guids in the property specified by propName
	protected void setElements(MethodElement owner, String propName, Set<? extends MethodElement> elements, EClass type) {
		if (owner == null) {
			return;
		}
		
		String value = "";	//$NON-NLS-1$
		List<String> guidList = new ArrayList<String>();
		if (elements != null) {
			for (MethodElement element : elements) {
				if (element != null && (type == null || type.isSuperTypeOf(element.eClass()))) {
					guidList.add(element.getGuid());
				}
			}
			Collections.sort(guidList);
			for (String guid : guidList) {
				if (value.length() != 0) {
					value += infoSeperator;
				}
				value += guid;
			}
		}
		setStringValue(owner, propName, value);
	}
	
	public XmlEditUtil newXmlEditUtil() {
		return new XmlEditUtil(this);
	}
	
	public void storeReferences(MethodElement element, boolean rollback)  throws Exception  {
		MeXmlEditUtil meXmlEditUtil = new MeXmlEditUtil(element, this);
		meXmlEditUtil.storeReferences(rollback);
	}
	
	public String getReferencesXml(MethodElement element, boolean rollback) throws Exception  {
		MeXmlEditUtil meXmlEditUtil = new MeXmlEditUtil(element, this);
		return meXmlEditUtil.getReferencesXml(rollback);
	}
	
	public boolean hasUdtList(MethodElement element) {
		return hasReferences(element);
	}
	
	public boolean hasReferences(MethodElement element) {
		String value = getStringValue(element, Me_references);
		return value != null && value.length() > 0;
	}
	
	public List<Practice> getUdtList(MethodElement element, boolean toModify) {
		List<Practice> value = (List<Practice>) getReferenceValue(ExtendReferenceMap.UtdList, element, toModify);
		if (value == null) {
			return new ArrayList<Practice>();
		}
		return value;
	}
	
	public List<MethodElement> getQReferenceListById(MethodElement element, String qualifierId, boolean toModify) {
		String referenceName = ExtendReferenceMap.getQReferenceNameById(qualifierId);
		List<MethodElement> value = (List<MethodElement>) getReferenceValue(
				referenceName, element, toModify);
		if (value == null) {
			return new ArrayList<MethodElement>();
		}
		return value;
	}	
	
	public void notifyElemetSaved(MethodElement element) {
		ExtendReferenceMap map = getCachedExtendReferenceMap(element, false);
		if (map == null) {
			return;
		}
		map.notifyOwnerElementSaved();
	}
	
	public void addOpposite(String referenceName, MethodElement thisElement, MethodElement otherElement) {
		ExtendReferenceMap map = getCachedExtendReferenceMap(thisElement, false);
		if (map == null) {
			return;
		}
		map.addOpposite(referenceName, otherElement);
	}
	
	public void removeOpposite(String referenceName, MethodElement thisElement, MethodElement otherElement) {
		ExtendReferenceMap map = getCachedExtendReferenceMap(thisElement, false);
		if (map == null) {
			return;
		}
		map.removeOpposite(referenceName, otherElement);
	}
	
	protected Object getReferenceValue(String referenceName, MethodElement element, boolean toModify) {
		MeXmlEditUtil meXmlEditUtil = new MeXmlEditUtil(element, this);
		return meXmlEditUtil.getReferenceValue(referenceName, element, toModify);
	}
	
	private ExtendReferenceMap getCachedExtendReferenceMap(MethodElement element, boolean toModify) {
		MethodElementExt extendObject = getExtendObject(element, toModify);
		if (extendObject == null) {
			return null;
		}
		return extendObject.getExtendReferenceMap(toModify);
	}
	
	public ExtendReferenceMap getExtendReferenceMap(MethodElement element, boolean toModify) {
		MeXmlEditUtil meXmlEditUtil = new MeXmlEditUtil(element, this);
		return meXmlEditUtil.getExtendReferenceMap(element, toModify);
	}
	
	private static class MeXmlEditUtil extends XmlEditUtil {
		
		private MethodElement element;
		
		public MeXmlEditUtil(MethodElement element, MethodElementPropUtil propUtil) {
			super(propUtil);
			this.element = element;
		}
		
		public void storeReferences(boolean rollback) throws Exception  {
			if (! buildReferencesElement(rollback)) {
				return;
			}			
			storeToOwner(element, Me_references);
		}
		
		public Object getReferenceValue(String referenceName, MethodElement element, boolean toModify) {
			ExtendReferenceMap map = getExtendReferenceMap(element, toModify);
			return map == null ? null : map.get(referenceName, toModify);
		}
		
		public ExtendReferenceMap getExtendReferenceMap(MethodElement element, boolean toModify) {
			ExtendReferenceMap map = getPropUtil().getCachedExtendReferenceMap(element, toModify);
			if (map != null && map.isRetrieved() || ! getPropUtil().hasUdtList(element)) {
				return map;
			}

			String xmlString = getPropUtil().getStringValue(element, Me_references);
			Element firstElement = null;
			try {
				firstElement = loadDocumentAndGetFirstElement(xmlString);
			} catch (Exception e) {
				LibraryEditPlugin.getDefault().getLogger().logError(e);
				firstElement = null;
			}
			if (firstElement != null) {
//				map = getExtendReferenceMap(element, true);	
				map = getPropUtil().getCachedExtendReferenceMap(element, true);
				map.retrieveReferencesFromElement(firstElement);
			}

			return map;
		}
		
		private boolean buildReferencesElement(boolean rollback) throws Exception {
			ExtendReferenceMap map = getExtendReferenceMap(element, false);
			if (map == null) {
				return false;
			}
			Element firstElement = createFirstElement(Me_references);
			map.storeReferencesToElement(firstElement, rollback);
			return true;
		}		
		
		public String getReferencesXml(boolean rollback) throws Exception  {
			if (! buildReferencesElement(rollback)) {
				return null;
			}			
			return XMLUtil.toXmlString(getDocument());
		}
		
	}
	
	public Object eGet(EObject eobj, EStructuralFeature feature, boolean toModify) {
		if (eobj == null) {
			return null;
		}
		if (feature == UmaUtil.MethodElement_UdtList) {
			if (! (eobj instanceof MethodElement)) {
				return null;
			}
			return getUdtList((MethodElement) eobj, toModify);
		}
		return eobj.eGet(feature);
	}
	
}
