//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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.tester.impl.testcommands;

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

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.tester.TesterOutputUtil;
import org.eclipse.epf.library.tester.iface.TCExeReply;
import org.eclipse.epf.library.tester.impl.TestCommandImpl;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * A test command class
 * 
 * @author Weiping Lu
 * @since 1.0
 * 
 */
public class TCEditContentElement extends TestCommandImpl {					
	
	static class TagData {
		public Map attMap = new HashMap();
		public Map refMap = new HashMap();
	}
	
	private EClass eclass;
	private TagData tagData;
	private Map refValueMap = new HashMap();
	private static Map eclassDataMap = new HashMap(); 
	
	public TCEditContentElement(EClass ecls) {
		eclass = ecls;
		TagData tagData = (TagData) eclassDataMap.get(eclass);
		if (tagData != null) {
			return;
		}		
		tagData = new TagData();
		eclassDataMap.put(eclass, tagData);
		
		addToEclassDataMap(eclass.getEAllAttributes(), tagData.attMap);
		addToEclassDataMap(eclass.getEAllReferences(), tagData.refMap);

	}
	
	private void addToEclassDataMap(List features, Map feaMap) {		
		for (int i=0; i<features.size(); i++) {
			EStructuralFeature feature = (EReference) features.get(i);			
			feaMap.put(feature.getName(), feature);
		}
	}
	
	public void parse(Element element) {
		setAttribute(AT_Type, element.getAttribute(AT_Type));
		setAttribute(AT_Path, element.getAttribute(AT_Path));

		for (Iterator it = tagData.attMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			String at_tag = (String) entry.getKey();
			setAttribute(at_tag, element.getAttribute(at_tag));
		}
		
		parseChildren(element, tagData.refMap);
	}
	
	protected void parseChildren(Element element, Map refMap) {
		for (Iterator it = refMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			String vt_tag = (String) entry.getKey();
			setAttribute(vt_tag, element.getAttribute(vt_tag));
			
			NodeList cnodes = element.getElementsByTagName(vt_tag);
			if (cnodes == null || cnodes.getLength() == 0) {
				continue;
			}
			Element cElement = (Element) cnodes.item(0);
			cnodes = cElement.getElementsByTagName(VT_Value);	
			if (cnodes == null || cnodes.getLength() == 0) {
				return;
			}
			List valueList = new ArrayList();
			for (int i=0; i<cnodes.getLength(); i++) {
				Element vElem = (Element) cnodes.item(i);
				String value = vElem.getFirstChild().getNodeValue();
				valueList.add(value);
			}
			refValueMap.put(vt_tag, valueList);
		}
	}
	
	public TCExeReply execute() {
		MethodLibrary currLib = getOwner().getCurrentBaseLib();
		
		String path = getAttribute(AT_Path);
		ContentElement ce = (ContentElement) TesterOutputUtil.getMethodElement(currLib, path);
		ContentDescription cd = ce.getPresentation();
			//System.out.println("wpl> cd: " + cd);
			//System.out.println("");	
		return null;
	}
	

	
}


