package org.eclipse.jst.pagedesigner.itemcreation.internal;

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

import javax.xml.namespace.QName;

import org.eclipse.emf.common.util.EList;
import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.MetadataFactory;
import org.eclipse.jst.jsf.common.metadata.Model;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.TraitValueHelper;
import org.eclipse.jst.jsf.common.metadata.query.IMetaDataModelContext;
import org.eclipse.jst.jsf.common.metadata.query.MetaDataQueryHelper;
import org.eclipse.jst.jsf.core.internal.tld.ITLDConstants;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
import org.eclipse.jst.pagedesigner.dom.JSFValidatorSupport;
import org.eclipse.jst.pagedesigner.dom.ValidatorSupport;
import org.eclipse.jst.pagedesigner.editors.palette.TagToolPaletteEntry;
import org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteElementTemplateHelper;
import org.eclipse.jst.pagedesigner.editors.palette.paletteinfos.PaletteInfo;
import org.eclipse.jst.pagedesigner.editors.palette.paletteinfos.PaletteInfos;
import org.eclipse.jst.pagedesigner.editors.palette.paletteinfos.PaletteInfosFactory;
import org.eclipse.jst.pagedesigner.editors.palette.paletteinfos.TagCreationAttribute;
import org.eclipse.jst.pagedesigner.editors.palette.paletteinfos.TagCreationInfo;
import org.eclipse.jst.pagedesigner.itemcreation.ITagCreator;
import org.eclipse.jst.pagedesigner.utils.BodyHelper;
import org.eclipse.jst.pagedesigner.utils.JSPUtil;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMDocType;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Element;

/**
 * {@link ITagCreator} used by the Web Page Editor palette. 
 * 
 * Uses org.eclipse.jst.jsf.common.metadata 
 */
public class DefaultTagCreator implements ITagCreator {
	
	private static final QName _qnameHTMLForm = new QName(CMDocType.HTML_DOC_TYPE, IHTMLConstants.TAG_FORM);
	
	/**
	 * The {@link TagToolPaletteEntry} being used
	 */
	protected TagToolPaletteEntry _tagItem;
	/**
	 * The {@link IMetaDataModelContext} for the tag creation
	 */
	protected IMetaDataModelContext _modelContext;
	/**
	 * The tag {@link Entity} being created
	 */
	private Entity _tagEntity;
	
	/**
	 * Construct a tag creator for the _modelContext
	 * @param _modelContext
	 */
	public DefaultTagCreator(IMetaDataModelContext modelContext) {
		this._modelContext = modelContext;
	}


	/* (non-Javadoc)
	 * @see org.eclipse.jst.pagedesigner.itemcreation.ITagCreator#createTag(org.eclipse.jst.pagedesigner.editors.palette.TagToolPaletteEntry, org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel, org.eclipse.jst.pagedesigner.dom.IDOMPosition)
	 */
	public Element createTag(TagToolPaletteEntry tagToolPaletteEntry, IDOMModel model, IDOMPosition domPosition) {
		this._tagItem = tagToolPaletteEntry;
	
		IDOMPosition position = preAdjustPositionForNecessaryContainers(model, domPosition);
		if (position == null)//throw exception?
			return null;

		String uri = getURI();
		String defaultPrefix = getDefaultPrefix();		
		String prefix = getPrefix(uri, model, defaultPrefix);
		
		Element ele =  createElement(model, prefix);
		if (ele == null)//throw exception?
			return null;
		
		applyTemplate(model, ele);
		applyRequiredAttrs(ele);
		
		addTagToContainer(position, ele);
		
		return ele;
	}

