/*
 * 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.ide.eclipse.adt.internal.editors.draw9patch.graphics;

import static com.android.SdkConstants.DOT_9PNG;
import static com.android.SdkConstants.DOT_PNG;
import com.android.ide.eclipse.adt.AdtPlugin;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * The model of 9-patched image.
 */
public class NinePatchedImage {
    private static final boolean DEBUG = false;

    /**
     * Get 9-patched filename as like image.9.png .
     */
    public static String getNinePatchedFileName(String fileName) {
        if (fileName.endsWith(DOT_9PNG)) {
            return fileName;
        }
        return fileName.substring(0, fileName.lastIndexOf(DOT_PNG)) + DOT_9PNG;
    }

    // For stretch regions and padding
    public static final int BLACK_TICK = 0xFF000000;
    // For Layout Bounds
    public static final int RED_TICK = 0xFFFF0000;
    // Blank
    public static final int TRANSPARENT_TICK = 0x00000000;

    private ImageData mBaseImageData;

    private Image mBaseImage = null;

    private boolean mHasNinePatchExtension = false;

    private boolean mDirtyFlag = false;

    private int[] mHorizontalPatchPixels = null;
    private int[] mVerticalPatchPixels = null;

    private int[] mHorizontalContentPixels = null;
    private int[] mVerticalContentPixels = null;

    // for Prevent unexpected stretch in StretchsView
    private boolean mRedTickOnlyInHorizontalFlag = false;
    private boolean mRedTickOnlyInVerticalFlag = false;

    private final List<Tick> mHorizontalPatches = new ArrayList<Tick>();
    private final List<Tick> mVerticalPatches = new ArrayList<Tick>();

    private final List<Tick> mHorizontalContents = new ArrayList<Tick>();
    private final List<Tick> mVerticalContents = new ArrayList<Tick>();


    private static final int CHUNK_BIN_SIZE = 100;
    private final List<Chunk> mChunkBin = new ArrayList<Chunk>(CHUNK_BIN_SIZE);

    private int mHorizontalFixedPatchSum = 0;
    private int mVerticalFixedPatchSum = 0;

    private static final int PROJECTION_BIN_SIZE = 100;
    private final List<Projection> mProjectionBin = new ArrayList<Projection>(PROJECTION_BIN_SIZE);

    private Chunk[][] mPatchChunks = null;

    public ImageData getImageData() {
        return mBaseImageData;
    }

    public int getWidth() {
        return mBaseImageData.width;
    }

    public int getHeight() {
        return mBaseImageData.height;
    }

    public Image getImage() {
        if (mBaseImage == null) {
            mBaseImage = new Image(AdtPlugin.getDisplay(), mBaseImageData);
        }
        return mBaseImage;
    }

    public boolean hasNinePatchExtension() {
        return mHasNinePatchExtension;
    }

    /**
     * Get the image has/hasn't been edited flag.
     * @return If has been edited, return true
     */
    public boolean isDirty() {
        return mDirtyFlag;
    }

    /**
     * Clear dirty(edited) flag.
     */
    public void clearDirtyFlag() {
        mDirtyFlag = false;
    }

    public NinePatchedImage(String fileName) {
        boolean hasNinePatchExtension = fileName.endsWith(DOT_9PNG);
        ImageData data = new ImageData(fileName);

        initNinePatchedImage(data, hasNinePatchExtension);
    }

    public NinePatchedImage(InputStream inputStream, String fileName) {
        boolean hasNinePatchExtension = fileName.endsWith(DOT_9PNG);
        ImageData data = new ImageData(inputStream);

        initNinePatchedImage(data, hasNinePatchExtension);
    }

    private Chunk getChunk() {
        if (mChunkBin.size() > 0) {
            Chunk chunk = mChunkBin.remove(0);
            chunk.init();
            return chunk;
        }
        return new Chunk();
    }

    private static final void recycleChunks(Chunk[][] patchChunks, List<Chunk> bin) {
        int yLen = patchChunks.length;
        int xLen = patchChunks[0].length;

        for (int y = 0; y < yLen; y++) {
            for (int x = 0; x < xLen; x++) {
                if (bin.size() < CHUNK_BIN_SIZE) {
                    bin.add(patchChunks[y][x]);
                }
                patchChunks[y][x] = null;
            }
        }
    }

