/*
 * Copyright (C) 2013 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.draw9patch.ui;

import com.android.draw9patch.graphics.GraphicsUtilities;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class PatchInfo {
    /** Color used to indicate stretch regions and padding. */
    public static final int BLACK_TICK = 0xFF000000;

    /** Color used to indicate layout bounds. */
    public static final int RED_TICK = 0xFFFF0000;

    /** Areas of the image that are stretchable in both directions. */
    public final List<Rectangle> patches;

    /** Areas of the image that are not stretchable in either direction. */
    public final List<Rectangle> fixed;

    /** Areas of image stretchable horizontally. */
    public final List<Rectangle> horizontalPatches;

    /** Areas of image stretchable vertically. */
    public final List<Rectangle> verticalPatches;

    /** Bounds of horizontal patch markers. */
    public final List<Pair<Integer>> horizontalPatchMarkers;

    /** Bounds of horizontal padding markers. */
    public final List<Pair<Integer>> horizontalPaddingMarkers;

    /** Bounds of vertical patch markers. */
    public final List<Pair<Integer>> verticalPatchMarkers;

    /** Bounds of vertical padding markers. */
    public final List<Pair<Integer>> verticalPaddingMarkers;

    public final boolean verticalStartWithPatch;
    public final boolean horizontalStartWithPatch;

    /** Beginning and end padding in the horizontal direction */
    public final Pair<Integer> horizontalPadding;

    /** Beginning and end padding in the vertical direction */
    public final Pair<Integer> verticalPadding;

    private BufferedImage image;

    public PatchInfo(BufferedImage image) {
        this.image = image;

        int width = image.getWidth();
        int height = image.getHeight();

        int[] row = GraphicsUtilities.getPixels(image, 0, 0, width, 1, null);
        int[] column = GraphicsUtilities.getPixels(image, 0, 0, 1, height, null);

        P left = getPatches(column);
        verticalStartWithPatch = left.startsWithPatch;
        verticalPatchMarkers = left.patches;

        P top = getPatches(row);
        horizontalStartWithPatch = top.startsWithPatch;
        horizontalPatchMarkers = top.patches;

        fixed = getRectangles(left.fixed, top.fixed);
        patches = getRectangles(left.patches, top.patches);

        if (fixed.size() > 0) {
            horizontalPatches = getRectangles(left.fixed, top.patches);
            verticalPatches = getRectangles(left.patches, top.fixed);
        } else {
            if (top.fixed.size() > 0) {
                horizontalPatches = new ArrayList<Rectangle>(0);
                verticalPatches = getVerticalRectangles(top.fixed);
            } else if (left.fixed.size() > 0) {
                horizontalPatches = getHorizontalRectangles(left.fixed);
                verticalPatches = new ArrayList<Rectangle>(0);
            } else {
                horizontalPatches = verticalPatches = new ArrayList<Rectangle>(0);
            }
        }

        row = GraphicsUtilities.getPixels(image, 0, height - 1, width, 1, row);
        column = GraphicsUtilities.getPixels(image, width - 1, 0, 1, height, column);

        top = PatchInfo.getPatches(row);
        horizontalPaddingMarkers = top.patches;
        horizontalPadding = getPadding(top.fixed);

        left = PatchInfo.getPatches(column);
        verticalPaddingMarkers = left.patches;
        verticalPadding = getPadding(left.fixed);
    }

    private List<Rectangle> getVerticalRectangles(List<Pair<Integer>> topPairs) {
        List<Rectangle> rectangles = new ArrayList<Rectangle>();
        for (Pair<Integer> top : topPairs) {
            int x = top.first;
            int width = top.second - top.first;

            rectangles.add(new Rectangle(x, 1, width, image.getHeight() - 2));
        }
        return rectangles;
    }

    private List<Rectangle> getHorizontalRectangles(List<Pair<Integer>> leftPairs) {
        List<Rectangle> rectangles = new ArrayList<Rectangle>();
        for (Pair<Integer> left : leftPairs) {
            int y = left.first;
            int height = left.second - left.first;

            rectangles.add(new Rectangle(1, y, image.getWidth() - 2, height));
        }
        return rectangles;
    }

    private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
        if (pairs.size() == 0) {
            return new Pair<Integer>(0, 0);
        } else if (pairs.size() == 1) {
            if (pairs.get(0).first == 1) {
                return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first, 0);
            } else {
                return new Pair<Integer>(0, pairs.get(0).second - pairs.get(0).first);
            }
        } else {
            int index = pairs.size() - 1;
            return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first,
                    pairs.get(index).second - pairs.get(index).first);
        }
    }

    private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
                                          List<Pair<Integer>> topPairs) {
        List<Rectangle> rectangles = new ArrayList<Rectangle>();
        for (Pair<Integer> left : leftPairs) {
            int y = left.first;
            int height = left.second - left.first;
            for (Pair<Integer> top : topPairs) {
                int x = top.first;
                int width = top.second - top.first;

                rectangles.add(new Rectangle(x, y, width, height));
            }
        }
        return rectangles;
    }

    private static class P {
        public final List<Pair<Integer>> fixed;
        public final List<Pair<Integer>> patches;
        public final boolean startsWithPatch;

        private P(List<Pair<Integer>> f, List<Pair<Integer>> p, boolean s) {
            fixed = f;
            patches = p;
            startsWithPatch = s;
        }
    }

    private static P getPatches(int[] pixels) {
        int lastIndex = 1;
        int lastPixel;
        boolean first = true;
        boolean startWithPatch = false;

        List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
        List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();

        // ignore layout bound markers for the purpose of patch calculation
        lastPixel = pixels[1] != PatchInfo.RED_TICK ? pixels[1] : 0;

        for (int i = 1; i < pixels.length - 1; i++) {
            // ignore layout bound markers for the purpose of patch calculation
            int pixel = pixels[i] != PatchInfo.RED_TICK ? pixels[i] : 0;

            if (pixel != lastPixel) {
                if (lastPixel == BLACK_TICK) {
                    if (first) startWithPatch = true;
                    patches.add(new Pair<Integer>(lastIndex, i));
                } else {
                    fixed.add(new Pair<Integer>(lastIndex, i));
                }
                first = false;

                lastIndex = i;
                lastPixel = pixel;
            }
        }
        if (lastPixel == BLACK_TICK) {
            if (first) startWithPatch = true;
            patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
        } else {
            fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
        }

        if (patches.size() == 0) {
            patches.add(new Pair<Integer>(1, pixels.length - 1));
            startWithPatch = true;
            fixed.clear();
        }

        return new P(fixed, patches, startWithPatch);
    }
}
