/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.ui.tree;

import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor.Mandatory;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.widgets.Shell;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import java.util.List;

/**
 * Performs basic actions on an XML tree: add node, remove node, move up/down.
 */
public abstract class UiActions implements ICommitXml {

    public UiActions() {
    }

    //---------------------
    // Actual implementations must override these to provide specific hooks

    /** Returns the UiDocumentNode for the current model. */
    abstract protected UiElementNode getRootNode();

    /** Commits pending data before the XML model is modified. */
    @Override
    abstract public void commitPendingXmlChanges();

    /**
     * Utility method to select an outline item based on its model node
     *
     * @param uiNode The node to select. Can be null (in which case nothing should happen)
     */
    abstract protected void selectUiNode(UiElementNode uiNode);

    //---------------------

    /**
     * Called when the "Add..." button next to the tree view is selected.
     * <p/>
     * This simplified version of doAdd does not support descriptor filters and creates
     * a new {@link UiModelTreeLabelProvider} for each call.
     */
    public void doAdd(UiElementNode uiNode, Shell shell) {
        doAdd(uiNode, null /* descriptorFilters */, shell, new UiModelTreeLabelProvider());
    }

    /**
     * Called when the "Add..." button next to the tree view is selected.
     *
     * Displays a selection dialog that lets the user select which kind of node
     * to create, depending on the current selection.
     */
    public void doAdd(UiElementNode uiNode,
            ElementDescriptor[] descriptorFilters,
            Shell shell, ILabelProvider labelProvider) {
        // If the root node is a document with already a root, use it as the root node
        UiElementNode rootNode = getRootNode();
        if (rootNode instanceof UiDocumentNode && rootNode.getUiChildren().size() > 0) {
            rootNode = rootNode.getUiChildren().get(0);
        }

        NewItemSelectionDialog dlg = new NewItemSelectionDialog(
                shell,
                labelProvider,
                descriptorFilters,
                uiNode, rootNode);
        dlg.open();
        Object[] results = dlg.getResult();
        if (results != null && results.length > 0) {
            addElement(dlg.getChosenRootNode(), null, (ElementDescriptor) results[0],
                    true /*updateLayout*/);
        }
    }

    /**
     * Adds a new XML element based on the {@link ElementDescriptor} to the given parent
     * {@link UiElementNode}, and then select it.
     * <p/>
     * If the parent is a document root which already contains a root element, the inner
     * root element is used as the actual parent. This ensure you can't create a broken
     * XML file with more than one root element.
     * <p/>
     * If a sibling is given and that sibling has the same parent, the new node is added
     * right after that sibling. Otherwise the new node is added at the end of the parent
     * child list.
     *
     * @param uiParent An existing UI node or null to add to the tree root
     * @param uiSibling An existing UI node before which to insert the new node. Can be null.
     * @param descriptor The descriptor of the element to add
     * @param updateLayout True if layout attributes should be set
     * @return The new {@link UiElementNode} or null.
     */
    public UiElementNode addElement(UiElementNode uiParent,
            UiElementNode uiSibling,
            ElementDescriptor descriptor,
            boolean updateLayout) {
        if (uiParent instanceof UiDocumentNode && uiParent.getUiChildren().size() > 0) {
            uiParent = uiParent.getUiChildren().get(0);
        }
        if (uiSibling != null && uiSibling.getUiParent() != uiParent) {
            uiSibling = null;
        }

        UiElementNode uiNew = addNewTreeElement(uiParent, uiSibling, descriptor, updateLayout);
        selectUiNode(uiNew);

        return uiNew;
    }

    /**
     * Called when the "Remove" button is selected.
     *
     * If the tree has a selection, remove it.
     * This simply deletes the XML node attached to the UI node: when the XML model fires the
     * update event, the tree will get refreshed.
     */
    public void doRemove(final List<UiElementNode> nodes, Shell shell) {

        if (nodes == null || nodes.size() == 0) {
            return;
        }

        final int len = nodes.size();

        StringBuilder sb = new StringBuilder();
        for (UiElementNode node : nodes) {
            sb.append("\n- "); //$NON-NLS-1$
            sb.append(node.getBreadcrumbTrailDescription(false /* include_root */));
        }

        if (MessageDialog.openQuestion(shell,
                len > 1 ? "Remove elements from Android XML"  // title
                        : "Remove element from Android XML",
                String.format("Do you really want to remove %1$s?", sb.toString()))) {
            commitPendingXmlChanges();
            getRootNode().getEditor().wrapEditXmlModel(new Runnable() {
                @Override
                public void run() {
                    UiElementNode previous = null;
                    UiElementNode parent = null;

                    for (int i = len - 1; i >= 0; i--) {
                        UiElementNode node = nodes.get(i);
                        previous = node.getUiPreviousSibling();
                        parent = node.getUiParent();

                        // delete node
                        node.deleteXmlNode();
                    }

                    // try to select the last previous sibling or the last parent
                    if (previous != null) {
                        selectUiNode(previous);
                    } else if (parent != null) {
                        selectUiNode(parent);
                    }
                }
            });
        }
    }

