/*
 * Copyright (C) 2011 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.grid;

import static com.android.ide.common.layout.grid.GridModel.UNDEFINED;

import com.android.ide.common.api.INode;
import com.android.ide.common.api.SegmentType;

/**
 * A match for a drag within a GridLayout, corresponding to an alignment with another
 * edge, or a margin, or centering, or a gap distance from another edge and so on.
 */
class GridMatch implements Comparable<GridMatch> {
    /** The distance to the matched edge - used to pick best matches */
    public final int distance;

    /** Type of edge that was matched (this refers to the edge on the dragged node,
     * not on the matched node/row/cell etc) */
    public final SegmentType type;

    /** Row or column for the match */
    public int cellIndex;

    /** If true, create a new row/column */
    public boolean createCell;

    /** The actual x or y position of the matched segment */
    public int matchedLine;

    /** Amount of margin between the matched edges */
    public int margin;

    /**
     * Constructs a match.
     *
     * @param type the edge of the dragged element that was matched
     * @param distance the absolute distance from the ideal match - used to find the best
     *            match
     * @param matchedLine the actual X or Y location of the ideal match
     * @param cellIndex the index of the row or column we matched with
     * @param createCell if true, create a new cell by splitting the existing cell at the
     *            matchedLine position
     * @param margin a margin distance to add to the actual location from the matched line
     */
    GridMatch(SegmentType type, int distance, int matchedLine, int cellIndex,
            boolean createCell, int margin) {
        super();
        this.type = type;
        this.distance = distance;
        this.matchedLine = matchedLine;
        this.cellIndex = cellIndex;
        this.createCell = createCell;
        this.margin = margin;
    }

    // Implements Comparable<GridMatch>
    @Override
    public int compareTo(GridMatch o) {
        // Pick closest matches first
        if (distance != o.distance) {
            return distance - o.distance;
        }

        // Prefer some types of matches over other matches
        return getPriority() - o.getPriority();
    }

    /**
     * Describes the match for the user
     *
     * @param layout the GridLayout containing the match
     * @return a short description for the user of the match
     */
    public String getDisplayName(INode layout) {
        switch (type) {
            case BASELINE:
                return String.format("Align baseline in row %1$d", cellIndex + 1);
            case CENTER_HORIZONTAL:
                return "Center horizontally";
            case LEFT:
                if (!createCell) {
                    return String.format("Insert into column %1$d", cellIndex + 1);
                }
                if (margin != UNDEFINED) {
                    if (cellIndex == 0 && margin != 0) {
                        return "Add one margin distance from the left";
                    }
                    return String.format("Add next to column %1$d", cellIndex + 1);
                }
                return String.format("Align left at x=%1$d", matchedLine - layout.getBounds().x);
            case RIGHT:
                if (!createCell) {
                    return String.format("Insert right-aligned into column %1$d", cellIndex + 1);
                }
                return String.format("Align right at x=%1$d", matchedLine - layout.getBounds().x);
            case TOP:
                if (!createCell) {
                    return String.format("Insert into row %1$d", cellIndex + 1);
                }
                if (margin != UNDEFINED) {
                    if (cellIndex == 0 && margin != 0) {
                        return "Add one margin distance from the top";
                    }
                    return String.format("Add below row %1$d", cellIndex + 1);
                }
                return String.format("Align top at y=%1d", matchedLine - layout.getBounds().y);
            case BOTTOM:
                if (!createCell) {
                    return String.format("Insert into bottom of row %1$d", cellIndex + 1);
                }
                return String.format("Align bottom at y=%1d", matchedLine - layout.getBounds().y);
            case CENTER_VERTICAL:
                return "Center vertically";
            case UNKNOWN:
            default:
                return null;
        }
    }

    /**
     * Computes the sorting priority of this match, giving baseline matches higher
     * precedence than centering which in turn is ordered before external edge matches
     */
    private int getPriority() {
        switch (type) {
            case BASELINE:
                return 0;
            case CENTER_HORIZONTAL:
            case CENTER_VERTICAL:
                return 1;
            case BOTTOM:
            case LEFT:
            case RIGHT:
            case TOP:
                return 2;
        }

        return 3;
    }
}