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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.uma.ExtendReferenceMap;
import org.eclipse.epf.library.edit.uma.MethodElementExt;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.util.UserDefinedTypeMeta;
import org.w3c.dom.Element;

public class PracticePropUtil extends MethodElementPropUtil {
	
	public static final String Practice_UtdData = "Practice_utdData";		//$NON-NLS-1$		
	
	private static PracticePropUtil practicePropUtil = new PracticePropUtil();
	public static PracticePropUtil getPracticePropUtil() {
		return practicePropUtil;
	}
	
	public static PracticePropUtil getPracticePropUtil(IActionManager actionManager) {
		return new PracticePropUtil(actionManager);
	}
	
	protected PracticePropUtil() {		
	}
	
	protected PracticePropUtil(IActionManager actionManager) {
		super(actionManager);
	}
	
	public void storeUtdData(Practice practice, UserDefinedTypeMeta meta)  throws Exception {
		PracticeXmlEditUtil xmlEditUtil = new PracticeXmlEditUtil(practice, this);
		xmlEditUtil.storeUtdData(meta);
		MethodElementExt extendObject = getExtendObject(practice, true);
		if (extendObject != null) {
			extendObject.setUserDefinedTypeMeta(meta);
		}
	}
	
	public  UserDefinedTypeMeta getUdtMeta(Practice practice) {
		try {
			return getUtdData(practice);			
		} catch (Exception e) {
			LibraryEditPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}
	
	public  UserDefinedTypeMeta getUtdData(Practice practice)  throws Exception {
		MethodElementExt extendObject = getExtendObject(practice, true);
		if (extendObject != null && extendObject.getUserDefinedTypeMeta() instanceof UserDefinedTypeMeta) {
			UserDefinedTypeMeta meta = (UserDefinedTypeMeta) extendObject.getUserDefinedTypeMeta();
			return meta == UserDefinedTypeMeta.noneValue ? null : meta;
		}
		UserDefinedTypeMeta meta = new UserDefinedTypeMeta();
		PracticeXmlEditUtil xmlEditUtil = new PracticeXmlEditUtil(practice, this);
		xmlEditUtil.retrieveUtdData(meta);
		if (extendObject == null) {
			return meta.getId() == null ? null : meta;
		}
		if (meta.getId() == null) {
			meta = UserDefinedTypeMeta.noneValue;
		} else {
			UserDefinedTypeMeta globalMeta = LibraryEditUtil.getInstance().getUserDefineType(meta.getId());
			if (meta.same(globalMeta)) {
				meta = globalMeta;
			}
		}
		extendObject.setUserDefinedTypeMeta(meta);
		return meta == UserDefinedTypeMeta.noneValue ? null : meta;
	}
	
	public  boolean isUdtType(MethodElement element) {
		if (element instanceof Practice) {
			return getUdtMeta((Practice) element) != null;			
		}
		return false;
	}
	
	public boolean isUdtType(MethodElement element, String typeId) {
		if (typeId != null && element instanceof Practice) {
			UserDefinedTypeMeta meta = getUdtMeta((Practice) element);
			if (meta != null) {
				return typeId.equals(meta.getRteNameMap().get(
						UserDefinedTypeMeta._typeId));
			}
		}
		return false;
	}
	
	public List<MethodElement> getUdtReferencingList(Practice practice) {
		String ofeature = ExtendReferenceMap.getOppositeName(ExtendReferenceMap.UtdList);
		List<MethodElement> list = (List<MethodElement>) getReferenceValue(ofeature, practice, false);
		return list == null ? new ArrayList<MethodElement>() : list;
	}
	
	private static class PracticeXmlEditUtil extends XmlEditUtil {
		
		private Practice practice;
		
		public static final String _id = "id"; 					//$NON-NLS-1$		
		
		public PracticeXmlEditUtil(Practice practice, MethodElementPropUtil propUtil) {
			super(propUtil);
			this.practice = practice;
		}		
		
		public void storeUtdData(UserDefinedTypeMeta meta) throws Exception {
			if (practice == null) {
				return;
			}
			Map<String, String> map = meta.getRteNameMap();
			Element firstElement = createFirstElement(Practice_UtdData);
			firstElement.setAttribute(_id, meta.getId());
			for (String name : UserDefinedTypeMeta.rteNames) {
				String value = map.get(name);
				if (value != null && value.trim().length() > 0) {
					firstElement.setAttribute(name, value.trim());
				}
			}			
			storeToOwner(practice, Practice_UtdData);	
		}
		
		public void retrieveUtdData(UserDefinedTypeMeta meta) throws Exception {
			Map<String, String> map = meta.getRteNameMap();
			
			String xmlString = getPropUtil().getStringValue(practice, Practice_UtdData);
			if (xmlString == null || xmlString.trim().length() == 0) {
				return;
			}
			Element firstElement = loadDocumentAndGetFirstElement(xmlString);
			if (firstElement == null) {
				return;
			}				
			String value = firstElement.getAttribute(_id);
			if (value != null && value.length() > 0) {
				meta.setId(value);
			}
			for (String name : UserDefinedTypeMeta.rteNames) {
				value = firstElement.getAttribute(name);
				if (value != null && value.length() > 0) {
					map.put(name, value);
				}
			}
		}
		
	}

	
	
}
