/*
 * Copyright (C) 2009 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.layout.gre;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.IAttributeInfo;
import com.android.ide.common.api.INode;
import com.android.ide.common.api.INodeHandler;
import com.android.ide.common.api.Margins;
import com.android.ide.common.api.Rect;
import com.android.ide.common.resources.platform.AttributeInfo;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
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.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SimpleAttribute;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SwtUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ViewHierarchy;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.project.SupportLibraryHelper;

import org.eclipse.core.resources.IProject;
import org.eclipse.swt.graphics.Rectangle;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

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

/**
 *
 */
public class NodeProxy implements INode {
    private static final Margins NO_MARGINS = new Margins(0, 0, 0, 0);
    private final UiViewElementNode mNode;
    private final Rect mBounds;
    private final NodeFactory mFactory;
    /** Map from URI to Map(key=>value) (where no namespace uses "" as a key) */
    private Map<String, Map<String, String>> mPendingAttributes;

    /**
     * Creates a new {@link INode} that wraps an {@link UiViewElementNode} that is
     * actually valid in the current UI/XML model. The view may not be part of the canvas
     * yet (e.g. if it has just been dynamically added and the canvas hasn't reloaded yet.)
     * <p/>
     * This method is package protected. To create a node, please use {@link NodeFactory} instead.
     *
     * @param uiNode The node to wrap.
     * @param bounds The bounds of a the view in the canvas. Must be either: <br/>
     *   - a valid rect for a view that is actually in the canvas <br/>
     *   - <b>*or*</b> null (or an invalid rect) for a view that has just been added dynamically
     *   to the model. We never store a null bounds rectangle in the node, a null rectangle
     *   will be converted to an invalid rectangle.
     * @param factory A {@link NodeFactory} to create unique children nodes.
     */
    /*package*/ NodeProxy(UiViewElementNode uiNode, Rectangle bounds, NodeFactory factory) {
        mNode = uiNode;
        mFactory = factory;
        if (bounds == null) {
            mBounds = new Rect();
        } else {
            mBounds = SwtUtils.toRect(bounds);
        }
    }

    @Override
    public @NonNull Rect getBounds() {
        return mBounds;
    }

    @Override
    public @NonNull Margins getMargins() {
        ViewHierarchy viewHierarchy = mFactory.getCanvas().getViewHierarchy();
        CanvasViewInfo view = viewHierarchy.findViewInfoFor(this);
        if (view != null) {
            Margins margins = view.getMargins();
            if (margins != null) {
                return margins;
            }
        }

        return NO_MARGINS;
    }


    @Override
    public int getBaseline() {
        ViewHierarchy viewHierarchy = mFactory.getCanvas().getViewHierarchy();
        CanvasViewInfo view = viewHierarchy.findViewInfoFor(this);
        if (view != null) {
            return view.getBaseline();
        }

        return -1;
    }

    /**
     * Updates the bounds of this node proxy. Bounds cannot be null, but it can be invalid.
     * This is a package-protected method, only the {@link NodeFactory} uses this method.
     */
    /*package*/ void setBounds(Rectangle bounds) {
        SwtUtils.set(mBounds, bounds);
    }

    /**
     * Returns the {@link UiViewElementNode} corresponding to this
     * {@link NodeProxy}.
     *
     * @return The {@link UiViewElementNode} corresponding to this
     *         {@link NodeProxy}
     */
    public UiViewElementNode getNode() {
        return mNode;
    }

    @Override
    public @NonNull String getFqcn() {
        if (mNode != null) {
            ElementDescriptor desc = mNode.getDescriptor();
            if (desc instanceof ViewElementDescriptor) {
                return ((ViewElementDescriptor) desc).getFullClassName();
            }
        }

        return "";
    }


    // ---- Hierarchy handling ----


    @Override
    public INode getRoot() {
        if (mNode != null) {
            UiElementNode p = mNode.getUiRoot();
            // The node root should be a document. Instead what we really mean to
            // return is the top level view element.
            if (p instanceof UiDocumentNode) {
                List<UiElementNode> children = p.getUiChildren();
                if (children.size() > 0) {
                    p = children.get(0);
                }
            }

            // Cope with a badly structured XML layout
            while (p != null && !(p instanceof UiViewElementNode)) {
                p = p.getUiNextSibling();
            }

            if (p == mNode) {
                return this;
            }
            if (p instanceof UiViewElementNode) {
                return mFactory.create((UiViewElementNode) p);
            }
        }

        return null;
    }

    @Override
    public INode getParent() {
        if (mNode != null) {
            UiElementNode p = mNode.getUiParent();
            if (p instanceof UiViewElementNode) {
                return mFactory.create((UiViewElementNode) p);
            }
        }

        return null;
    }

