/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors.descriptors;

import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * {@link ElementDescriptor} describes the properties expected for a given XML element node.
 *
 * {@link ElementDescriptor} have an XML name, UI name, a tooltip, an SDK url,
 * an attributes list and a children list.
 *
 * An UI node can be "mandatory", meaning the UI node is never deleted and it may lack
 * an actual XML node attached. A non-mandatory UI node MUST have an XML node attached
 * and it will cease to exist when the XML node ceases to exist.
 */
public class ElementDescriptor implements Comparable<ElementDescriptor> {
    private static final String ELEMENT_ICON_FILENAME = "element"; //$NON-NLS-1$

    /** The XML element node name. Case sensitive. */
    protected final String mXmlName;
    /** The XML element name for the user interface, typically capitalized. */
    private final String mUiName;
    /** The list of allowed attributes. */
    private AttributeDescriptor[] mAttributes;
    /** The list of allowed children */
    private ElementDescriptor[] mChildren;
    /* An optional tooltip. Can be empty. */
    private String mTooltip;
    /** An optional SKD URL. Can be empty. */
    private String mSdkUrl;
    /** Whether this UI node must always exist (even for empty models). */
    private final Mandatory mMandatory;

    public enum Mandatory {
        NOT_MANDATORY,
        MANDATORY,
        MANDATORY_LAST
    }

    /**
     * Constructs a new {@link ElementDescriptor} based on its XML name, UI name,
     * tooltip, SDK url, attributes list, children list and mandatory.
     *
     * @param xml_name The XML element node name. Case sensitive.
     * @param ui_name The XML element name for the user interface, typically capitalized.
     * @param tooltip An optional tooltip. Can be null or empty.
     * @param sdk_url An optional SKD URL. Can be null or empty.
     * @param attributes The list of allowed attributes. Can be null or empty.
     * @param children The list of allowed children. Can be null or empty.
     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
     *  ceases to exist.
     */
    public ElementDescriptor(String xml_name, String ui_name, String tooltip, String sdk_url,
            AttributeDescriptor[] attributes,
            ElementDescriptor[] children,
            Mandatory mandatory) {
        mMandatory = mandatory;
        mXmlName = xml_name;
        mUiName = ui_name;
        mTooltip = (tooltip != null && tooltip.length() > 0) ? tooltip : null;
        mSdkUrl = (sdk_url != null && sdk_url.length() > 0) ? sdk_url : null;
        setAttributes(attributes != null ? attributes : new AttributeDescriptor[]{});
        mChildren = children != null ? children : new ElementDescriptor[]{};
    }

    /**
     * Constructs a new {@link ElementDescriptor} based on its XML name, UI name,
     * tooltip, SDK url, attributes list, children list and mandatory.
     *
     * @param xml_name The XML element node name. Case sensitive.
     * @param ui_name The XML element name for the user interface, typically capitalized.
     * @param tooltip An optional tooltip. Can be null or empty.
     * @param sdk_url An optional SKD URL. Can be null or empty.
     * @param attributes The list of allowed attributes. Can be null or empty.
     * @param children The list of allowed children. Can be null or empty.
     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
     *  ceases to exist.
     */
    public ElementDescriptor(String xml_name, String ui_name, String tooltip, String sdk_url,
            AttributeDescriptor[] attributes,
            ElementDescriptor[] children,
            boolean mandatory) {
        mMandatory = mandatory ? Mandatory.MANDATORY : Mandatory.NOT_MANDATORY;
        mXmlName = xml_name;
        mUiName = ui_name;
        mTooltip = (tooltip != null && tooltip.length() > 0) ? tooltip : null;
        mSdkUrl = (sdk_url != null && sdk_url.length() > 0) ? sdk_url : null;
        setAttributes(attributes != null ? attributes : new AttributeDescriptor[]{});
        mChildren = children != null ? children : new ElementDescriptor[]{};
    }

