package org.eclipse.epf.library.edit.meta.internal;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.library.edit.meta.IMetaDef;
import org.eclipse.epf.library.edit.meta.TypeDefException;
import org.eclipse.epf.uma.util.ExtendedAttribute;
import org.eclipse.epf.uma.util.ExtendedFeature;
import org.eclipse.epf.uma.util.ExtendedReference;
import org.eclipse.epf.uma.util.ExtendedSection;
import org.eclipse.epf.uma.util.ExtendedTable;
import org.eclipse.epf.uma.util.ModifiedTypeMeta;
import org.w3c.dom.Element;

public class ModifiedTypeMetaImpl extends MetaElementImpl implements ModifiedTypeMeta {
		
	private List<ExtendedReference> references;
	private List<ExtendedAttribute> rtes;
	private List<ExtendedAttribute> attributes;

	private List<ExtendedSection> sections;
	private List<ExtendedSection> referenceSections;
	private List<ExtendedSection> rteSections;
	private List<ExtendedSection> attributeSections;
	private List<ExtendedTable> tables;
	
	private List<String> linkTypes;

	public ModifiedTypeMetaImpl() {
		super(null);
	}
	
	public List<ExtendedReference> getReferences() {
		if (references == null) {
			references = new ArrayList<ExtendedReference>();
		}
		return references;
	}
	
	@Deprecated
	public List<ExtendedAttribute> getRtes() {
		if (rtes == null) {
			rtes = new ArrayList<ExtendedAttribute>();
		}
		return rtes;
	}
	
	public List<ExtendedAttribute> getAttributes() {
		if (attributes == null) {
			attributes = new ArrayList<ExtendedAttribute>();
		}
		return attributes;
	}
	
	@Override
	public boolean isSuppressed() {
		return false;
	}
	
	public List<ExtendedSection> getSections() {
		if (sections == null) {
			sections = new ArrayList<ExtendedSection>();
		}
		return sections;
	}
	
	public List<ExtendedSection> getReferenceSections() {
		if (referenceSections == null) {
			referenceSections = new ArrayList<ExtendedSection>();
		}
		return referenceSections;
	}
	
	@Deprecated
	public List<ExtendedSection> getRteSections() {
		if (rteSections == null) {
			rteSections = new ArrayList<ExtendedSection>();
		}
		return rteSections;
	}
	
	public List<ExtendedSection> getAttributeSections() {
		if (attributeSections == null) {
			attributeSections = new ArrayList<ExtendedSection>();
		}
		return attributeSections;
	}
	
	public List<ExtendedTable> getTables() {
		if (tables == null) {
			tables = new ArrayList<ExtendedTable>();
		}
		return tables;
	}
		
	public List<String> getLinkTypes() {
		if (linkTypes == null) {
			linkTypes = new ArrayList<String>();
		}
		return linkTypes;
	}
	
	public void parseElement(Element element)	throws TypeDefException {		
		super.parseElement(element);
				
		getSections().clear();
		getLinkTypes().clear();
		
		List<Element> linkTypeElements = XMLUtil.getChildElementsByTagName(element, IMetaDef.linkType);
		if (linkTypeElements != null) {
			for (Element linkTypeElement : linkTypeElements) {
				String linkType = linkTypeElement.getAttribute(IMetaDef.ID);
				getLinkTypes().add(linkType);
			}
		}
		
		List<Element> sectionElements = XMLUtil.getChildElementsByTagName(element, IMetaDef.SECTION);
		if (sectionElements != null) {
			for (Element sElement : sectionElements) {
				ExtendedSectionImpl ses = new ExtendedSectionImpl(this);
				ses.parseElement(sElement);				
				getSections().add(ses);
			}
		}
		init();
	}
	
	@Override
	public boolean processInheritance() {
		if (! super.processInheritance()) {
			return false;
		}
		
		if (getSuperMeta() == null) {
			int sz = getSections().size();
			sections = (List<ExtendedSection>) processSuppress(this.getSections());
			if (sz != sections.size()) {
				init();
			}
			return true;
		} 
		
		if (getSuperMeta() instanceof ModifiedTypeMetaImpl){
			ModifiedTypeMetaImpl sMeta = (ModifiedTypeMetaImpl) getSuperMeta();
			sMeta.processInheritance();			
			sections = (List<ExtendedSection>) processInherentList(this.getSections(), sMeta.getSections());
			for (ExtendedSection section : getSections()) {
				section.processInheritance();
			}
			init();
			return true;
		}
		
		return true;
	}

	private void init() {
		getReferences().clear();
		getRtes().clear();
		getAttributes().clear();
		getReferenceSections().clear();
		getRteSections().clear();
		getAttributeSections().clear();
		getTables().clear();

		for (ExtendedSection section : getSections()) {
			if (IMetaDef.REFERENCE.equals(section.getType())) {
				getReferenceSections().add(section);
				getReferences().addAll(section.getReferences());
				getTables().addAll(section.getTables());

			} else if (IMetaDef.RTE.equals(section.getType())) {
				getRteSections().add(section);
				getRtes().addAll(section.getRtes());
				
			} else if (IMetaDef.ATTRIBUTE.equals(section.getType())) {
				getAttributeSections().add(section);
				getAttributes().addAll(section.getAttributes());
			}
		}
	}
	
	public boolean processLink(ModifiedTypeMeta linkedMeta) {
		if (linkedMeta == null) {
			return false;
		}
		getSections().addAll(linkedMeta.getSections());
		getReferences().addAll(linkedMeta.getReferences());
		getRtes().addAll(linkedMeta.getRtes());
		getAttributes().addAll(linkedMeta.getAttributes());
		getReferenceSections().addAll(linkedMeta.getReferenceSections());;
		getRteSections().addAll(linkedMeta.getRteSections());
		getAttributeSections().addAll(linkedMeta.getAttributeSections());
		if (extendedFeatures == null) {
			extendedFeatures = new HashSet<ExtendedFeature>();
		}
		extendedFeatures.addAll(linkedMeta.getReferences());
		extendedFeatures.addAll(linkedMeta.getRtes());
		extendedFeatures.addAll(linkedMeta.getAttributes());
		return true;
	}
	
	private Set<ExtendedFeature> extendedFeatures;
	public boolean isLinkedFeature(ExtendedFeature feature) {
		return extendedFeatures == null ? false : extendedFeatures.contains(feature);
	}
	
	@Override
	protected void getDebugStringImpl(StringBuffer sb, String indent) {
		super.getDebugStringImpl(sb, indent);
		sb.append(indent + "sections: " + sections.size() + "\n");
		for (int i = 0; i < sections.size(); i++) {
			ExtendedSection meta = sections.get(i);
			sb.append(meta.getDebugString(i, indent + indent));
		}
		sb.append(indent + "linkTypes: " + linkTypes.size() + "\n");
		for (int i = 0; i < linkTypes.size(); i++) {
			sb.append(indent + indent + linkTypes.get(i) + "\n");
		}		
		sb.append("\n");		
	}
	
}