    @Override
    public @NonNull INode[] getChildren() {
        if (mNode != null) {
            List<UiElementNode> uiChildren = mNode.getUiChildren();
            List<INode> nodes = new ArrayList<INode>(uiChildren.size());
            for (UiElementNode uiChild : uiChildren) {
                if (uiChild instanceof UiViewElementNode) {
                    nodes.add(mFactory.create((UiViewElementNode) uiChild));
                }
            }

            return nodes.toArray(new INode[nodes.size()]);
        }

        return new INode[0];
    }


    // ---- XML Editing ---

    @Override
    public void editXml(@NonNull String undoName, final @NonNull INodeHandler c) {
        final AndroidXmlEditor editor = mNode.getEditor();

        if (editor != null) {
            // Create an undo edit XML wrapper, which takes a runnable
            editor.wrapUndoEditXmlModel(
                    undoName,
                    new Runnable() {
                        @Override
                        public void run() {
                            // Here editor.isEditXmlModelPending returns true and it
                            // is safe to edit the model using any method from INode.

                            // Finally execute the closure that will act on the XML
                            c.handle(NodeProxy.this);
                            applyPendingChanges();
                        }
                    });
        }
    }

    private void checkEditOK() {
        final AndroidXmlEditor editor = mNode.getEditor();
        if (!editor.isEditXmlModelPending()) {
            throw new RuntimeException("Error: XML edit call without using INode.editXml!");
        }
    }

    @Override
    public @NonNull INode appendChild(@NonNull String viewFqcn) {
        return insertOrAppend(viewFqcn, -1);
    }

    @Override
    public @NonNull INode insertChildAt(@NonNull String viewFqcn, int index) {
        return insertOrAppend(viewFqcn, index);
    }

    @Override
    public void removeChild(@NonNull INode node) {
        checkEditOK();

        ((NodeProxy) node).mNode.deleteXmlNode();
    }

    private INode insertOrAppend(String viewFqcn, int index) {
        checkEditOK();

        AndroidXmlEditor editor = mNode.getEditor();
        if (editor != null) {
            // Possibly replace the tag with a compatibility version if the
            // minimum SDK requires it
            IProject project = editor.getProject();
            if (project != null) {
                viewFqcn = SupportLibraryHelper.getTagFor(project, viewFqcn);
            }
        }

        // Find the descriptor for this FQCN
        ViewElementDescriptor vd = getFqcnViewDescriptor(viewFqcn);
        if (vd == null) {
            warnPrintf("Can't create a new %s element", viewFqcn);
            return null;
        }

        final UiElementNode uiNew;
        if (index == -1) {
            // Append at the end.
            uiNew = mNode.appendNewUiChild(vd);
        } else {
            // Insert at the requested position or at the end.
            int n = mNode.getUiChildren().size();
            if (index < 0 || index >= n) {
                uiNew = mNode.appendNewUiChild(vd);
            } else {
                uiNew = mNode.insertNewUiChild(index, vd);
            }
        }

        // Set default attributes -- but only for new widgets (not when moving or copying)
        RulesEngine engine = null;
        LayoutEditorDelegate delegate = LayoutEditorDelegate.fromEditor(editor);
        if (delegate != null) {
            engine = delegate.getRulesEngine();
        }
        if (engine == null || engine.getInsertType().isCreate()) {
            // TODO: This should probably use IViewRule#getDefaultAttributes() at some point
            DescriptorsUtils.setDefaultLayoutAttributes(uiNew, false /*updateLayout*/);
        }

        Node xmlNode = uiNew.createXmlNode();

        if (!(uiNew instanceof UiViewElementNode) || xmlNode == null) {
            // Both things are not supposed to happen. When they do, we're in big trouble.
            // We don't really know how to revert the state at this point and the UI model is
            // now out of sync with the XML model.
            // Panic ensues.
            // The best bet is to abort now. The edit wrapper will release the edit and the
            // XML/UI should get reloaded properly (with a likely invalid XML.)
            warnPrintf("Failed to create a new %s element", viewFqcn);
            throw new RuntimeException("XML node creation failed."); //$NON-NLS-1$
        }

        UiViewElementNode uiNewView = (UiViewElementNode) uiNew;
        NodeProxy newNode = mFactory.create(uiNewView);

        if (engine != null) {
            engine.callCreateHooks(editor, this, newNode, null);
        }

        return newNode;
    }

    @Override
    public boolean setAttribute(
            @Nullable String uri,
            @NonNull String name,
            @Nullable String value) {
        checkEditOK();
        UiAttributeNode attr = mNode.setAttributeValue(name, uri, value, true /* override */);

        if (uri == null) {
            uri = ""; //$NON-NLS-1$
        }

        Map<String, String> map = null;
        if (mPendingAttributes == null) {
            // Small initial size: we don't expect many different namespaces
            mPendingAttributes = new HashMap<String, Map<String, String>>(3);
        } else {
            map = mPendingAttributes.get(uri);
        }
        if (map == null) {
            map = new HashMap<String, String>();
            mPendingAttributes.put(uri, map);
        }
        map.put(name, value);

        return attr != null;
    }