    private Projection getProjection() {
        if (mProjectionBin.size() > 0) {
            Projection projection = mProjectionBin.remove(0);
            return projection;
        }
        return new Projection();
    }

    private static final void recycleProjections(Projection[][] projections, List<Projection> bin) {
        int yLen = projections.length;
        int xLen = 0;
        if (yLen > 0) {
            xLen = projections[0].length;
        }

        for (int y = 0; y < yLen; y++) {
            for (int x = 0; x < xLen; x++) {
                if (bin.size() < CHUNK_BIN_SIZE) {
                    bin.add(projections[y][x]);
                }
                projections[y][x] = null;
            }
        }
    }

    private static final int[] initArray(int[] array) {
        int len = array.length;
        for (int i = 0; i < len; i++) {
            array[i] = TRANSPARENT_TICK;
        }
        return array;
    }

    /**
     * Get one pixel with alpha from the image.
     * @return packed integer value as ARGB8888
     */
    private static final int getPixel(ImageData image, int x, int y) {
        return (image.getAlpha(x, y) << 24) + image.getPixel(x, y);
    }

    private static final boolean isTransparentPixel(ImageData image, int x, int y) {
        return image.getAlpha(x, y) == 0x0;
    }

    private static final boolean isValidTickColor(int pixel) {
        return (pixel == BLACK_TICK || pixel == RED_TICK);
    }

    private void initNinePatchedImage(ImageData imageData, boolean hasNinePatchExtension) {
        mBaseImageData = imageData;
        mHasNinePatchExtension = hasNinePatchExtension;
    }

    private boolean ensurePixel(int x, int y, int[] pixels, int index) {
        boolean isValid = true;
        int pixel = getPixel(mBaseImageData, x, y);
        if (!isTransparentPixel(mBaseImageData, x, y)) {
            if (index == 0 || index == pixels.length - 1) {
                isValid = false;
            }
            if (isValidTickColor(pixel)) {
                pixels[index] = pixel;
            } else {
                isValid = false;
            }
            // clear pixel
            mBaseImageData.setAlpha(x, y, 0x0);
        }
        return isValid;
    }

    private boolean ensureHorizontalPixel(int x, int y, int[] pixels) {
        return ensurePixel(x, y, pixels, x);
    }

    private boolean ensureVerticalPixel(int x, int y, int[] pixels) {
        return ensurePixel(x, y, pixels, y);
    }

    /**
     * Ensure that image data is 9-patch.
     */
    public boolean ensure9Patch() {
        boolean isValid = true;

        int width = mBaseImageData.width;
        int height = mBaseImageData.height;

        createPatchArray();
        createContentArray();

        // horizontal
        for (int x = 0; x < width; x++) {
            // top row
            if (!ensureHorizontalPixel(x, 0, mHorizontalPatchPixels)) {
                isValid = false;
            }
            // bottom row
            if (!ensureHorizontalPixel(x, height - 1, mHorizontalContentPixels)) {
                isValid = false;
            }
        }
        // vertical
        for (int y = 0; y < height; y++) {
            // left column
            if (!ensureVerticalPixel(0, y, mVerticalPatchPixels)) {
                isValid = false;
            }
            // right column
            if (!ensureVerticalPixel(width -1, y, mVerticalContentPixels)) {
                isValid = false;
            }
        }
        findPatches();
        findContentsArea();

        return isValid;
    }

    private void createPatchArray() {
        mHorizontalPatchPixels = initArray(new int[mBaseImageData.width]);
        mVerticalPatchPixels = initArray(new int[mBaseImageData.height]);
    }

    private void createContentArray() {
        mHorizontalContentPixels = initArray(new int[mBaseImageData.width]);
        mVerticalContentPixels = initArray(new int[mBaseImageData.height]);
    }

