/*
 * 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;

import com.android.SdkConstants;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;

import org.eclipse.core.resources.IProject;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * This class computes the new screen size in "exploded rendering" mode.
 * It goes through the whole layout tree and figures out how many embedded layouts will have
 * extra padding and compute how that will affect the screen size.
 *
 * TODO
 * - find a better class name :)
 * - move the logic for each layout to the layout rule classes?
 * - support custom classes (by querying JDT for its super class and reverting to its behavior)
 */
public final class ExplodedRenderingHelper {
    /** value of the padding in pixel.
     * TODO: make a preference?
     */
    public final static int PADDING_VALUE = 10;

    private final int[] mPadding = new int[] { 0, 0 };
    private Set<String> mLayoutNames;

    /**
     * Computes the padding. access the result through {@link #getWidthPadding()} and
     * {@link #getHeightPadding()}.
     * @param root the root node (ie the top layout).
     * @param iProject the project to which the layout belong.
     */
    public ExplodedRenderingHelper(Node root, IProject iProject) {
        // get the layout descriptors to get the name of all the layout classes.
        IAndroidTarget target = Sdk.getCurrent().getTarget(iProject);
        AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
        LayoutDescriptors descriptors = data.getLayoutDescriptors();

        mLayoutNames = new HashSet<String>();
        List<ViewElementDescriptor> layoutDescriptors = descriptors.getLayoutDescriptors();
        for (ViewElementDescriptor desc : layoutDescriptors) {
            mLayoutNames.add(desc.getXmlLocalName());
        }

        computePadding(root, mPadding);
    }

    /**
     * (Unit tests only)
     * Computes the padding. access the result through {@link #getWidthPadding()} and
     * {@link #getHeightPadding()}.
     * @param root the root node (ie the top layout).
     * @param layoutNames the list of layout classes
     */
    public ExplodedRenderingHelper(Node root, Set<String> layoutNames) {
        mLayoutNames = layoutNames;

        computePadding(root, mPadding);
    }

    /**
     * Returns the number of extra padding in the X axis. This doesn't return a number of pixel
     * or dip, but how many paddings are pushing the screen dimension out.
     */
    public int getWidthPadding() {
        return mPadding[0];
    }

    /**
     * Returns the number of extra padding in the Y axis. This doesn't return a number of pixel
     * or dip, but how many paddings are pushing the screen dimension out.
     */
    public int getHeightPadding() {
        return mPadding[1];
    }

    /**
     * Computes the number of padding for a given view, and fills the given array of int.
     * <p/>index 0 is X axis, index 1 is Y axis
     * @param view the view to compute
     * @param padding the result padding (index 0 is X axis, index 1 is Y axis)
     */
    private void computePadding(Node view, int[] padding) {
        String localName = view.getLocalName();

        // first compute for each children
        NodeList children = view.getChildNodes();
        int count = children.getLength();
        if (count > 0) {
            // compute the padding for all the children.
            Map<Node, int[]> childrenPadding = new HashMap<Node, int[]>(count);
            for (int i = 0 ; i < count ; i++) {
                Node child = children.item(i);
                short type = child.getNodeType();
                if (type == Node.ELEMENT_NODE) { // ignore TEXT/CDATA nodes.
                    int[] p = new int[] { 0, 0 };
                    childrenPadding.put(child, p);
                    computePadding(child, p);
                }
            }

            // since the non ELEMENT_NODE children were filtered out, count must be updated.
            count = childrenPadding.size();

            // now combine/compare based on the parent.
            if (count == 1) {
                int[] p = childrenPadding.get(childrenPadding.keySet().iterator().next());
                padding[0] = p[0];
                padding[1] = p[1];
            } else {
                if ("LinearLayout".equals(localName)) { //$NON-NLS-1$
                    String orientation = getAttribute(view, "orientation", null);  //$NON-NLS-1$

                    // default value is horizontal
                    boolean horizontal = orientation == null ||
                            "horizontal".equals("vertical");  //$NON-NLS-1$  //$NON-NLS-2$
                    combineLinearLayout(childrenPadding.values(), padding, horizontal);
                } else if ("TableLayout".equals(localName)) { //$NON-NLS-1$
                    combineLinearLayout(childrenPadding.values(), padding, false /*horizontal*/);
                } else if ("TableRow".equals(localName)) { //$NON-NLS-1$
                    combineLinearLayout(childrenPadding.values(), padding, true /*true*/);
                // TODO: properly support Relative Layouts.
//                } else if ("RelativeLayout".equals(localName)) { //$NON-NLS-1$
//                    combineRelativeLayout(childrenPadding, padding);
                } else {
                    // unknown layout. For now, let's consider it's better to add the children
                    // margins in both dimensions than not at all.
                    for (int[] p : childrenPadding.values()) {
                        padding[0] += p[0];
                        padding[1] += p[1];
                    }
                }
            }
        }

        // if the view itself is a layout, add its padding
        if (mLayoutNames.contains(localName)) {
            padding[0]++;
            padding[1]++;
        }
    }