    /**
     * Called when the "Up" button is selected.
     * <p/>
     * If the tree has a selection, move it up, either in the child list or as the last child
     * of the previous parent.
     */
    public void doUp(
            final List<UiElementNode> uiNodes,
            final ElementDescriptor[] descriptorFilters) {
        if (uiNodes == null || uiNodes.size() < 1) {
            return;
        }

        final Node[]          selectXmlNode = { null };
        final UiElementNode[] uiLastNode    = { null };
        final UiElementNode[] uiSearchRoot  = { null };

        commitPendingXmlChanges();
        getRootNode().getEditor().wrapEditXmlModel(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < uiNodes.size(); i++) {
                    UiElementNode uiNode = uiLastNode[0] = uiNodes.get(i);
                    doUpInternal(
                            uiNode,
                            descriptorFilters,
                            selectXmlNode,
                            uiSearchRoot,
                            false /*testOnly*/);
                }
            }
        });

        assert uiLastNode[0] != null; // tell Eclipse this can't be null below

        if (selectXmlNode[0] == null) {
            // The XML node has not been moved, we can just select the same UI node
            selectUiNode(uiLastNode[0]);
        } else {
            // The XML node has moved. At this point the UI model has been reloaded
            // and the XML node has been affected to a new UI node. Find that new UI
            // node and select it.
            if (uiSearchRoot[0] == null) {
                uiSearchRoot[0] = uiLastNode[0].getUiRoot();
            }
            if (uiSearchRoot[0] != null) {
                selectUiNode(uiSearchRoot[0].findXmlNode(selectXmlNode[0]));
            }
        }
    }

    /**
     * Checks whether the "up" action can be performed on all items.
     *
     * @return True if the up action can be carried on *all* items.
     */
    public boolean canDoUp(
            List<UiElementNode> uiNodes,
            ElementDescriptor[] descriptorFilters) {
        if (uiNodes == null || uiNodes.size() < 1) {
            return false;
        }

        final Node[]          selectXmlNode = { null };
        final UiElementNode[] uiSearchRoot  = { null };

        commitPendingXmlChanges();

        for (int i = 0; i < uiNodes.size(); i++) {
            if (!doUpInternal(
                    uiNodes.get(i),
                    descriptorFilters,
                    selectXmlNode,
                    uiSearchRoot,
                    true /*testOnly*/)) {
                return false;
            }
        }

        return true;
    }

    private boolean doUpInternal(
            UiElementNode uiNode,
            ElementDescriptor[] descriptorFilters,
            Node[] outSelectXmlNode,
            UiElementNode[] outUiSearchRoot,
            boolean testOnly) {
        // the node will move either up to its parent or grand-parent
        outUiSearchRoot[0] = uiNode.getUiParent();
        if (outUiSearchRoot[0] != null && outUiSearchRoot[0].getUiParent() != null) {
            outUiSearchRoot[0] = outUiSearchRoot[0].getUiParent();
        }
        Node xmlNode = uiNode.getXmlNode();
        ElementDescriptor nodeDesc = uiNode.getDescriptor();
        if (xmlNode == null || nodeDesc == null) {
            return false;
        }
        UiElementNode uiParentNode = uiNode.getUiParent();
        Node xmlParent = uiParentNode == null ? null : uiParentNode.getXmlNode();
        if (xmlParent == null) {
            return false;
        }

        UiElementNode uiPrev = uiNode.getUiPreviousSibling();

        // Only accept a sibling that has an XML attached and
        // is part of the allowed descriptor filters.
        while (uiPrev != null &&
                (uiPrev.getXmlNode() == null || !matchDescFilter(descriptorFilters, uiPrev))) {
            uiPrev = uiPrev.getUiPreviousSibling();
        }

        if (uiPrev != null && uiPrev.getXmlNode() != null) {
            // This node is not the first one of the parent.
            Node xmlPrev = uiPrev.getXmlNode();
            if (uiPrev.getDescriptor().acceptChild(nodeDesc)) {
                // If the previous sibling can accept this child, then it
                // is inserted at the end of the children list.
                if (testOnly) {
                    return true;
                }
                xmlPrev.appendChild(xmlParent.removeChild(xmlNode));
                outSelectXmlNode[0] = xmlNode;
            } else {
                // This node is not the first one of the parent, so it can be
                // removed and then inserted before its previous sibling.
                if (testOnly) {
                    return true;
                }
                xmlParent.insertBefore(
                        xmlParent.removeChild(xmlNode),
                        xmlPrev);
                outSelectXmlNode[0] = xmlNode;
            }
        } else if (uiParentNode != null && !(xmlParent instanceof Document)) {
            UiElementNode uiGrandParent = uiParentNode.getUiParent();
            Node xmlGrandParent = uiGrandParent == null ? null : uiGrandParent.getXmlNode();
            ElementDescriptor grandDesc =
                uiGrandParent == null ? null : uiGrandParent.getDescriptor();

            if (xmlGrandParent != null &&
                    !(xmlGrandParent instanceof Document) &&
                    grandDesc != null &&
                    grandDesc.acceptChild(nodeDesc)) {
                // If the node is the first one of the child list of its
                // parent, move it up in the hierarchy as previous sibling
                // to the parent. This is only possible if the parent of the
                // parent is not a document.
                // The parent node must actually accept this kind of child.

                if (testOnly) {
                    return true;
                }
                xmlGrandParent.insertBefore(
                        xmlParent.removeChild(xmlNode),
                        xmlParent);
                outSelectXmlNode[0] = xmlNode;
            }
        }

        return false;
    }

    private boolean matchDescFilter(
            ElementDescriptor[] descriptorFilters,
            UiElementNode uiNode) {
        if (descriptorFilters == null || descriptorFilters.length < 1) {
            return true;
        }

        ElementDescriptor desc = uiNode.getDescriptor();

        for (ElementDescriptor filter : descriptorFilters) {
            if (filter.equals(desc)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Called when the "Down" button is selected.
     *
     * If the tree has a selection, move it down, either in the same child list or as the
     * first child of the next parent.
     */
    public void doDown(
            final List<UiElementNode> nodes,
            final ElementDescriptor[] descriptorFilters) {
        if (nodes == null || nodes.size() < 1) {
            return;
        }

        final Node[]          selectXmlNode = { null };
        final UiElementNode[] uiLastNode    = { null };
        final UiElementNode[] uiSearchRoot  = { null };

        commitPendingXmlChanges();
        getRootNode().getEditor().wrapEditXmlModel(new Runnable() {
            @Override
            public void run() {
                for (int i = nodes.size() - 1; i >= 0; i--) {
                    final UiElementNode node = uiLastNode[0] = nodes.get(i);
                    doDownInternal(
                            node,
                            descriptorFilters,
                            selectXmlNode,
                            uiSearchRoot,
                            false /*testOnly*/);
                }
            }
        });

        assert uiLastNode[0] != null; // tell Eclipse this can't be null below

        if (selectXmlNode[0] == null) {
            // The XML node has not been moved, we can just select the same UI node
            selectUiNode(uiLastNode[0]);
        } else {
            // The XML node has moved. At this point the UI model has been reloaded
            // and the XML node has been affected to a new UI node. Find that new UI
            // node and select it.
            if (uiSearchRoot[0] == null) {
                uiSearchRoot[0] = uiLastNode[0].getUiRoot();
            }
            if (uiSearchRoot[0] != null) {
                selectUiNode(uiSearchRoot[0].findXmlNode(selectXmlNode[0]));
            }
        }
    }

    /**
     * Checks whether the "down" action can be performed on all items.
     *
     * @return True if the down action can be carried on *all* items.
     */
    public boolean canDoDown(
            List<UiElementNode> uiNodes,
            ElementDescriptor[] descriptorFilters) {
        if (uiNodes == null || uiNodes.size() < 1) {
            return false;
        }

        final Node[]          selectXmlNode = { null };
        final UiElementNode[] uiSearchRoot  = { null };

        commitPendingXmlChanges();

        for (int i = 0; i < uiNodes.size(); i++) {
            if (!doDownInternal(
                    uiNodes.get(i),
                    descriptorFilters,
                    selectXmlNode,
                    uiSearchRoot,
                    true /*testOnly*/)) {
                return false;
            }
        }

        return true;
    }

    private boolean doDownInternal(
            UiElementNode uiNode,
            ElementDescriptor[] descriptorFilters,
            Node[] outSelectXmlNode,
            UiElementNode[] outUiSearchRoot,
            boolean testOnly) {
        // the node will move either down to its parent or grand-parent
        outUiSearchRoot[0] = uiNode.getUiParent();
        if (outUiSearchRoot[0] != null && outUiSearchRoot[0].getUiParent() != null) {
            outUiSearchRoot[0] = outUiSearchRoot[0].getUiParent();
        }

        Node xmlNode = uiNode.getXmlNode();
        ElementDescriptor nodeDesc = uiNode.getDescriptor();
        if (xmlNode == null || nodeDesc == null) {
            return false;
        }
        UiElementNode uiParentNode = uiNode.getUiParent();
        Node xmlParent = uiParentNode == null ? null : uiParentNode.getXmlNode();
        if (xmlParent == null) {
            return false;
        }

        UiElementNode uiNext = uiNode.getUiNextSibling();

        // Only accept a sibling that has an XML attached and
        // is part of the allowed descriptor filters.
        while (uiNext != null &&
                (uiNext.getXmlNode() == null || !matchDescFilter(descriptorFilters, uiNext))) {
            uiNext = uiNext.getUiNextSibling();
        }

        if (uiNext != null && uiNext.getXmlNode() != null) {
            // This node is not the last one of the parent.
            Node xmlNext = uiNext.getXmlNode();
            // If the next sibling is a node that can have children, though,
            // then the node is inserted as the first child.
            if (uiNext.getDescriptor().acceptChild(nodeDesc)) {
                if (testOnly) {
                    return true;
                }
                // Note: insertBefore works as append if the ref node is
                // null, i.e. when the node doesn't have children yet.
                xmlNext.insertBefore(
                        xmlParent.removeChild(xmlNode),
                        xmlNext.getFirstChild());
                outSelectXmlNode[0] = xmlNode;
            } else {
                // This node is not the last one of the parent, so it can be
                // removed and then inserted after its next sibling.

                if (testOnly) {
                    return true;
                }
                // Insert "before after next" ;-)
                xmlParent.insertBefore(
                        xmlParent.removeChild(xmlNode),
                        xmlNext.getNextSibling());
                outSelectXmlNode[0] = xmlNode;
            }
        } else if (uiParentNode != null && !(xmlParent instanceof Document)) {
            UiElementNode uiGrandParent = uiParentNode.getUiParent();
            Node xmlGrandParent = uiGrandParent == null ? null : uiGrandParent.getXmlNode();
            ElementDescriptor grandDesc =
                uiGrandParent == null ? null : uiGrandParent.getDescriptor();

            if (xmlGrandParent != null &&
                    !(xmlGrandParent instanceof Document) &&
                    grandDesc != null &&
                    grandDesc.acceptChild(nodeDesc)) {
                // This node is the last node of its parent.
                // If neither the parent nor the grandparent is a document,
                // then the node can be inserted right after the parent.
                // The parent node must actually accept this kind of child.
                if (testOnly) {
                    return true;
                }
                xmlGrandParent.insertBefore(
                        xmlParent.removeChild(xmlNode),
                        xmlParent.getNextSibling());
                outSelectXmlNode[0] = xmlNode;
            }
        }

        return false;
    }

    //---------------------

    /**
     * Adds a new element of the given descriptor's type to the given UI parent node.
     *
     * This actually creates the corresponding XML node in the XML model, which in turn
     * will refresh the current tree view.
     *
     * @param uiParent An existing UI node or null to add to the tree root
     * @param uiSibling An existing UI node to insert right before. Can be null.
     * @param descriptor The descriptor of the element to add
     * @param updateLayout True if layout attributes should be set
     * @return The {@link UiElementNode} that has been added to the UI tree.
     */
    private UiElementNode addNewTreeElement(UiElementNode uiParent,
            UiElementNode uiSibling,
            ElementDescriptor descriptor,
            final boolean updateLayout) {
        commitPendingXmlChanges();

        List<UiElementNode> uiChildren = uiParent.getUiChildren();
        int n = uiChildren.size();

        // The default is to append at the end of the list.
        int index = n;

        if (uiSibling != null) {
            // Try to find the requested sibling.
            index = uiChildren.indexOf(uiSibling);
            if (index < 0) {
                // This sibling didn't exist. Should not happen but compensate
                // by simply adding to the end of the list.
                uiSibling = null;
                index = n;
            }
        }

        if (uiSibling == null) {
            // If we don't require any specific position, make sure to insert before the
            // first mandatory_last descriptor's position, if any.

            for (int i = 0; i < n; i++) {
                UiElementNode uiChild = uiChildren.get(i);
                if (uiChild.getDescriptor().getMandatory() == Mandatory.MANDATORY_LAST) {
                    index = i;
                    break;
                }
            }
        }

        final UiElementNode uiNew = uiParent.insertNewUiChild(index, descriptor);
        UiElementNode rootNode = getRootNode();

        rootNode.getEditor().wrapEditXmlModel(new Runnable() {
            @Override
            public void run() {
                DescriptorsUtils.setDefaultLayoutAttributes(uiNew, updateLayout);
                uiNew.createXmlNode();
            }
        });
        return uiNew;
    }
}