    /**
     * Convert to 9-patch image.
     * <p>
     * This method doesn't consider that target image is already 9-patched or
     * not.
     * </p>
     */
    public void convertToNinePatch() {
        mBaseImageData = GraphicsUtilities.convertToNinePatch(mBaseImageData);
        mHasNinePatchExtension = true;

        createPatchArray();
        createContentArray();

        findPatches();
        findContentsArea();
    }

    public boolean isValid(int x, int y) {
        return (x == 0) ^ (y == 0)
                ^ (x == mBaseImageData.width - 1) ^ (y == mBaseImageData.height - 1);
    }

    /**
     * Set patch or content.
     */
    public void setPatch(int x, int y, int color) {
        if (isValid(x, y)) {
            if (x == 0) {
                mVerticalPatchPixels[y] = color;
            } else if (y == 0) {
                mHorizontalPatchPixels[x] = color;
            } else if (x == mBaseImageData.width - 1) {
                mVerticalContentPixels[y] = color;
            } else if (y == mBaseImageData.height - 1) {
                mHorizontalContentPixels[x] = color;
            }

            // Mark as dirty
            mDirtyFlag = true;
        }
    }

    /**
     * Erase the pixel.
     */
    public void erase(int x, int y) {
        if (isValid(x, y)) {
            int color = TRANSPARENT_TICK;
            if (x == 0) {
                mVerticalPatchPixels[y] = color;
            } else if (y == 0) {
                mHorizontalPatchPixels[x] = color;
            } else if (x == mBaseImageData.width - 1) {
                mVerticalContentPixels[y] = color;
            } else if (y == mBaseImageData.height - 1) {
                mHorizontalContentPixels[x] = color;
            }

            // Mark as dirty
            mDirtyFlag = true;
        }
    }

    public List<Tick> getHorizontalPatches() {
        return mHorizontalPatches;
    }

    public List<Tick> getVerticalPatches() {
        return mVerticalPatches;
    }

    /**
     * Find patches from pixels array.
     * @param pixels Target of seeking ticks.
     * @param out Add the found ticks.
     * @return If BlackTick is not found but only RedTick is found, returns true
     */
    private static boolean findPatches(int[] pixels, List<Tick> out) {
        boolean redTickOnly = true;
        Tick patch = null;
        int len = 0;

        // find patches
        out.clear();
        len = pixels.length - 1;
        for (int i = 1; i < len; i++) {
            int pixel = pixels[i];

            if (redTickOnly && pixel != TRANSPARENT_TICK && pixel != RED_TICK) {
                redTickOnly = false;
            }

            if (patch != null) {
                if (patch.color != pixel) {
                    patch.end = i;
                    out.add(patch);
                    patch = null;
                }
            }
            if (patch == null) {
                patch = new Tick(pixel);
                patch.start = i;
            }
        }

        if (patch != null) {
            patch.end = len;
            out.add(patch);
        }
        return redTickOnly;
    }

    public void findPatches() {

        // find horizontal patches
        mRedTickOnlyInHorizontalFlag = findPatches(mHorizontalPatchPixels, mHorizontalPatches);

        // find vertical patches
        mRedTickOnlyInVerticalFlag = findPatches(mVerticalPatchPixels, mVerticalPatches);
    }

    public Rectangle getContentArea() {
        Tick horizontal = getContentArea(mHorizontalContents);
        Tick vertical = getContentArea(mVerticalContents);

        Rectangle rect = new Rectangle(0, 0, 0, 0);
        rect.x = 1;
        rect.width = mBaseImageData.width - 1;
        rect.y = 1;
        rect.height = mBaseImageData.height - 1;

        if (horizontal != null) {
            rect.x = horizontal.start;
            rect.width = horizontal.getLength();
        }
        if (vertical != null) {
            rect.y = vertical.start;
            rect.height = vertical.getLength();
        }

        return rect;
    }

    private Tick getContentArea(List<Tick> list) {
        int size = list.size();
        if (size == 0) {
            return null;
        }
        if (size == 1) {
            return list.get(0);
        }

        Tick start = null;
        Tick end = null;

        for (int i = 0; i < size; i++) {
            Tick t = list.get(i);
            if (t.color == BLACK_TICK) {
                if (start == null) {
                    start = t;
                    end = t;
                } else {
                    end = t;
                }
            }
        }

        // red tick only
        if (start == null) {
            return null;
        }

        Tick result = new Tick(start.color);
        result.start = start.start;
        result.end = end.end;

        return result;
    }