	/**
	 * @param model
	 * @param prefix
	 * @return {@link Element}
	 */
	protected Element createElement(IDOMModel model, String prefix){
		Element ele =  model.getDocument().createElement(_tagItem.getTagName());
		if (ele == null)
			return null;
		
		//ugly... fix me
		
		// XXX: we are using "startsWith("directive.")" to test whether
		// should setJSPTag, this
		// maybe is not the best way. Need check whether SSE have special
		// API for it.
		if (ITLDConstants.URI_JSP.equals(getURI())
				&& (ele.getLocalName().startsWith("directive.")
						|| "declaration".equals(ele.getLocalName())
						|| "expression".equals(ele.getLocalName()) || "scriptlet"
						.equals(ele.getLocalName()))) {
			// it is a jsp tag
			((IDOMElement) ele).setJSPTag(true);
		}
		if (prefix != null)
			ele.setPrefix(prefix);
		return ele;
	}
	/**
	 * @param position
	 * @param tagElement
	 */
	protected void addTagToContainer(IDOMPosition position, Element tagElement) {
		if (position == null || position.getContainerNode() == null) {
			return;
		}
		
		if (position.getNextSiblingNode() == null) {
			position.getContainerNode().appendChild(tagElement);
		} else {
			position.getContainerNode().insertBefore(tagElement,
					position.getNextSiblingNode());
		}
		
	}

	/**
	 * Return position for tag after all necessary containers are created.  
	 * If nnecessary containers cannot be created and do not exist for any reason, implementer should return null
	 * to signal that the tag creation should not occur.
	 * @param model
	 * @param domPosition
	 * @return position after necessary containers are created
	 */
	protected IDOMPosition preAdjustPositionForNecessaryContainers(IDOMModel model,
			IDOMPosition domPosition) {
				
		IDOMPosition position = DOMPositionHelper.splitText(domPosition);

		position = BodyHelper
				.adjustInsertPosition(getURI(), getLocalTagName(), position);
		
		position = createContainers(position);
		if (position == null) {
			// user cancelled
			return null;
		}
		
		// because the next call of getPrefix() may insert new taglib node
		// into the document, if we use the normal
		// DOMPositin which use index, maybe it will be invalidated by the
		// new taglib node. So use RefPosition here.
		return DOMPositionHelper.toDOMRefPosition(position);
	}

	/**
	 * @param position
	 * @return position after creating required containers
	 */
	protected IDOMPosition createContainers(IDOMPosition position) {
		
		//FIX ME - should be done in subclass
		if (isJSFComponent()) {
			return JSFValidatorSupport.prepareInsertJSFComponent(position, getURI(), getLocalTagName(), isHTMLFormRequired());
		}
		else if (isHTMLFormRequired()){
			boolean hasform = ValidatorSupport.checkContainer(position, _qnameHTMLForm);
			IDOMPosition newPosition = position;
			if (!hasform) {
				newPosition = ValidatorSupport
						.insertContainer(position, _qnameHTMLForm);
				if (newPosition == null) {
					newPosition = position;
				}
			}
			return newPosition;
		}
        return position;
	}

	private boolean isJSFComponent() {		
		Model model = MetaDataQueryHelper.getModel(_modelContext);
		Trait t = MetaDataQueryHelper.getTrait(model, "is-jsf-component-library");
		if (t != null)
			return TraitValueHelper.getValueAsBoolean(t);
		
		return false;
	}

	/**
	 * @return convenience method returning default prefix to be used by the tag item
	 */
	private  String getDefaultPrefix() {
		return _tagItem.getDefaultPrefix();
	}

	/**
	 * @return convenience method returning uri of the tag item's library
	 */
	private String getURI() {		
		return _tagItem.getURI();
	}
	
	/**
	 * @return convenience method returning the tag name without prefix
	 * 
	 */
	private String getLocalTagName(){
		return _tagItem.getTagName();
	}
	/**
	 * Add required attributes and default values, if set, to the created tag element
	 * @param element
	 */
	protected void applyRequiredAttrs(Element element) {
		TagCreationInfo info = getTagCreationInfo();
		if (info != null){
			EList list = info.getAttributes();
			if (list != null) {
				for (Iterator it = list.iterator(); it.hasNext();) {
					TagCreationAttribute attr = (TagCreationAttribute)it.next();
					element.setAttribute(attr.getId(), (attr.getValue() == null ? "" : attr.getValue()));
				}
			}
		}			
	}

