/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.converter;

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

import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
import org.eclipse.jst.pagedesigner.dom.DOMUtil;
import org.eclipse.jst.pagedesigner.preview.PageExpressionContext;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * This is base class for all non-hidden tag converters.
 * 
 * @author mengbo
 * @version 1.5
 */
public abstract class AbstractTagConverter implements ITagConverter,
		ITagEditInfo, INodeAdapter, IDOMFactory {
	private IDOMDocument _targetDocument;

	private Element _hostElement;

	private Element _resultElement;

	private List _childNodes = Collections.EMPTY_LIST;

	private Map _childNodePositions = Collections.EMPTY_MAP;

	private int _mode;

	private int _minWidth;

	private int _minHeight;

	private boolean _needBorderDecorator;

	/**
	 * 
	 */
	public AbstractTagConverter(Element host) {
		_hostElement = host;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.converter.ITagConverter#setTargetDocument(org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument)
	 */
	public void setDestDocument(IDOMDocument document) {
		_targetDocument = document;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#convertRefresh(java.lang.Object)
	 */
	public final void convertRefresh(Object context) {
		_resultElement = null;
		_childNodes = new ArrayList();
		_childNodePositions = new HashMap();

		_resultElement = doConvertRefresh();
		if (_resultElement instanceof INodeNotifier) {
			((INodeNotifier) _resultElement).addAdapter(this);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
	 *      int, java.lang.Object, java.lang.Object, java.lang.Object, int)
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType,
			Object changedFeature, Object oldValue, Object newValue, int pos) {
		// do nothing.
	}

	/**
	 * Child class should override this method. The child class should NEVER
	 * change the host DOM structure.
	 * 
	 * @return the convert result. Should be an HTML element.
	 */
	protected abstract Element doConvertRefresh();

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getHostElement()
	 */
	public final Element getHostElement() {
		return _hostElement;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getResultElement()
	 */
	public final Element getResultElement() {
		return _resultElement;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getChildModeList()
	 */
	public final List getChildModeList() {
		return _childNodes;
	}


	public List getNonVisualChildren() 
    {
	    // by default, no non-visual children
        return Collections.EMPTY_LIST;
    }

    /**
	 * child class should call this method.
	 * 
	 * @param childNode
	 *            the childNode of the hostElement that should be futher
	 *            converted.
	 * @param position
	 * 
	 */
	protected void addChild(Node childNode, ConvertPosition position) {
		_childNodes.add(childNode);
		_childNodePositions.put(childNode, position);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getChildVisualPosition(org.w3c.dom.Node)
	 */
	public final ConvertPosition getChildVisualPosition(Node childModel) {
		return (ConvertPosition) _childNodePositions.get(childModel);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#isVisualByHTML()
	 */
	public boolean isVisualByHTML() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#getVisualImage()
	 */
	public Image getVisualImage() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.visualtag.ITagConverter#dispose()
	 */
	public void dispose() {
        // do nothing; children may wish to sub-class
        // TODO: null shared references?
        // this doesn't seem to be called by anybody..
        // need to review this
	}

	protected boolean shouldIgnore(Node node) {
		int nodeType = node.getNodeType();
		switch (nodeType) {
		case Node.TEXT_NODE:
		case Node.CDATA_SECTION_NODE:
		case Node.ELEMENT_NODE:
			return false;
		default:
			return true;
		}

	}

	/**
	 * utility method for those converter that only converts the host tag's name
	 * and directly copy children.
	 * 
	 */
	protected void copyChildren(Element src, Element dest) {
		Node node = src.getFirstChild();
		int index = 0;
		for (; node != null; node = node.getNextSibling()) {
			if (!shouldIgnore(node)) {
				addChild(node, new ConvertPosition(dest, index++));
			}
		}
	}

	/**
	 * utility method for those converter that directly copy children.
	 * 
	 */
	protected void dumCopyChildren(Element src, Element dest) {
		Node node = src.getFirstChild();
		Document destDoc = dest.getOwnerDocument();
		for (; node != null; node = node.getNextSibling()) {
			if (!shouldIgnore(node)) {
				Node n = DOMUtil.cloneNodeDeepIgnoreError(destDoc, node);
				dest.appendChild(n);
			}
		}
	}

	/**
	 * In the future, the conversion result HTML DOM tree could be in another
	 * document.
	 * 
	 * @return the destination document
	 */
	public IDOMDocument getDestDocument() {
		if (this._targetDocument != null) {
			return this._targetDocument;
		}
        return (IDOMDocument) _hostElement.getOwnerDocument();
	}

	/**
	 * shortcut method. Child class should always use this method to create a
	 * result element.
	 * 
	 * @param tagName
	 * @return a new element named tagName
	 */
	public Element createElement(String tagName) {
		return getDestDocument().createElement(tagName);
	}

	/**
	 * shortcut method. Child class should always use this method to create a
	 * text node.
	 * 
	 * @param text
	 * @return a new text node using text as the value
	 */
	public Text createText(String text) {
		return getDestDocument().createTextNode(text);
	}

	protected String mapURL(String original) {
		// TODO: how to map URL? such as original url look like:
		// getContext().getPath()+...
		return original;
	}

	// TODO: FIXME: XXX:
	// if the value is expression, we may want to do something here!!!
	protected String mapValue(String value) {
		if (value == null) {
			return null;
		}
		if (isDesignerMode()) {
			// if there has jsf binding expressions
			int checkPos = value.indexOf("#{");
			if (checkPos != -1) {
				String mapValue = "";
				int preferType = PreferenceReader.getMapValueType();
				switch (preferType) {
				case PreferenceReader.FULL_EXPRESSION_TYPE:
					mapValue = value;
					break;
				case PreferenceReader.LAST_EXPRESSION_TYPE:
					String strBackup = value;
					StringBuffer sb = new StringBuffer();
					while (strBackup.indexOf("#{") != -1) {
						int pos = strBackup.indexOf("#{");
						int endBracketPos = strBackup.indexOf("}", pos + 1);
						if (endBracketPos != -1) {
							sb.append(strBackup.substring(0, pos + 2));
							String exp = strBackup.substring(pos + 2,
									endBracketPos);
							if (allowTrim(exp)) {
								int lastDotPos = exp.lastIndexOf(".");
								if (lastDotPos != -1) {
									String convertedExp = exp
											.substring(lastDotPos + 1);
									sb.append(convertedExp);
								} else {
									sb.append(exp);
								}

							} else {
								sb.append(exp);
							}
							sb.append("}");
						} else {
							break;
						}
						if (strBackup.length() > endBracketPos + 1) {
							strBackup = strBackup.substring(endBracketPos + 1);
						} else {
							strBackup = "";
							break;
						}

					}
					sb.append(strBackup);
					mapValue = sb.toString();
					break;
				case PreferenceReader.REAL_VALUE_TYPE:
					// TODO calculate the expression value
				default:
					mapValue = value;
					break;
				}

				return mapValue;
			}
		} else {
			// preview mode. let's try to display the value.
			try {
				return (String) PageExpressionContext.getCurrent()
						.evaluateExpression(value, String.class, null);
			} catch (Exception ex) {
				// can't calculate the result. ignore.
				// ex.printStackTrace();
			}
		}
		return value;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#needBorderDecorator()
	 */
	public boolean needBorderDecorator() {
		return this._needBorderDecorator;
	}

	public void setNeedBorderDecorator(boolean b) {
		this._needBorderDecorator = b;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo#needTableDecorator()
	 */
	public boolean needTableDecorator() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#isAdapterForType(java.lang.Object)
	 */
	public boolean isAdapterForType(Object type) {
		if (type == ITagEditInfo.class) {
			return true;
		}
		return false;
	}

	/**
	 * @param mode
	 */
	public final void setMode(int mode) {
		this._mode = mode;
	}

	public final boolean isPreviewMode() {
		return this._mode == IConverterFactory.MODE_PREVIEW;
	}

	public final boolean isDesignerMode() {
		return this._mode == IConverterFactory.MODE_DESIGNER;
	}

	public final int getMode() {
		return this._mode;
	}

	/**
	 * The method is used to judge whether the value binding and method binding
	 * expression is allowed to be trimmed.Currently only expression contains
	 * only letter,digit,and '.' is allowed to be trimmed.
	 * 
	 * @param expression
	 *            value binding or method binding expression
	 * @return
	 */
	private boolean allowTrim(String expression) {
		for (int i = 0, size = expression.length(); i < size; i++) {
			char ch = expression.charAt(i);
			if (!Character.isLetterOrDigit(ch) && (ch != '.') && (ch != '_')) {
				return false;
			}
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#getMinWidth()
	 */
	public int getMinWidth() {
		return this._minWidth;
	}

	public void setMinWidth(int minWidth) {
		this._minWidth = minWidth;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.converter.AbstractTagConverter#getMinHeight()
	 */
	public int getMinHeight() {
		return this._minHeight;
	}

	public void setMinHeight(int minHeight) {
		this._minHeight = minHeight;
	}

	public static boolean hasAttribute(Element element, String attrname) {
		return element.hasAttribute(attrname);
	}
}
