/*******************************************************************************
  * Copyright (c) 2007-2008 Red Hat, Inc.
  * Distributed under license by Red Hat, Inc. All rights reserved.
  * This program is 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
  *
  * Contributor:
  *     Red Hat, Inc. - initial API and implementation
  ******************************************************************************/
package org.jboss.tools.jsf.vpe.ajax4jsf.template;

import org.jboss.tools.vpe.editor.context.VpePageContext;
import org.jboss.tools.vpe.editor.mapping.AttributeData;
import org.jboss.tools.vpe.editor.mapping.NodeData;
import org.jboss.tools.vpe.editor.template.VpeAbstractTemplate;
import org.jboss.tools.vpe.editor.template.VpeChildrenInfo;
import org.jboss.tools.vpe.editor.template.VpeCreationData;
import org.jboss.tools.vpe.editor.util.HTML;
import org.mozilla.interfaces.nsIDOMAttr;
import org.mozilla.interfaces.nsIDOMDocument;
import org.mozilla.interfaces.nsIDOMElement;
import org.mozilla.interfaces.nsIDOMText;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.jboss.tools.jsf.vpe.jsf.template.util.model.VpeElementProxyData;
import org.jboss.tools.jsf.vpe.richfaces.template.util.RichFaces;

import com.sun.org.apache.regexp.internal.recompile;

/**
 * @author yradtsevich
 *
 */
public class Ajax4JSFStatusTemplate extends VpeAbstractTemplate {

	/*
	 *<vpe:tag name="a4j:status" case-sensitive="yes">
	 *	<vpe:template children="yes" modify="yes">
	 *		<span class="{@styleClass};{@stopStyleClass}" style="{@style};{@stopStyle}" title="{tagstring()}">
	 *			<vpe:value expr=" {jsfvalue(@stopText)}"/>
	 *		</span>
	 *	</vpe:template>
	 *</vpe:tag>
	 */
	
	public VpeCreationData create(VpePageContext pageContext, Node sourceNode,
			nsIDOMDocument visualDocument) {
		Creator creator = new Creator(pageContext, (Element)sourceNode, visualDocument);
		return creator.create();
	}
	
	/**
	 * @see org.jboss.tools.vpe.editor.template.VpeAbstractTemplate#isRecreateAtAttrChange(org.jboss.tools.vpe.editor.context.VpePageContext, org.w3c.dom.Element, org.mozilla.interfaces.nsIDOMDocument, org.mozilla.interfaces.nsIDOMElement, java.lang.Object, java.lang.String, java.lang.String)
	 */
	@Override
	public boolean isRecreateAtAttrChange(VpePageContext pageContext,
			Element sourceElement, nsIDOMDocument visualDocument,
			nsIDOMElement visualNode, Object data, String name, String value) {
		return true;
	}
	
	private static class Creator {
		private static final String ATTR_STOP_TEXT = "stopText";//$NON-NLS-1$
		private static final String STOP_FACET_NAME = "stop";//$NON-NLS-1$
		private static final String START_FACET_NAME = "start";//$NON-NLS-1$
		private static final String ATTR_STOP_STYLE_CLASS = "stopStyleClass"; //$NON-NLS-1$
		private static final String ATTR_STOP_STYLE = "stopStyle"; //$NON-NLS-1$
		private final VpePageContext pageContext;
		private final Element sourceElement;
		private final nsIDOMDocument visualDocument;
		private VpeCreationData vpeCreationData;

		public Creator(VpePageContext pageContext, Element sourceElement,
				nsIDOMDocument visualDocument) {
			this.pageContext = pageContext;
			this.sourceElement = sourceElement;
			this.visualDocument = visualDocument;
		}


		public VpeCreationData create() {
			nsIDOMElement mainElement = createMainElement();			
			vpeCreationData = new VpeCreationData(mainElement);
			nsIDOMElement stopTextElement = createStopTextElement();
			if (stopTextElement != null) {
				mainElement.appendChild(createStopTextElement());
			}
			addChildrenInfo(mainElement);
			return vpeCreationData;
		}
		