    /**
     * This is for unit test use only.
     * @see com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.NinePatchedImageTest
     */
    public List<Tick> getHorizontalContents() {
        return mHorizontalContents;
    }

    /**
     * This is for unit test use only.
     * @see com.android.ide.eclipse.adt.internal.editors.draw9patch.graphics.NinePatchedImageTest
     */
    public List<Tick> getVerticalContents() {
        return mVerticalContents;
    }

    private static void findContentArea(int[] pixels, List<Tick> out) {
        Tick contents = null;
        int len = 0;

        // find horizontal contents area
        out.clear();
        len = pixels.length - 1;
        for (int x = 1; x < len; x++) {
            if (contents != null) {
                if (contents.color != pixels[x]) {
                    contents.end = x;
                    out.add(contents);
                    contents = null;
                }
            }
            if (contents == null) {
                contents = new Tick(pixels[x]);
                contents.start = x;
            }
        }

        if (contents != null) {
            contents.end = len;
            out.add(contents);
        }
    }

    public void findContentsArea() {

        // find horizontal contents area
        findContentArea(mHorizontalContentPixels, mHorizontalContents);

        // find vertical contents area
        findContentArea(mVerticalContentPixels, mVerticalContents);
    }

    /**
     * Get raw image data.
     * <p>
     * The raw image data is applicable for save.
     * </p>
     */
    public ImageData getRawImageData() {
        ImageData image = GraphicsUtilities.copy(mBaseImageData);

        final int width = image.width;
        final int height = image.height;
        int len = 0;

        len = mHorizontalPatchPixels.length;
        for (int x = 0; x < len; x++) {
            int pixel = mHorizontalPatchPixels[x];
            if (pixel != TRANSPARENT_TICK) {
                image.setAlpha(x, 0, 0xFF);
                image.setPixel(x, 0, pixel);
            }
        }

        len = mVerticalPatchPixels.length;
        for (int y = 0; y < len; y++) {
            int pixel = mVerticalPatchPixels[y];
            if (pixel != TRANSPARENT_TICK) {
                image.setAlpha(0, y, 0xFF);
                image.setPixel(0, y, pixel);
            }
        }

        len = mHorizontalContentPixels.length;
        for (int x = 0; x < len; x++) {
            int pixel = mHorizontalContentPixels[x];
            if (pixel != TRANSPARENT_TICK) {
                image.setAlpha(x, height - 1, 0xFF);
                image.setPixel(x, height - 1, pixel);
            }
        }

        len = mVerticalContentPixels.length;
        for (int y = 0; y < len; y++) {
            int pixel = mVerticalContentPixels[y];
            if (pixel != TRANSPARENT_TICK) {
                image.setAlpha(width - 1, y, 0xFF);
                image.setPixel(width - 1, y, pixel);
            }
        }

        return image;
    }