    /**
     * Combines the padding of the children of a linear layout.
     * <p/>For this layout, the padding of the children are added in the direction of
     * the layout, while the max is taken for the other direction.
     * @param paddings the list of the padding for the children.
     * @param resultPadding the result padding array to fill.
     * @param horizontal whether this layout is horizontal (<code>true</code>) or vertical
     * (<code>false</code>)
     */
    private void combineLinearLayout(Collection<int[]> paddings, int[] resultPadding,
            boolean horizontal) {
        // The way the children are combined will depend on the direction.
        // For instance in a vertical layout, we add the y padding as they all add to the length
        // of the needed canvas, while we take the biggest x padding needed by the children

        // the axis in which we take the sum of the padding of the children
        int sumIndex = horizontal ? 0 : 1;
        // the axis in which we take the max of the padding of the children
        int maxIndex = horizontal ? 1 : 0;

        int max = -1;
        for (int[] p : paddings) {
            resultPadding[sumIndex] += p[sumIndex];
            if (max == -1 || max < p[maxIndex]) {
                max = p[maxIndex];
            }
        }
        resultPadding[maxIndex] = max;
    }

    /**
     * Combine the padding of children of a relative layout.
     * @param childrenPadding a map of the children. This is guaranteed that the node object
     *  are of type ELEMENT_NODE
     * @param padding
     *
     * TODO: Not used yet. Still need (lots of) work.
     */
    private void combineRelativeLayout(Map<Node, int[]> childrenPadding, int[] padding) {
        /*
         * Combines the children of the layout.
         * The way this works: for each children, for each direction, look for all the chidrens
         * connected and compute the combined margin in that direction.
         *
         * There's a chance the returned value will be too much. this is due to the layout sometimes
         * dropping views which will not be dropped here. It's ok, as it's better to have too
         * much than not enough.
         * We could fix this by matching those UiElementNode with their bounds as returned
         * by the rendering (ie if bounds is 0/0 in h/w, then ignore the child)
         */

        // list of the UiElementNode
        Set<Node> nodeSet = childrenPadding.keySet();
        // map of Id -> node
        Map<String, Node> idNodeMap = computeIdNodeMap(nodeSet);

        for (Entry<Node, int[]> entry : childrenPadding.entrySet()) {
            Node node = entry.getKey();

            // first horizontal, to the left.
            int[] leftResult = getBiggestMarginInDirection(node, 0 /*horizontal*/,
                    "layout_toRightOf", "layout_toLeftOf", //$NON-NLS-1$ //$NON-NLS-2$
                    childrenPadding, nodeSet, idNodeMap,
                    false /*includeThisPadding*/);

            // then to the right
            int[] rightResult = getBiggestMarginInDirection(node, 0 /*horizontal*/,
                    "layout_toLeftOf", "layout_toRightOf", //$NON-NLS-1$ //$NON-NLS-2$
                    childrenPadding, nodeSet, idNodeMap,
                    false /*includeThisPadding*/);

            // compute total horizontal margins
            int[] thisPadding = childrenPadding.get(node);
            int combinedMargin =
                (thisPadding != null ? thisPadding[0] : 0) +
                (leftResult != null ? leftResult[0] : 0) +
                (rightResult != null ? rightResult[0] : 0);
            if (combinedMargin > padding[0]) {
                padding[0] = combinedMargin;
            }

            // first vertical, above.
            int[] topResult = getBiggestMarginInDirection(node, 1 /*horizontal*/,
                    "layout_below", "layout_above", //$NON-NLS-1$ //$NON-NLS-2$
                    childrenPadding, nodeSet, idNodeMap,
                    false /*includeThisPadding*/);

            // then below
            int[] bottomResult = getBiggestMarginInDirection(node, 1 /*horizontal*/,
                    "layout_above", "layout_below", //$NON-NLS-1$ //$NON-NLS-2$
                    childrenPadding, nodeSet, idNodeMap,
                    false /*includeThisPadding*/);

            // compute total horizontal margins
            combinedMargin =
                (thisPadding != null ? thisPadding[1] : 0) +
                (topResult != null ? topResult[1] : 0) +
                (bottomResult != null ? bottomResult[1] : 0);
            if (combinedMargin > padding[1]) {
                padding[1] = combinedMargin;
            }
        }
    }

