/*******************************************************************************
 * Copyright (c) 2005 Oracle Corporation.
 * 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:
 *    Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.dtmanager.converter.internal;

import java.net.URL;

import javax.servlet.jsp.el.ELException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.IImageDescriptorProvider;
import org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider;
import org.eclipse.jst.jsf.common.metadata.internal.IResourceURLProvider;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
import org.eclipse.jst.pagedesigner.converter.ITagConverter;
import org.eclipse.jst.pagedesigner.dtmanager.DTManager;
import org.eclipse.jst.pagedesigner.dtmanager.IDTInfo;
import org.eclipse.jst.pagedesigner.dtmanager.converter.ITagConverterDecorator;
import org.eclipse.jst.pagedesigner.dtmanager.dtinfo.ResolveAttributeValue;
import org.eclipse.jst.pagedesigner.dtmanager.dtinfo.TagDecorateInfo;
import org.eclipse.jst.pagedesigner.preview.PageExpressionContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * ITagConverterDecorator implementation for DTTagConverter.
 * 
 * @author Ian Trimble - Oracle
 */
public class DTTagConverterDecorator implements ITagConverterDecorator
{

    private static final String DECORATE_INFO_ID_DESIGN = "vpd-decorate-design"; //$NON-NLS-1$
    private static final String DECORATE_INFO_ID_PREVIEW = "vpd-decorate-preview"; //$NON-NLS-1$
    private static final String MD_PLUGIN_LOCATION = "$metadata-plugin-location$"; //$NON-NLS-1$

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.jst.pagedesigner.dtmanager.converter.ITagConverterDecorator
     * #decorate(org.eclipse.jst.pagedesigner.converter.ITagConverter)
     */
    public void decorate(ITagConverter tagConverter)
    {
        if (!(tagConverter instanceof DTTagConverter))
        {
            throw new IllegalArgumentException(
                    "ITagConverter argument must be an instance of DTTagConverter"); //$NON-NLS-1$
        }
        DTTagConverter dtTagConverter = (DTTagConverter) tagConverter;

        if (dtTagConverter.getMode() == IConverterFactory.MODE_DESIGNER)
        {
            decorateFromDTInfo(dtTagConverter, DECORATE_INFO_ID_DESIGN);
        } else if (dtTagConverter.getMode() == IConverterFactory.MODE_PREVIEW)
        {
            decorateFromDTInfo(dtTagConverter, DECORATE_INFO_ID_PREVIEW);
        }

        if (tagConverter.getResultElement() == null
                && tagConverter.isVisualByHTML())
        {
            createUnknownTagRepresentation(dtTagConverter);
        }
    }

    /**
     * Performs decoration of the specified DTTagConverter instance from IDTInfo
     * (metadata) for the specified (by ID) TagDecorateInfo.
     * 
     * @param dtTagConverter
     *            DTTagConverter instance.
     * @param tagDecorateInfoID
     *            ID of the TagDecorateInfo to be located in metadata.
     */
    protected void decorateFromDTInfo(DTTagConverter dtTagConverter,
            String tagDecorateInfoID)
    {
        Element srcElement = dtTagConverter.getHostElement();
        DTManager dtManager = DTManager.getInstance();
        IDTInfo dtInfo = dtManager.getDTInfo(srcElement);
        if (dtInfo != null)
        {
            TagDecorateInfo tdInfo = dtInfo
                    .getTagDecorateInfo(tagDecorateInfoID);
            if (tdInfo != null)
            {
                dtTagConverter.setMultiLevel(tdInfo.isMultiLevel());
                dtTagConverter.setNeedBorderDecorator(tdInfo
                        .isNeedBorderDecorator());
                dtTagConverter.setNeedTableDecorator(tdInfo
                        .isNeedTableDecorator());
                if (tdInfo.isNonVisual())
                {
                    setNonVisual(dtTagConverter, dtInfo, tdInfo
                            .getNonVisualImagePath());
                }
                if (tdInfo.isResolveChildText())
                {
                    resolveChildText(dtTagConverter.getResultElement(), dtInfo);
                }
                if (tdInfo.isSetNonVisualChildElements())
                {
                    setNonVisualChildElements(dtTagConverter, srcElement);
                }
                dtTagConverter.setWidget(tdInfo.isWidget());
                dtTagConverter.setMinHeight(tdInfo.getMinHeight());
                dtTagConverter.setMinWidth(tdInfo.getMinWidth());
                ResolveAttributeValue resAttrValue = tdInfo
                        .getResolveAttributeValue();
                if (resAttrValue != null)
                {
                    String attributeName = resAttrValue.getAttributeName();
                    if (attributeName != null && attributeName.length() > 0)
                    {
                        resolveAttributeValue(dtTagConverter.getHostElement(),
                                dtTagConverter.getResultElement(),
                                attributeName, dtInfo, tagDecorateInfoID);
                    }
                }
            }
        }
    }

