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

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_GRAVITY;
import static com.android.SdkConstants.ATTR_LAYOUT_ABOVE;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_BASELINE;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_BOTTOM;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_LEFT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_BOTTOM;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_LEFT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_RIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_PARENT_TOP;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_RIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_TOP;
import static com.android.SdkConstants.ATTR_LAYOUT_ALIGN_WITH_PARENT_MISSING;
import static com.android.SdkConstants.ATTR_LAYOUT_BELOW;
import static com.android.SdkConstants.ATTR_LAYOUT_CENTER_HORIZONTAL;
import static com.android.SdkConstants.ATTR_LAYOUT_CENTER_IN_PARENT;
import static com.android.SdkConstants.ATTR_LAYOUT_CENTER_VERTICAL;
import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
import static com.android.SdkConstants.ATTR_LAYOUT_TO_LEFT_OF;
import static com.android.SdkConstants.ATTR_LAYOUT_TO_RIGHT_OF;
import static com.android.SdkConstants.VALUE_TRUE;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.DropFeedback;
import com.android.ide.common.api.IDragElement;
import com.android.ide.common.api.IGraphics;
import com.android.ide.common.api.IMenuCallback;
import com.android.ide.common.api.INode;
import com.android.ide.common.api.INodeHandler;
import com.android.ide.common.api.IViewRule;
import com.android.ide.common.api.InsertType;
import com.android.ide.common.api.Point;
import com.android.ide.common.api.Rect;
import com.android.ide.common.api.RuleAction;
import com.android.ide.common.api.SegmentType;
import com.android.ide.common.layout.relative.ConstraintPainter;
import com.android.ide.common.layout.relative.DeletionHandler;
import com.android.ide.common.layout.relative.GuidelinePainter;
import com.android.ide.common.layout.relative.MoveHandler;
import com.android.ide.common.layout.relative.ResizeHandler;
import com.android.utils.Pair;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * An {@link IViewRule} for android.widget.RelativeLayout and all its derived
 * classes.
 */
public class RelativeLayoutRule extends BaseLayoutRule {
    private static final String ACTION_SHOW_STRUCTURE = "_structure"; //$NON-NLS-1$
    private static final String ACTION_SHOW_CONSTRAINTS = "_constraints"; //$NON-NLS-1$
    private static final String ACTION_CENTER_VERTICAL = "_centerVert"; //$NON-NLS-1$
    private static final String ACTION_CENTER_HORIZONTAL = "_centerHoriz"; //$NON-NLS-1$
    private static final URL ICON_CENTER_VERTICALLY =
        RelativeLayoutRule.class.getResource("centerVertically.png"); //$NON-NLS-1$
    private static final URL ICON_CENTER_HORIZONTALLY =
        RelativeLayoutRule.class.getResource("centerHorizontally.png"); //$NON-NLS-1$
    private static final URL ICON_SHOW_STRUCTURE =
        BaseLayoutRule.class.getResource("structure.png"); //$NON-NLS-1$
    private static final URL ICON_SHOW_CONSTRAINTS =
        BaseLayoutRule.class.getResource("constraints.png"); //$NON-NLS-1$

    public static boolean sShowStructure = false;
    public static boolean sShowConstraints = true;

    // ==== Selection ====

    @Override
    public List<String> getSelectionHint(@NonNull INode parentNode, @NonNull INode childNode) {
        List<String> infos = new ArrayList<String>(18);
        addAttr(ATTR_LAYOUT_ABOVE, childNode, infos);
        addAttr(ATTR_LAYOUT_BELOW, childNode, infos);
        addAttr(ATTR_LAYOUT_TO_LEFT_OF, childNode, infos);
        addAttr(ATTR_LAYOUT_TO_RIGHT_OF, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_BASELINE, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_TOP, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_BOTTOM, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_LEFT, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_RIGHT, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_PARENT_TOP, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_PARENT_BOTTOM, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_PARENT_LEFT, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_PARENT_RIGHT, childNode, infos);
        addAttr(ATTR_LAYOUT_ALIGN_WITH_PARENT_MISSING, childNode, infos);
        addAttr(ATTR_LAYOUT_CENTER_HORIZONTAL, childNode, infos);
        addAttr(ATTR_LAYOUT_CENTER_IN_PARENT, childNode, infos);
        addAttr(ATTR_LAYOUT_CENTER_VERTICAL, childNode, infos);

        return infos;
    }