    /**
     * Constructs a new {@link ElementDescriptor} based on its XML name and children list.
     * The UI name is build by capitalizing the XML name.
     * The UI nodes will be non-mandatory.
     *
     * @param xml_name The XML element node name. Case sensitive.
     * @param children The list of allowed children. Can be null or empty.
     * @param mandatory Whether this node must always exist (even for empty models). A mandatory
     *  UI node is never deleted and it may lack an actual XML node attached. A non-mandatory
     *  UI node MUST have an XML node attached and it will cease to exist when the XML node
     *  ceases to exist.
     */
    public ElementDescriptor(String xml_name, ElementDescriptor[] children, Mandatory mandatory) {
        this(xml_name, prettyName(xml_name), null, null, null, children, mandatory);
    }

    /**
     * Constructs a new {@link ElementDescriptor} based on its XML name and children list.
     * The UI name is build by capitalizing the XML name.
     * The UI nodes will be non-mandatory.
     *
     * @param xml_name The XML element node name. Case sensitive.
     * @param children The list of allowed children. Can be null or empty.
     */
    public ElementDescriptor(String xml_name, ElementDescriptor[] children) {
        this(xml_name, prettyName(xml_name), null, null, null, children, false);
    }

    /**
     * Constructs a new {@link ElementDescriptor} based on its XML name.
     * The UI name is build by capitalizing the XML name.
     * The UI nodes will be non-mandatory.
     *
     * @param xml_name The XML element node name. Case sensitive.
     */
    public ElementDescriptor(String xml_name) {
        this(xml_name, prettyName(xml_name), null, null, null, null, false);
    }

    /** Returns whether this node must always exist (even for empty models) */
    public Mandatory getMandatory() {
        return mMandatory;
    }

    @Override
    public String toString() {
        return String.format("%s [%s, attr %d, children %d%s]",    //$NON-NLS-1$
                this.getClass().getSimpleName(),
                mXmlName,
                mAttributes != null ? mAttributes.length : 0,
                mChildren != null ? mChildren.length : 0,
                mMandatory != Mandatory.NOT_MANDATORY ? ", " + mMandatory.toString() : "" //$NON-NLS-1$ //$NON-NLS-2$
                );
    }

    /**
     * Returns the XML element node local name (case sensitive)
     */
    public final String getXmlLocalName() {
        int pos = mXmlName.indexOf(':');
        if (pos != -1) {
            return mXmlName.substring(pos+1);
        }
        return mXmlName;
    }

    /**
     * Returns the XML element node name, including the prefix.
     * Case sensitive.
     * <p/>
     * In Android resources, the element node name for Android resources typically does not
     * have a prefix and is typically the simple Java class name (e.g. "View"), whereas for
     * custom views it is generally the fully qualified class name of the view (e.g.
     * "com.mycompany.myapp.MyView").
     * <p/>
     * Most of the time you'll probably want to use {@link #getXmlLocalName()} to get a local
     * name guaranteed without a prefix.
     * <p/>
     * Note that the prefix that <em>may</em> be available in this descriptor has nothing to
     * do with the actual prefix the node might have (or needs to have) in the actual XML file
     * since descriptors are fixed and do not depend on any current namespace defined in the
     * target XML.
     */
    public String getXmlName() {
        return mXmlName;
    }

    /**
     * Returns the namespace of the attribute.
     */
    public final String getNamespace() {
        // For now we hard-code the prefix as being "android"
        if (mXmlName.startsWith(ANDROID_NS_NAME_PREFIX)) {
            return ANDROID_URI;
        }

        return ""; //$NON-NLs-1$
    }


    /** Returns the XML element name for the user interface, typically capitalized. */
    public String getUiName() {
        return mUiName;
    }

    /**
     * Returns an icon for the element.
     * This icon is generic, that is all element descriptors have the same icon
     * no matter what they represent.
     *
     * @return An icon for this element or null.
     * @see #getCustomizedIcon()
     */
    public Image getGenericIcon() {
        return IconFactory.getInstance().getIcon(ELEMENT_ICON_FILENAME);
    }