	/**
	 * If TagCreationInfo is defined for the tag element, apply the template if defined
	 * @param model
	 * @param tagElement
	 */
	protected void applyTemplate(IDOMModel model, Element tagElement) {
		TagCreationInfo tagCreationInfo = getTagCreationInfo();
		if (tagCreationInfo != null)
			PaletteElementTemplateHelper.applyTemplate(model, tagElement, getTagToolItem(), tagCreationInfo); 		
	}

	/**
	 * @return {@link TagCreationInfo} for the tag entity
	 */
	protected TagCreationInfo getTagCreationInfo(){
		Model model = MetaDataQueryHelper.getModel(_modelContext);
		if (model != null){
			Trait trait = MetaDataQueryHelper.getTrait(model, PaletteInfos.TRAIT_ID);
			if (trait != null){
				PaletteInfos pis = (PaletteInfos)trait.getValue();
				PaletteInfo pi = pis.findPaletteInfoById(_tagItem.getId());
				if (pi != null){
					return pi.getTagCreation();					
				}
			}
			//tag-creation trait on entity directly?
			Entity tag = getTagEntity();
			if (tag != null){//metadata exists
				trait = MetaDataQueryHelper.getTrait(tag, "tag-create");
				if (trait != null && trait.getValue() != null){
					return (TagCreationInfo)trait.getValue();					
				}
			}
		}
		return null;
	}

	/**
	 * @return the {@link TagToolPaletteEntry}
	 */
	protected TagToolPaletteEntry getTagToolItem(){
		return _tagItem;
	}
	
	
	/**
	 * Returns the ns prefix for the tag and also creates taglib reference if necessary
	 * @param uri
	 * @param model
	 * @param suggested
	 * @return prefix to use
	 */
	protected String getPrefix(String uri, IDOMModel model,
			String suggested) {
		if (ITLDConstants.URI_HTML.equalsIgnoreCase(uri)
				|| ITLDConstants.URI_JSP.equalsIgnoreCase(uri)
				|| CMDocType.JSP11_DOC_TYPE.equalsIgnoreCase(uri)) {
			return null;
		}

		// now handles custom tag lib
		return JSPUtil.getOrCreatePrefix(model, uri, suggested);
	}
	
	/**
	 * @param tag
	 * @return a "create-tag" {@link Trait} for the tag.  May be null there are no required attrs.
	 */
	protected Trait createRequiredAttrTraits(CMElementDeclaration tag) {

		List reqs = new ArrayList();
		for (Iterator it=tag.getAttributes().iterator();it.hasNext();){
			CMAttributeDeclaration attr = (CMAttributeDeclaration)it.next();
			if (attr.getUsage() == CMAttributeDeclaration.REQUIRED){
				reqs.add(attr);
			}			
		}
		if (reqs.size() > 0)
			return internalCreateTagCreateAttributes(reqs);
		
		return null;
	}		
	
	private Trait internalCreateTagCreateAttributes(List reqs) {
		Trait t = MetadataFactory.eINSTANCE.createTrait();
		t.setId("create-trait");
		
		TagCreationInfo info = PaletteInfosFactory.eINSTANCE.createTagCreationInfo();
		for (Iterator it=reqs.iterator();it.hasNext();){
			TagCreationAttribute attrInfo = PaletteInfosFactory.eINSTANCE.createTagCreationAttribute();
			CMAttributeDeclaration attr = (CMAttributeDeclaration)it.next();
			attrInfo.setId(attr.getAttrName());
			attrInfo.setValue("");//TODO: use default value?
			info.getAttributes().add(attrInfo);
		}
		t.setValue(info); 
		return t;
	}
	
	/**
	 * @return flag indicating that html form container ancestor is required
	 */
	protected boolean isHTMLFormRequired() {
		Trait t = MetaDataQueryHelper.getTrait(getTagEntity(), "requires-html-form");
		if (t != null)
			return TraitValueHelper.getValueAsBoolean(t);
		
		return false;
	}

	/**
	 * @return the {@link Entity} for this tag element being created
	 */
	protected Entity getTagEntity() {
		if (_tagEntity == null){
			_tagEntity = MetaDataQueryHelper.getEntity(_modelContext, _tagItem.getTagName());
			
		}
		return _tagEntity;
	}
}