    /**
     * Creates a visual representation result Element for an unknown tag.
     * 
     * @param dtTagConverter
     *            DTTagConverter instance.
     */
    protected void createUnknownTagRepresentation(DTTagConverter dtTagConverter)
    {
        Element element = dtTagConverter.createElement("span"); //$NON-NLS-1$
        element.setAttribute("style", "color:red;font-weight:bold;"); //$NON-NLS-1$ //$NON-NLS-2$
        Text text = dtTagConverter
                .createText("<" + dtTagConverter.getHostElement().getTagName() + "/>"); //$NON-NLS-1$ //$NON-NLS-2$
        element.appendChild(text);
        dtTagConverter.setResultElement(element);
        dtTagConverter.setWidget(true);
    }

    /**
     * Adds child Elements of the specified source Element to the specified
     * DTTagConverter instance's collection of non-visual children.
     * 
     * @param dtTagConverter
     *            DTTagConverter instance.
     * @param srcElement
     *            Source Element for which child Elements are to be added.
     */
    protected void setNonVisualChildElements(DTTagConverter dtTagConverter,
            Element srcElement)
    {
        NodeList childNodes = srcElement.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++)
        {
            Node curNode = childNodes.item(i);
            if (curNode.getNodeType() == Node.ELEMENT_NODE)
            {
                dtTagConverter.addNonVisualChildElement((Element) curNode);
            }
        }
    }

    /**
     * Performs simple EL resolution for the child Text Node of the specified
     * source Element instance.
     * 
     * @param srcElement
     *            Source Element for which child Text Node EL resolution is to
     *            be performed.
     * @param dtInfo
     *            IDTInfo instance.
     */
    protected void resolveChildText(Element srcElement, IDTInfo dtInfo)
    {
        if (srcElement != null)
        {
            NodeList childNodes = srcElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++)
            {
                Node childNode = childNodes.item(i);
                if (childNode.getNodeType() == Node.TEXT_NODE)
                {
                    Text textNode = (Text) childNode;
                    String textNodeValue = textNode.getNodeValue();
                    try
                    {
                        String newTextNodeValue;
                        if (textNodeValue.contains(MD_PLUGIN_LOCATION))
                        {
                            newTextNodeValue = resolveMDPluginLocation(
                                    textNodeValue, dtInfo);
                        } else
                        {
                            newTextNodeValue = (String) PageExpressionContext
                                    .getCurrent().evaluateExpression(
                                            textNodeValue, String.class, null);
                        }
                        if (newTextNodeValue != null
                                && !textNodeValue.equals(newTextNodeValue))
                        {
                            textNode.setNodeValue(newTextNodeValue);
                        }
                    } catch (Exception ex)
                    {
                        // ignore - could not resolve, do not change existing
                        // value
                    }
                }
            }
        }
    }

    /**
     * Performs simple EL resolution for the value of the specified attribute of
     * the specified Element.
     * 
     * @param srcElement
     * 
     * @param targetElement
     *            Source Element instance.
     * @param attributeName
     *            Name of attribute for which the value should be resolved.
     * @param dtInfo
     *            IDTInfo instance.
     * @param tagDecorateInfoID 
     */
    protected void resolveAttributeValue(Element srcElement,
            Element targetElement, String attributeName, IDTInfo dtInfo, 
            String tagDecorateInfoID)
    {
        if (targetElement != null)
        {
            String oldAttributeValue = null;
            String targetAttributeName = attributeName;
            // determine if attributeName is XPath and re-target as appropriate
            if (attributeName.contains("/")) { //$NON-NLS-1$
                int lastSlashPos = attributeName.lastIndexOf("/"); //$NON-NLS-1$
                String xPathExpression = attributeName.substring(0,
                        lastSlashPos);
                XPath xPath = XPathFactory.newInstance().newXPath();
                try
                {
                    Object resultObject = xPath.evaluate(xPathExpression,
                            targetElement, XPathConstants.NODE);
                    if (resultObject instanceof Element)
                    {
                        targetElement = (Element) resultObject;
                        targetAttributeName = attributeName
                                .substring(lastSlashPos + 1);
                    }
                    else if (resultObject instanceof Text)
                    {
                        Node parentNode = ((Text)resultObject).getParentNode();
                        if (parentNode instanceof Element)
                        {
                            parentNode.normalize();
                            targetAttributeName = IAttributeValueResolver.TEXT_NODE_KEY;
                            oldAttributeValue = ((Text)resultObject).getNodeValue();
                        }
                    }
                }
                catch (XPathExpressionException xee)
                {
                    // could not evaluate - leave targetElement and
                    // targetAttributeName unchanged
                }
            }

            
            if (!IAttributeValueResolver.TEXT_NODE_KEY.equals(targetAttributeName))
            {
                oldAttributeValue = targetElement.getAttribute(targetAttributeName);
            }

            if (oldAttributeValue != null && oldAttributeValue.length() > 0)
            {
                String newAttributeValue;
                if (oldAttributeValue.contains(MD_PLUGIN_LOCATION))
                {
                    newAttributeValue = resolveMDPluginLocation(
                            oldAttributeValue, dtInfo);
                }
                else
                {
                    newAttributeValue = resolveAttributeValue(srcElement,
                            targetElement, targetAttributeName,
                            oldAttributeValue, tagDecorateInfoID);
                }
                if (newAttributeValue != null
                        && !oldAttributeValue.equals(newAttributeValue))
                {
                    if (IAttributeValueResolver.TEXT_NODE_KEY
                            .equals(targetAttributeName))
                    {
                        for (int i = targetElement.getChildNodes().getLength()-1; i >= 0; i--)
                        {
                            Node childNode = targetElement.getChildNodes().item(i);
                            if (childNode.getNodeType() == Node.TEXT_NODE)
                            {
                                targetElement.removeChild(childNode);
                            }
                        }
                        targetElement.appendChild(targetElement.getOwnerDocument().createTextNode(newAttributeValue));
                    }
                    else
                    {
                        targetElement.setAttribute(targetAttributeName,
                                newAttributeValue);
                    }
                }
            }
        }
    }

    private String resolveAttributeValue(final Element originalElement,
            final Element convertedElement,
            final String convertedAttributeName, final String oldAttributeValue,
            final String tagDecorateInfoID)
    {
        String newValue = null;
        boolean valueResolved = false;
        final String[] result = new String[1];

        for (final IAttributeValueResolver resolver : AttributeValueResolverRegistryReader
                .getInstance().getExtensions())
        {
            SafeRunner.run(new ISafeRunnable()
            {
                public void handleException(Throwable exception)
                {
                    PDPlugin
                            .log(
                                    "While resolving attribute in converter decorator", exception); //$NON-NLS-1$
                }

                public void run() throws Exception
                {
                    if (resolver.canResolve(originalElement,
                            convertedElement, convertedAttributeName, oldAttributeValue))
                    {
                        result[0] = resolver.resolveAttribute(
                                originalElement, convertedElement,
                                convertedAttributeName, oldAttributeValue);
                    }
                }
            });
            if (result[0] != null)
            {
                newValue = result[0];
                valueResolved = true;
                break;
            }
        }

        if (!valueResolved &&
                // maintain backward compatibility: only do this default
                // behaviour for the preview
                tagDecorateInfoID.equals(DECORATE_INFO_ID_PREVIEW))
        {
            // fall- through to default case.
            try
            {
                
                PageExpressionContext current = PageExpressionContext.getCurrent();
                if (current != null)
                {
                    return (String) current
                            .evaluateExpression(oldAttributeValue, String.class,
                                    null);
                }
            } catch (ELException e)
            {
                // ignore. we will just return null since couldn't resolve
            }
        }
        return newValue;
    }

    /**
     * Resolves any instance of MD_PLUGIN_LOCATION in input String.
     * 
     * @param input
     *            Input String.
     * @param dtInfo
     *            IDTInfo instance.
     * @return Input String with any instance of MD_PLUGIN_LOCATION resolved.
     */
    protected String resolveMDPluginLocation(String input, IDTInfo dtInfo)
    {
        String output = input;
        if (input != null && input.contains(MD_PLUGIN_LOCATION))
        {
            int tokenStart = input.indexOf(MD_PLUGIN_LOCATION);
            int tokenEnd = tokenStart + MD_PLUGIN_LOCATION.length();
            String prefix = input.substring(0, tokenStart);
            String suffix = input.substring(tokenEnd);
            Trait trait = dtInfo.getTrait();
            IMetaDataSourceModelProvider mdSourceModelProvider = trait
                    .getSourceModelProvider();
            IResourceURLProvider resourceURLProvider = (IResourceURLProvider) mdSourceModelProvider
                    .getAdapter(IResourceURLProvider.class);
            URL url = resourceURLProvider.getResourceURL("/META-INF/"); //$NON-NLS-1$
            String resolvedToken = url.toExternalForm();
            resolvedToken = resolvedToken.substring(0,
                    resolvedToken.length() - 10);
            output = prefix + resolvedToken + suffix;
        }
        return output;
    }

    /**
     * Sets DTTagConverter instance as non-visual as HTML and sets the
     * ImageDescriptor instance that DTTagConverter will use to return an Image
     * for rendering.
     * 
     * @param dtTagConverter
     *            DTTagConverter instance.
     * @param dtInfo
     *            IDTInfo instance.
     * @param imagePath
     *            Image path, relative to declaring plug-in.
     */
    protected void setNonVisual(DTTagConverter dtTagConverter, IDTInfo dtInfo,
            String imagePath)
    {
        dtTagConverter.setVisualByHTML(false);
        if (imagePath != null && imagePath.length() > 0)
        {
            Trait trait = dtInfo.getTrait();
            IImageDescriptorProvider imgDescProvider = (IImageDescriptorProvider) trait
                    .getSourceModelProvider().getAdapter(
                            IImageDescriptorProvider.class);
            if (imgDescProvider != null)
            {
                ImageDescriptor imageDescriptor = imgDescProvider
                        .getImageDescriptor(imagePath);
                dtTagConverter.setVisualImageDescriptor(imageDescriptor);
            }
        }
    }

}