    @Override
    public String getStringAttr(@Nullable String uri, @NonNull String attrName) {
        UiElementNode uiNode = mNode;

        if (attrName == null) {
            return null;
        }

        if (mPendingAttributes != null) {
            Map<String, String> map = mPendingAttributes.get(uri == null ? "" : uri); //$NON-NLS-1$
            if (map != null) {
                String value = map.get(attrName);
                if (value != null) {
                    return value;
                }
            }
        }

        if (uiNode.getXmlNode() != null) {
            Node xmlNode = uiNode.getXmlNode();
            if (xmlNode != null) {
                NamedNodeMap nodeAttributes = xmlNode.getAttributes();
                if (nodeAttributes != null) {
                    Node attr = nodeAttributes.getNamedItemNS(uri, attrName);
                    if (attr != null) {
                        return attr.getNodeValue();
                    }
                }
            }
        }
        return null;
    }

    @Override
    public IAttributeInfo getAttributeInfo(@Nullable String uri, @NonNull String attrName) {
        UiElementNode uiNode = mNode;

        if (attrName == null) {
            return null;
        }

        for (AttributeDescriptor desc : uiNode.getAttributeDescriptors()) {
            String dUri = desc.getNamespaceUri();
            String dName = desc.getXmlLocalName();
            if ((uri == null && dUri == null) || (uri != null && uri.equals(dUri))) {
                if (attrName.equals(dName)) {
                    return desc.getAttributeInfo();
                }
            }
        }

        return null;
    }

    @Override
    public @NonNull IAttributeInfo[] getDeclaredAttributes() {

        AttributeDescriptor[] descs = mNode.getAttributeDescriptors();
        int n = descs.length;
        IAttributeInfo[] infos = new AttributeInfo[n];

        for (int i = 0; i < n; i++) {
            infos[i] = descs[i].getAttributeInfo();
        }

        return infos;
    }

    @Override
    public @NonNull List<String> getAttributeSources() {
        ElementDescriptor descriptor = mNode.getDescriptor();
        if (descriptor instanceof ViewElementDescriptor) {
            return ((ViewElementDescriptor) descriptor).getAttributeSources();
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public @NonNull IAttribute[] getLiveAttributes() {
        UiElementNode uiNode = mNode;

        if (uiNode.getXmlNode() != null) {
            Node xmlNode = uiNode.getXmlNode();
            if (xmlNode != null) {
                NamedNodeMap nodeAttributes = xmlNode.getAttributes();
                if (nodeAttributes != null) {

                    int n = nodeAttributes.getLength();
                    IAttribute[] result = new IAttribute[n];
                    for (int i = 0; i < n; i++) {
                        Node attr = nodeAttributes.item(i);
                        String uri = attr.getNamespaceURI();
                        String name = attr.getLocalName();
                        String value = attr.getNodeValue();

                        result[i] = new SimpleAttribute(uri, name, value);
                    }
                    return result;
                }
            }
        }

        return new IAttribute[0];

    }

    @Override
    public String toString() {
        return "NodeProxy [node=" + mNode + ", bounds=" + mBounds + "]";
    }

    // --- internal helpers ---

    /**
     * Helper methods that returns a {@link ViewElementDescriptor} for the requested FQCN.
     * Will return null if we can't find that FQCN or we lack the editor/data/descriptors info
     * (which shouldn't really happen since at this point the SDK should be fully loaded and
     * isn't reloading, or we wouldn't be here editing XML for a layout rule.)
     */
    private ViewElementDescriptor getFqcnViewDescriptor(String fqcn) {
        LayoutEditorDelegate delegate = LayoutEditorDelegate.fromEditor(mNode.getEditor());
        if (delegate != null) {
            return delegate.getFqcnViewDescriptor(fqcn);
        }

        return null;
    }

    private void warnPrintf(String msg, Object...params) {
        AdtPlugin.printToConsole(
                mNode == null ? "" : mNode.getDescriptor().getXmlLocalName(),
                String.format(msg, params)
                );
    }

    /**
     * If there are any pending changes in these nodes, apply them now
     *
     * @return true if any modifications were made
     */
    public boolean applyPendingChanges() {
        boolean modified = false;

        // Flush all pending attributes
        if (mPendingAttributes != null) {
            mNode.commitDirtyAttributesToXml();
            modified = true;
            mPendingAttributes = null;

        }
        for (INode child : getChildren()) {
            modified |= ((NodeProxy) child).applyPendingChanges();
        }

        return modified;
    }
}