		private nsIDOMElement createMainElement() {
			nsIDOMElement span = visualDocument.createElement(HTML.TAG_SPAN);
			
			// set class of the span to "{@styleClass} {@stopStyleClass}"
			{
				String styleClass = sourceElement.getAttribute(RichFaces.ATTR_STYLE_CLASS);
				String stopStyleClass = sourceElement.getAttribute(ATTR_STOP_STYLE_CLASS);
				StringBuffer spanClass = new StringBuffer();
				if (styleClass != null) {
					spanClass.append(styleClass);
				}
				if (stopStyleClass != null) {
					spanClass.append(HTML.VALUE_CLASS_DELIMITER).append(stopStyleClass);
				}
				span.setAttribute(HTML.ATTR_CLASS, spanClass.toString());
			}

			// set style of the span to "{@style};{@stopStyle}"
			{
				String style = sourceElement.getAttribute(RichFaces.ATTR_STYLE);
				String stopStyle = sourceElement.getAttribute(ATTR_STOP_STYLE);
				StringBuffer spanStyle = new StringBuffer();
				if (style != null) {
					spanStyle.append(style).append(HTML.VALUE_STYLE_DELIMITER); 
				}
				if (stopStyle != null) {
					spanStyle.append(stopStyle).append(HTML.VALUE_STYLE_DELIMITER);
				}
				span.setAttribute(HTML.ATTR_STYLE, spanStyle.toString());
			}
			return span;
		}
		
		/**
		 * Creates new {@code nsIDOMElement} and inserts text of {@code 'stopText'} attribute
		 * into this element. Also it registers created element in {@link #vpeCreationData}
		 * 
		 * @return created {@code nsIDOMElement} or {@code null} if {@link #sourceElement}
		 * does not have {@code 'stopText'} attribute
		 */
		private nsIDOMElement createStopTextElement() {
			nsIDOMElement visualElement = null;
			
			Attr stopTextAttribute = sourceElement.getAttributeNode(ATTR_STOP_TEXT);
			if (stopTextAttribute != null) {
				visualElement = visualDocument.createElement(HTML.TAG_SPAN);
				nsIDOMText textNode = visualDocument.createTextNode(
						stopTextAttribute.getNodeValue());
				visualElement.appendChild(textNode);
				// add attribute for ability of editing
				VpeElementProxyData elementData = new VpeElementProxyData();
				elementData.addNodeData(new AttributeData(stopTextAttribute, textNode, true));
				vpeCreationData.setElementData(elementData);
			}
			
			return visualElement;
		}
		
		/**
		 * Creates new object of {@link VpeChildrenInfo}, initializes it,
		 * and adds it to {@link #vpeCreationData}
		 * 
		 * @param visualParent visual parent for {@code VpeChildrenInfo}
		 */
		private void addChildrenInfo(nsIDOMElement visualParent) {
			final VpeChildrenInfo childrenInfo = new VpeChildrenInfo(visualParent);
			vpeCreationData.addChildrenInfo(childrenInfo);
			NodeList children = sourceElement.getChildNodes();
			int childrenLength = children.getLength();
			for (int i = 0; i < childrenLength; i++) {
				Node child = children.item(i);
				if (child.getNodeType() == Node.ELEMENT_NODE
						&& child.getNodeName().endsWith(RichFaces.TAG_FACET)) {
					Element facet = (Element)child;
					String facetName = facet.getAttribute(RichFaces.ATTR_NAME);
					if (START_FACET_NAME.equalsIgnoreCase(facetName)) {
						// just skip
					} else if (STOP_FACET_NAME.equalsIgnoreCase(facetName)) {
						childrenInfo.addSourceChild(facet);
					}
				}
			}
		}
	}
}