    /**
     * Returns an optional icon for the element, typically to be used in XML form trees.
     * <p/>
     * This icon is customized to the given descriptor, that is different elements
     * will have different icons.
     * <p/>
     * By default this tries to return an icon based on the XML name of the element.
     * If this fails, it tries to return the default Android logo as defined in the
     * plugin. If all fails, it returns null.
     *
     * @return An icon for this element. This is never null.
     */
    public Image getCustomizedIcon() {
        IconFactory factory = IconFactory.getInstance();
        int color = hasChildren() ? IconFactory.COLOR_BLUE
                : IconFactory.COLOR_GREEN;
        int shape = hasChildren() ? IconFactory.SHAPE_RECT
                : IconFactory.SHAPE_CIRCLE;
        String name = mXmlName;

        int pos = name.lastIndexOf('.');
        if (pos != -1) {
            // If the user uses a fully qualified name, such as
            // "android.gesture.GestureOverlayView" in their XML, we need to
            // look up only by basename
            name = name.substring(pos + 1);
        }
        Image icon = factory.getIcon(name, color, shape);
        if (icon == null) {
            icon = getGenericIcon();
        }
        if (icon == null) {
            icon = AdtPlugin.getAndroidLogo();
        }
        return icon;
    }

    /**
     * Returns an optional ImageDescriptor for the element.
     * <p/>
     * By default this tries to return an image based on the XML name of the element.
     * If this fails, it tries to return the default Android logo as defined in the
     * plugin. If all fails, it returns null.
     *
     * @return An ImageDescriptor for this element or null.
     */
    public ImageDescriptor getImageDescriptor() {
        IconFactory factory = IconFactory.getInstance();
        int color = hasChildren() ? IconFactory.COLOR_BLUE : IconFactory.COLOR_GREEN;
        int shape = hasChildren() ? IconFactory.SHAPE_RECT : IconFactory.SHAPE_CIRCLE;
        ImageDescriptor id = factory.getImageDescriptor(mXmlName, color, shape);
        return id != null ? id : AdtPlugin.getAndroidLogoDesc();
    }

    /* Returns the list of allowed attributes. */
    public AttributeDescriptor[] getAttributes() {
        return mAttributes;
    }

    /** Sets the list of allowed attributes. */
    public void setAttributes(AttributeDescriptor[] attributes) {
        mAttributes = attributes;
        for (AttributeDescriptor attribute : attributes) {
            attribute.setParent(this);
        }
    }

    /** Returns the list of allowed children */
    public ElementDescriptor[] getChildren() {
        return mChildren;
    }

    /** @return True if this descriptor has children available */
    public boolean hasChildren() {
        return mChildren.length > 0;
    }

    /**
     * Checks whether this descriptor can accept the given descriptor type
     * as a direct child.
     *
     * @return True if this descriptor can accept children of the given descriptor type.
     *   False if not accepted, no children allowed, or target is null.
     */
    public boolean acceptChild(ElementDescriptor target) {
        if (target != null && mChildren.length > 0) {
            String targetXmlName = target.getXmlName();
            for (ElementDescriptor child : mChildren) {
                if (child.getXmlName().equals(targetXmlName)) {
                    return true;
                }
            }
        }

        return false;
    }

    /** Sets the list of allowed children. */
    public void setChildren(ElementDescriptor[] newChildren) {
        mChildren = newChildren;
    }

    /**
     * Sets the list of allowed children.
     * <p/>
     * This is just a convenience method that converts a Collection into an array and
     * calls {@link #setChildren(ElementDescriptor[])}.
     * <p/>
     * This means a <em>copy</em> of the collection is made. The collection is not
     * stored by the recipient and can thus be altered by the caller.
     */
    public void setChildren(Collection<ElementDescriptor> newChildren) {
        setChildren(newChildren.toArray(new ElementDescriptor[newChildren.size()]));
    }