    private void addAttr(String propertyName, INode childNode, List<String> infos) {
        String a = childNode.getStringAttr(ANDROID_URI, propertyName);
        if (a != null && a.length() > 0) {
            // Display the layout parameters without the leading layout_ prefix
            // and id references without the @+id/ prefix
            if (propertyName.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)) {
                propertyName = propertyName.substring(ATTR_LAYOUT_RESOURCE_PREFIX.length());
            }
            a = stripIdPrefix(a);
            String s = propertyName + ": " + a;
            infos.add(s);
        }
    }

    @Override
    public void paintSelectionFeedback(@NonNull IGraphics graphics, @NonNull INode parentNode,
            @NonNull List<? extends INode> childNodes, @Nullable Object view) {
        super.paintSelectionFeedback(graphics, parentNode, childNodes, view);

        boolean showDependents = true;
        if (sShowStructure) {
            childNodes = Arrays.asList(parentNode.getChildren());
            // Avoid painting twice - both as incoming and outgoing
            showDependents = false;
        } else if (!sShowConstraints) {
            return;
        }

        ConstraintPainter.paintSelectionFeedback(graphics, parentNode, childNodes, showDependents);
    }

    // ==== Drag'n'drop support ====

    @Override
    public DropFeedback onDropEnter(@NonNull INode targetNode, @Nullable Object targetView,
            @Nullable IDragElement[] elements) {
        return new DropFeedback(new MoveHandler(targetNode, elements, mRulesEngine),
                new GuidelinePainter());
    }

    @Override
    public DropFeedback onDropMove(@NonNull INode targetNode, @NonNull IDragElement[] elements,
            @Nullable DropFeedback feedback, @NonNull Point p) {
        if (elements == null || elements.length == 0 || feedback == null) {
            return null;
        }

        MoveHandler state = (MoveHandler) feedback.userData;
        int offsetX = p.x + (feedback.dragBounds != null ? feedback.dragBounds.x : 0);
        int offsetY = p.y + (feedback.dragBounds != null ? feedback.dragBounds.y : 0);
        state.updateMove(feedback, elements, offsetX, offsetY, feedback.modifierMask);

        // Or maybe only do this if the results changed...
        feedback.requestPaint = true;

        return feedback;
    }

    @Override
    public void onDropLeave(@NonNull INode targetNode, @NonNull IDragElement[] elements,
            @Nullable DropFeedback feedback) {
    }

    @Override
    public void onDropped(final @NonNull INode targetNode, final @NonNull IDragElement[] elements,
            final @Nullable DropFeedback feedback, final @NonNull Point p) {
        if (feedback == null) {
            return;
        }

        final MoveHandler state = (MoveHandler) feedback.userData;

        final Map<String, Pair<String, String>> idMap = getDropIdMap(targetNode, elements,
                feedback.isCopy || !feedback.sameCanvas);

        targetNode.editXml("Dropped", new INodeHandler() {
            @Override
            public void handle(@NonNull INode n) {
                int index = -1;

                // Remove cycles
                state.removeCycles();

                // Now write the new elements.
                INode previous = null;
                for (IDragElement element : elements) {
                    String fqcn = element.getFqcn();

                    // index==-1 means to insert at the end.
                    // Otherwise increment the insertion position.
                    if (index >= 0) {
                        index++;
                    }

                    INode newChild = targetNode.insertChildAt(fqcn, index);

                    // Copy all the attributes, modifying them as needed.
                    addAttributes(newChild, element, idMap, BaseLayoutRule.DEFAULT_ATTR_FILTER);
                    addInnerElements(newChild, element, idMap);

                    if (previous == null) {
                        state.applyConstraints(newChild);
                        previous = newChild;
                    } else {
                        // Arrange the nodes next to each other, depending on which
                        // edge we are attaching to. For example, if attaching to the
                        // top edge, arrange the subsequent nodes in a column below it.
                        //
                        // TODO: Try to do something smarter here where we detect
                        // constraints between the dragged edges, and we preserve these.
                        // We have to do this carefully though because if the
                        // constraints go through some other nodes not part of the
                        // selection, this doesn't work right, and you might be
                        // dragging several connected components, which we'd then
                        // need to stitch together such that they are all visible.

                        state.attachPrevious(previous, newChild);
                        previous = newChild;
                    }
                }
            }
        });
    }

    @Override
    public void onChildInserted(@NonNull INode node, @NonNull INode parent,
            @NonNull InsertType insertType) {
        // TODO: Handle more generically some way to ensure that widgets with no
        // intrinsic size get some minimum size until they are attached on multiple
        // opposing sides.
        //String fqcn = node.getFqcn();
        //if (fqcn.equals(FQCN_EDIT_TEXT)) {
        //    node.setAttribute(ANDROID_URI, ATTR_LAYOUT_WIDTH, "100dp"); //$NON-NLS-1$
        //}
    }

    @Override
    public void onRemovingChildren(@NonNull List<INode> deleted, @NonNull INode parent,
            boolean moved) {
        super.onRemovingChildren(deleted, parent, moved);

        if (!moved) {
            DeletionHandler handler = new DeletionHandler(deleted, Collections.<INode>emptyList(),
                    parent);
            handler.updateConstraints();
        }
    }

    // ==== Resize Support ====

    @Override
    public DropFeedback onResizeBegin(@NonNull INode child, @NonNull INode parent,
            @Nullable SegmentType horizontalEdgeType, @Nullable SegmentType verticalEdgeType,
            @Nullable Object childView, @Nullable Object parentView) {
        ResizeHandler state = new ResizeHandler(parent, child, mRulesEngine,
                horizontalEdgeType, verticalEdgeType);
        return new DropFeedback(state, new GuidelinePainter());
    }

    @Override
    public void onResizeUpdate(@Nullable DropFeedback feedback, @NonNull INode child,
            @NonNull INode parent, @NonNull Rect newBounds,
            int modifierMask) {
        if (feedback == null) {
            return;
        }

        ResizeHandler state = (ResizeHandler) feedback.userData;
        state.updateResize(feedback, child, newBounds, modifierMask);
    }

    @Override
    public void onResizeEnd(@Nullable DropFeedback feedback, @NonNull INode child,
            @NonNull INode parent, final @NonNull Rect newBounds) {
        if (feedback == null) {
            return;
        }
        final ResizeHandler state = (ResizeHandler) feedback.userData;

        child.editXml("Resize", new INodeHandler() {
            @Override
            public void handle(@NonNull INode n) {
                state.removeCycles();
                state.applyConstraints(n);
            }
        });
    }

    // ==== Layout Actions Bar ====

    @Override
    public void addLayoutActions(
            @NonNull List<RuleAction> actions,
            final @NonNull INode parentNode,
            final @NonNull List<? extends INode> children) {
        super.addLayoutActions(actions, parentNode, children);

        actions.add(createGravityAction(Collections.<INode>singletonList(parentNode),
                ATTR_GRAVITY));
        actions.add(RuleAction.createSeparator(25));
        actions.add(createMarginAction(parentNode, children));

        IMenuCallback callback = new IMenuCallback() {
            @Override
            public void action(@NonNull RuleAction action,
                    @NonNull List<? extends INode> selectedNodes,
                    final @Nullable String valueId,
                    final @Nullable Boolean newValue) {
                final String id = action.getId();
                if (id.equals(ACTION_CENTER_VERTICAL)|| id.equals(ACTION_CENTER_HORIZONTAL)) {
                    parentNode.editXml("Center", new INodeHandler() {
                        @Override
                        public void handle(@NonNull INode n) {
                            if (id.equals(ACTION_CENTER_VERTICAL)) {
                                for (INode child : children) {
                                    centerVertically(child);
                                }
                            } else if (id.equals(ACTION_CENTER_HORIZONTAL)) {
                                for (INode child : children) {
                                    centerHorizontally(child);
                                }
                            }
                            mRulesEngine.redraw();
                        }

                    });
                } else if (id.equals(ACTION_SHOW_CONSTRAINTS)) {
                    sShowConstraints = !sShowConstraints;
                    mRulesEngine.redraw();
                } else {
                    assert id.equals(ACTION_SHOW_STRUCTURE);
                    sShowStructure = !sShowStructure;
                    mRulesEngine.redraw();
                }
            }
        };

        // Centering actions
        if (children != null && children.size() > 0) {
                        actions.add(RuleAction.createSeparator(150));
            actions.add(RuleAction.createAction(ACTION_CENTER_VERTICAL, "Center Vertically",
                    callback, ICON_CENTER_VERTICALLY, 160, false));
            actions.add(RuleAction.createAction(ACTION_CENTER_HORIZONTAL, "Center Horizontally",
                    callback, ICON_CENTER_HORIZONTALLY, 170, false));
        }

        actions.add(RuleAction.createSeparator(80));
        actions.add(RuleAction.createToggle(ACTION_SHOW_CONSTRAINTS, "Show Constraints",
                sShowConstraints, callback, ICON_SHOW_CONSTRAINTS, 180, false));
        actions.add(RuleAction.createToggle(ACTION_SHOW_STRUCTURE, "Show All Relationships",
                sShowStructure, callback, ICON_SHOW_STRUCTURE, 190, false));
    }

    private void centerHorizontally(INode node) {
        // Clear horizontal-oriented attributes from the node
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_PARENT_LEFT, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_LEFT, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_TO_RIGHT_OF, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_HORIZONTAL, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_PARENT_RIGHT, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_RIGHT, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_TO_LEFT_OF, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_HORIZONTAL, null);

        if (VALUE_TRUE.equals(node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_CENTER_IN_PARENT))) {
            // Already done
        } else if (VALUE_TRUE.equals(node.getStringAttr(ANDROID_URI,
                ATTR_LAYOUT_CENTER_VERTICAL))) {
            node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_VERTICAL, null);
            node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_IN_PARENT, VALUE_TRUE);
        } else {
            node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_HORIZONTAL, VALUE_TRUE);
        }
    }

    private void centerVertically(INode node) {
        // Clear vertical-oriented attributes from the node
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_PARENT_TOP, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_TOP, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_BELOW, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_PARENT_BOTTOM, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_BOTTOM, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ABOVE, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_VERTICAL, null);
        node.setAttribute(ANDROID_URI, ATTR_LAYOUT_ALIGN_BASELINE, null);

        // Center vertically
        if (VALUE_TRUE.equals(node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_CENTER_IN_PARENT))) {
            // ALready done
        } else if (VALUE_TRUE.equals(node.getStringAttr(ANDROID_URI,
                ATTR_LAYOUT_CENTER_HORIZONTAL))) {
            node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_HORIZONTAL, null);
            node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_IN_PARENT, VALUE_TRUE);
        } else {
            node.setAttribute(ANDROID_URI, ATTR_LAYOUT_CENTER_VERTICAL, VALUE_TRUE);
        }
    }
}