    public Chunk[][] getChunks(Chunk[][] chunks) {
        int lenY = mVerticalPatches.size();
        int lenX = mHorizontalPatches.size();

        if (lenY == 0 || lenX == 0) {
            return null;
        }

        if (chunks == null) {
            chunks = new Chunk[lenY][lenX];
        } else {
            int y = chunks.length;
            int x = chunks[0].length;
            if (lenY != y || lenX != x) {
                recycleChunks(chunks, mChunkBin);
                chunks = new Chunk[lenY][lenX];
            }
        }

        // for calculate weights
        float horizontalPatchSum = 0;
        float verticalPatchSum = 0;

        mVerticalFixedPatchSum = 0;
        mHorizontalFixedPatchSum = 0;

        for (int y = 0; y < lenY; y++) {
            Tick yTick = mVerticalPatches.get(y);

            for (int x = 0; x < lenX; x++) {
                Tick xTick = mHorizontalPatches.get(x);
                Chunk t = getChunk();
                chunks[y][x] = t;

                t.rect.x = xTick.start;
                t.rect.width = xTick.getLength();
                t.rect.y = yTick.start;
                t.rect.height = yTick.getLength();

                if (mRedTickOnlyInHorizontalFlag
                        || xTick.color == BLACK_TICK || lenX == 1) {
                    t.type += Chunk.TYPE_HORIZONTAL;
                    if (y == 0) {
                        horizontalPatchSum += t.rect.width;
                    }
                }
                if (mRedTickOnlyInVerticalFlag
                        || yTick.color == BLACK_TICK || lenY == 1) {
                    t.type += Chunk.TYPE_VERTICAL;
                    if (x == 0) {
                        verticalPatchSum += t.rect.height;
                    }
                }

                if ((t.type & Chunk.TYPE_HORIZONTAL) == 0 && lenX > 1 && y == 0) {
                    mHorizontalFixedPatchSum += t.rect.width;
                }
                if ((t.type & Chunk.TYPE_VERTICAL) == 0 && lenY > 1 && x == 0) {
                    mVerticalFixedPatchSum += t.rect.height;
                }

            }
        }

        // calc weights
        for (int y = 0; y < lenY; y++) {
            for (int x = 0; x < lenX; x++) {
                Chunk chunk = chunks[y][x];
                if ((chunk.type & Chunk.TYPE_HORIZONTAL) != 0) {
                    chunk.horizontalWeight = chunk.rect.width / horizontalPatchSum;
                }
                if ((chunk.type & Chunk.TYPE_VERTICAL) != 0) {
                    chunk.verticalWeight = chunk.rect.height / verticalPatchSum;

                }
            }
        }

        return chunks;
    }

    public Chunk[][] getCorruptedChunks(Chunk[][] chunks) {
        chunks = getChunks(chunks);

        if (chunks != null) {
            int yLen = chunks.length;
            int xLen = chunks[0].length;

            for (int yPos = 0; yPos < yLen; yPos++) {
                for (int xPos = 0; xPos < xLen; xPos++) {
                    Chunk c = chunks[yPos][xPos];
                    Rectangle r = c.rect;
                    if ((c.type & Chunk.TYPE_HORIZONTAL) != 0
                            && isHorizontalCorrupted(mBaseImageData, r)) {
                        c.type |= Chunk.TYPE_CORRUPT;
                    }
                    if ((c.type & Chunk.TYPE_VERTICAL) != 0
                            && isVerticalCorrupted(mBaseImageData, r)) {
                        c.type |= Chunk.TYPE_CORRUPT;
                    }
                }
            }
        }
        return chunks;
    }