    /**
     * Returns an optional tooltip. Will be null if not present.
     * <p/>
     * The tooltip is based on the Javadoc of the element and already processed via
     * {@link DescriptorsUtils#formatTooltip(String)} to be displayed right away as
     * a UI tooltip.
     */
    public String getTooltip() {
        return mTooltip;
    }

    /** Returns an optional SKD URL. Will be null if not present. */
    public String getSdkUrl() {
        return mSdkUrl;
    }

    /** Sets the optional tooltip. Can be null or empty. */
    public void setTooltip(String tooltip) {
        mTooltip = tooltip;
    }

    /** Sets the optional SDK URL. Can be null or empty. */
    public void setSdkUrl(String sdkUrl) {
        mSdkUrl = sdkUrl;
    }

    /**
     * @return A new {@link UiElementNode} linked to this descriptor.
     */
    public UiElementNode createUiNode() {
        return new UiElementNode(this);
    }

    /**
     * Returns the first children of this descriptor that describes the given XML element name.
     * <p/>
     * In recursive mode, searches the direct children first before descending in the hierarchy.
     *
     * @return The ElementDescriptor matching the requested XML node element name or null.
     */
    public ElementDescriptor findChildrenDescriptor(String element_name, boolean recursive) {
        return findChildrenDescriptorInternal(element_name, recursive, null);
    }

    private ElementDescriptor findChildrenDescriptorInternal(String element_name,
            boolean recursive,
            Set<ElementDescriptor> visited) {
        if (recursive && visited == null) {
            visited = new HashSet<ElementDescriptor>();
        }

        for (ElementDescriptor e : getChildren()) {
            if (e.getXmlName().equals(element_name)) {
                return e;
            }
        }

        if (visited != null) {
            visited.add(this);
        }

        if (recursive) {
            for (ElementDescriptor e : getChildren()) {
                if (visited != null) {
                    if (!visited.add(e)) {  // Set.add() returns false if element is already present
                        continue;
                    }
                }
                ElementDescriptor f = e.findChildrenDescriptorInternal(element_name,
                        recursive, visited);
                if (f != null) {
                    return f;
                }
            }
        }

        return null;
    }

    /**
     * Utility helper than pretty-formats an XML Name for the UI.
     * This is used by the simplified constructor that takes only an XML element name.
     *
     * @param xml_name The XML name to convert.
     * @return The XML name with dashes replaced by spaces and capitalized.
     */
    private static String prettyName(String xml_name) {
        char c[] = xml_name.toCharArray();
        if (c.length > 0) {
            c[0] = Character.toUpperCase(c[0]);
        }
        return new String(c).replace("-", " ");  //$NON-NLS-1$  //$NON-NLS-2$
    }

    /**
     * Returns true if this node defines the given attribute
     *
     * @param namespaceUri the namespace URI of the target attribute
     * @param attributeName the attribute name
     * @return true if this element defines an attribute of the given name and namespace
     */
    public boolean definesAttribute(String namespaceUri, String attributeName) {
        for (AttributeDescriptor desc : mAttributes) {
            if (desc.getXmlLocalName().equals(attributeName) &&
                    desc.getNamespaceUri().equals(namespaceUri)) {
                return true;
            }
        }

        return false;
    }

    // Implements Comparable<ElementDescriptor>:
    @Override
    public int compareTo(ElementDescriptor o) {
        return mUiName.compareToIgnoreCase(o.mUiName);
    }

    /**
     * Ensures that this view descriptor's attribute list is up to date. This is
     * always the case for all the builtin descriptors, but for example for a
     * custom view, it could be changing dynamically so caches may have to be
     * recomputed. This method will return true if nothing changed, and false if
     * it recomputed its info.
     *
     * @return true if the attributes are already up to date and nothing changed
     */
    public boolean syncAttributes() {
        return true;
    }
}
