//------------------------------------------------------------------------------
//Copyright (c) 2005, 2007 IBM Corporation 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:
//IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.util;

import java.util.Collection;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.util.MeList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
* @author Weiping Lu
*
* @since 1.5.1.3
*/
public class XmlEditUtil {

	private MethodElementPropUtil propUtil;
	private Document doc;
	public MethodElementPropUtil getPropUtil() {
		return propUtil;
	}

	public XmlEditUtil(MethodElementPropUtil propUtil) {
		this.propUtil = propUtil;
	}
	
	protected Document getDocument() throws Exception {
		if (doc == null) {
			doc = XMLUtil.createDocument();
		}
		return doc;
	}
	
	//Return the root element
	protected Element loadDocumentAndGetFirstElement(String xmlString) throws Exception {
		doc = XMLUtil.loadXml(xmlString);
		Node node = doc.getFirstChild();
		return node instanceof Element ? (Element) node : null;
	}
	
	protected Element createFirstElement(String name) throws Exception {
		Element element = getDocument().createElement(name);
		getDocument().appendChild(element);
		return element;
	}
	
	protected void storeToOwner(MethodElement owner, String propName)  throws Exception  {
		String value = XMLUtil.toXmlString(doc);
		propUtil.setStringValue(owner, propName, value);
	}
	
	public static String convertToGuidsString(Collection<? extends MethodElement> elements) {
		String value = ""; 	//$NON-NLS-1$
		if (elements == null || elements.isEmpty()) {
			return value;
		}
		for (MethodElement element : elements) {
			if (value.length() > 0) {
				value += MethodElementPropUtil.infoSeperator;
			}
			value += element.getGuid();
		}
		return value;
	}
	
	public static MeList convertToMethodElements(String guidsString, EClass type) {
		return convertToMethodElements(guidsString, type, uHandler);
	}
	
	public static MeList convertToMethodElements(String guidsString, EClass type, UnresolvedGuidHandler uHandler) {
		MeList list = new MeList();
		if (guidsString == null || guidsString.length() == 0) {
			return list;
		}
		String[] guids = guidsString.split(MethodElementPropUtil.infoSeperator);
		if (guids == null || guids.length == 0) {
			return list;			
		}		
		
		boolean hasUnresolved = false;
		for (String guid : guids) {
			MethodElement element = LibraryEditUtil.getInstance().getMethodElement(guid);
			if (element == null && uHandler != null) {
				element = uHandler.getElement(guid);
				if (element != null) {
					hasUnresolved = true;
				}
			}
			if (element != null) {
				if (type == null || type.isSuperTypeOf(element.eClass())) {
					list.add(element);
				}
			}
		}
		if (hasUnresolved) {
			list.setHasUnresolved(true);
		}
		return list;
	}
		
	protected Integer getIntValue(Element element, String attName) {		
		String value = element.getAttribute(attName);
		if (value == null || value.length() == 0) {
			return null;
		}
		try {
			return Integer.parseInt(value);
		} catch (Exception e) {
			return null;
		}
	}

	protected void addClonedElement(Element parent, Element elementToClone)
			throws Exception {
		if (elementToClone == null) {
			return;
		}
		Node node = XMLUtil.cloneNode(elementToClone, getDocument());
		parent.appendChild(node);
	}
	
	public static UnresolvedGuidHandler uHandler = new UnresolvedGuidHandler();
	public static class UnresolvedGuidHandler {
		
		public MethodElement getElement(String guid) {
			return null;
		}
		
		public boolean hasUnresolvedElement() {
			return false;
		}
		
	}	
	
}