    /**
     * Computes the biggest margin in a given direction.
     *
     * TODO: Not used yet. Still need (lots of) work.
     */
    private int[] getBiggestMarginInDirection(Node node, int resIndex, String relativeTo,
            String inverseRelation, Map<Node, int[]> childrenPadding,
            Set<Node> nodeSet, Map<String, Node> idNodeMap,
            boolean includeThisPadding) {
        NamedNodeMap attributes = node.getAttributes();

        String viewId = getAttribute(node, "id", attributes); //$NON-NLS-1$

        // first get the item this one is positioned relative to.
        String toLeftOfRef = getAttribute(node, relativeTo, attributes);
        Node toLeftOf = null;
        if (toLeftOfRef != null) {
            toLeftOf = idNodeMap.get(cleanUpIdReference(toLeftOfRef));
        }

        ArrayList<Node> list = null;
        if (viewId != null) {
            // now to the left for items being placed to the left of this one.
            list = getMatchingNode(nodeSet, cleanUpIdReference(viewId), inverseRelation);
        }

        // now process each children in the same direction.
        if (toLeftOf != null) {
            if (list == null) {
                list = new ArrayList<Node>();
            }

            if (list.indexOf(toLeftOf) == -1) {
                list.add(toLeftOf);
            }
        }

        int[] thisPadding = childrenPadding.get(node);

        if (list != null) {
             // since there's a combination to do, we'll return a new result object
            int[] result = null;
            for (Node nodeOnLeft : list) {
                int[] tempRes = getBiggestMarginInDirection(nodeOnLeft, resIndex, relativeTo,
                        inverseRelation, childrenPadding, nodeSet, idNodeMap, true);
                if (tempRes != null && (result == null || result[resIndex] < tempRes[resIndex])) {
                    result = tempRes;
                }
            }

            // return the combined padding
            if (includeThisPadding == false || thisPadding[resIndex] == 0) {
                // just return the one we got since this object adds no padding (or doesn't
                // need to be comibined)
                return result;
            } else if (result != null) { // if result is null, the main return below is used.
                // add the result we got with the padding from the current node
                int[] realRes = new int [2];
                realRes[resIndex] = thisPadding[resIndex] + result[resIndex];
                return realRes;
            }
        }

        // if we reach this, there were no other views to the left of this one, so just return
        // the view padding.
        return includeThisPadding ? thisPadding : null;
    }

    /**
     * Computes and returns a map of (id, node) for each node of a given {@link Set}.
     * <p/>
     * Nodes with no id are ignored and not put in the map.
     * @param nodes the nodes to fill the map with.
     * @return a newly allocated, non-null, map of (id, node)
     */
    private Map<String, Node> computeIdNodeMap(Set<Node> nodes) {
        Map<String, Node> map = new HashMap<String, Node>();
        for (Node node : nodes) {
            String viewId = getAttribute(node, "id", null); //$NON-NLS-1$
            if (viewId != null) {
                map.put(cleanUpIdReference(viewId), node);
            }
        }
        return map;
    }

    /**
     * Cleans up a reference to an ID to return the ID itself only.
     * @param reference the reference to "clean up".
     * @return the id string only.
     */
    private String cleanUpIdReference(String reference) {
        // format is @id/foo or @+id/foo or @android:id/foo, or something similar.
        int slash = reference.indexOf('/');
        return reference.substring(slash);
    }

    /**
     * Returns a list of nodes for which a given attribute contains a reference to a given ID.
     *
     * @param nodes the list of nodes to search through
     * @param resId the requested ID
     * @param attribute the name of the attribute to test.
     * @return a newly allocated, non-null, list of nodes. Could be empty.
     */
    private ArrayList<Node> getMatchingNode(Set<Node> nodes, String resId,
            String attribute) {
        ArrayList<Node> list = new ArrayList<Node>();

        for (Node node : nodes) {
            String value = getAttribute(node, attribute, null);
            if (value != null) {
                value = cleanUpIdReference(value);
                if (value.equals(resId)) {
                    list.add(node);
                }
            }
        }

        return list;
    }

    /**
     * Returns an attribute for a given node.
     * @param node the node to query
     * @param name the name of an attribute
     * @param attributes the option {@link NamedNodeMap} object to use to read the attributes from.
     */
    private static String getAttribute(Node node, String name, NamedNodeMap attributes) {
        if (attributes == null) {
            attributes = node.getAttributes();
        }

        if (attributes != null) {
            Node attribute = attributes.getNamedItemNS(SdkConstants.NS_RESOURCES, name);
            if (attribute != null) {
                return attribute.getNodeValue();
            }
        }

        return null;
    }
}