    private static boolean isVerticalCorrupted(ImageData data, Rectangle r) {
        int[] column = new int[r.width];
        int[] sample = new int[r.width];

        GraphicsUtilities.getHorizontalPixels(data, r.x, r.y, r.width, column);

        int lenY = r.y + r.height;
        for (int y = r.y; y < lenY; y++) {
            GraphicsUtilities.getHorizontalPixels(data, r.x, y, r.width, sample);
            if (!Arrays.equals(column, sample)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isHorizontalCorrupted(ImageData data, Rectangle r) {
        int[] column = new int[r.height];
        int[] sample = new int[r.height];
        GraphicsUtilities.getVerticalPixels(data, r.x, r.y, r.height, column);

        int lenX = r.x + r.width;
        for (int x = r.x; x < lenX; x++) {
            GraphicsUtilities.getVerticalPixels(data, x, r.y, r.height, sample);
            if (!Arrays.equals(column, sample)) {
                return true;
            }
        }
        return false;
    }

    public Projection[][] getProjections(int width, int height, Projection[][] projections) {
        mPatchChunks = getChunks(mPatchChunks);
        if (mPatchChunks == null) {
            return null;
        }

        if (DEBUG) {
            System.out.println(String.format("width:%d, height:%d", width, height));
        }

        int lenY = mPatchChunks.length;
        int lenX = mPatchChunks[0].length;

        if (projections == null) {
            projections = new Projection[lenY][lenX];
        } else {
            int y = projections.length;
            int x = projections[0].length;
            if (lenY != y || lenX != x) {
                recycleProjections(projections, mProjectionBin);
                projections = new Projection[lenY][lenX];
            }
        }

        float xZoom = ((float) width / mBaseImageData.width);
        float yZoom = ((float) height / mBaseImageData.height);

        if (DEBUG) {
            System.out.println(String.format("xZoom:%f, yZoom:%f", xZoom, yZoom));
        }

        int destX = 0;
        int destY = 0;
        int streatchableWidth = width - mHorizontalFixedPatchSum;
        streatchableWidth = streatchableWidth > 0 ? streatchableWidth : 1;

        int streatchableHeight = height - mVerticalFixedPatchSum;
        streatchableHeight = streatchableHeight > 0 ? streatchableHeight : 1;

        if (DEBUG) {
            System.out.println(String.format("streatchable %d %d", streatchableWidth,
                    streatchableHeight));
        }

        for (int yPos = 0; yPos < lenY; yPos++) {
            destX = 0;
            Projection p = null;
            for (int xPos = 0; xPos < lenX; xPos++) {
                Chunk chunk = mPatchChunks[yPos][xPos];

                if (DEBUG) {
                    System.out.println(String.format("Tile[%d, %d] = %s",
                            yPos, xPos, chunk.toString()));
                }

                p = getProjection();
                projections[yPos][xPos] = p;

                p.chunk = chunk;
                p.src = chunk.rect;
                p.dest.x = destX;
                p.dest.y = destY;

                // fixed size
                p.dest.width = chunk.rect.width;
                p.dest.height = chunk.rect.height;

                // horizontal stretch
                if ((chunk.type & Chunk.TYPE_HORIZONTAL) != 0) {
                    p.dest.width = Math.round(streatchableWidth * chunk.horizontalWeight);
                }
                // vertical stretch
                if ((chunk.type & Chunk.TYPE_VERTICAL) != 0) {
                    p.dest.height = Math.round(streatchableHeight * chunk.verticalWeight);
                }

                destX += p.dest.width;
            }
            destY += p.dest.height;
        }
        return projections;
    }

    /**
     * Projection class for make relation between chunked image and resized image.
     */
    public static class Projection {
        public Chunk chunk = null;
        public Rectangle src = null;
        public final Rectangle dest = new Rectangle(0, 0, 0, 0);

        @Override
        public String toString() {
            return String.format("src[%d, %d, %d, %d] => dest[%d, %d, %d, %d]",
                    src.x, src.y, src.width, src.height,
                    dest.x, dest.y, dest.width, dest.height);
        }
    }

    public static class Chunk {
        public static final int TYPE_FIXED = 0x0;
        public static final int TYPE_HORIZONTAL = 0x1;
        public static final int TYPE_VERTICAL = 0x2;
        public static final int TYPE_CORRUPT = 0x80000000;

        public int type = TYPE_FIXED;

        public Rectangle rect = new Rectangle(0, 0, 0, 0);

        public float horizontalWeight = 0.0f;
        public float verticalWeight = 0.0f;

        void init() {
            type = Chunk.TYPE_FIXED;
            horizontalWeight = 0.0f;
            verticalWeight = 0.0f;
            rect.x = 0;
            rect.y = 0;
            rect.width = 0;
            rect.height = 0;
        }

        private String typeToString() {
            switch (type) {
                case TYPE_FIXED:
                    return "FIXED";
                case TYPE_HORIZONTAL:
                    return "HORIZONTAL";
                case TYPE_VERTICAL:
                    return "VERTICAL";
                case TYPE_HORIZONTAL + TYPE_VERTICAL:
                    return "BOTH";
                default:
                    return "UNKNOWN";
            }
        }

        @Override
        public String toString() {
            return String.format("%s %f/%f %s", typeToString(), horizontalWeight, verticalWeight,
                    rect.toString());
        }
    }

    public static class Tick {
        public int start;
        public int end;
        public int color;

        /**
         * Get the tick length.
         */
        public int getLength() {
            return end - start;
        }

        public Tick(int tickColor) {
            color = tickColor;
        }

        @Override
        public String toString() {
            return String.format("%d tick: %d to %d", color, start, end);
        }
    }
}
