/*
 * 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.gallery3d.filtershow.crop;

import android.graphics.Rect;
import android.graphics.RectF;

import com.android.gallery3d.filtershow.imageshow.GeometryMath;

public class CropObject {

    private BoundedRect mBoundedRect;
    private float mAspectWidth = 1;
    private float mAspectHeight = 1;
    private boolean mFixAspectRatio = false;
    private float mRotation = 0;
    private float mTouchTolerance = 45;
    private float mMinSideSize = 20;

    public static final int MOVE_NONE = 0;
    // Sides
    public static final int MOVE_LEFT = 1;
    public static final int MOVE_TOP = 2;
    public static final int MOVE_RIGHT = 4;
    public static final int MOVE_BOTTOM = 8;
    public static final int MOVE_BLOCK = 16;

    // Corners
    public static final int TOP_LEFT = MOVE_TOP | MOVE_LEFT;
    public static final int TOP_RIGHT = MOVE_TOP | MOVE_RIGHT;
    public static final int BOTTOM_RIGHT = MOVE_BOTTOM | MOVE_RIGHT;
    public static final int BOTTOM_LEFT = MOVE_BOTTOM | MOVE_LEFT;

    private int mMovingEdges = MOVE_NONE;

    public CropObject(Rect outerBound, Rect innerBound, int outerAngle) {
        mBoundedRect = new BoundedRect(outerAngle % 360, outerBound, innerBound);
    }

    public CropObject(RectF outerBound, RectF innerBound, int outerAngle) {
        mBoundedRect = new BoundedRect(outerAngle % 360, outerBound, innerBound);
    }

    public void resetBoundsTo(RectF inner, RectF outer) {
        mBoundedRect.resetTo(0, outer, inner);
    }

    public void getInnerBounds(RectF r) {
        mBoundedRect.setToInner(r);
    }

    public void getOuterBounds(RectF r) {
        mBoundedRect.setToOuter(r);
    }

    public RectF getInnerBounds() {
        return mBoundedRect.getInner();
    }

    public RectF getOuterBounds() {
        return mBoundedRect.getOuter();
    }

    public int getSelectState() {
        return mMovingEdges;
    }

    public boolean isFixedAspect() {
        return mFixAspectRatio;
    }

    public void rotateOuter(int angle) {
        mRotation = angle % 360;
        mBoundedRect.setRotation(mRotation);
        clearSelectState();
    }

    public boolean setInnerAspectRatio(int width, int height) {
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("Width and Height must be greater than zero");
        }
        RectF inner = mBoundedRect.getInner();
        CropMath.fixAspectRatioContained(inner, width, height);
        if (inner.width() < mMinSideSize || inner.height() < mMinSideSize) {
            return false;
        }
        mAspectWidth = width;
        mAspectHeight = height;
        mFixAspectRatio = true;
        mBoundedRect.setInner(inner);
        clearSelectState();
        return true;
    }

    public void setTouchTolerance(float tolerance) {
        if (tolerance <= 0) {
            throw new IllegalArgumentException("Tolerance must be greater than zero");
        }
        mTouchTolerance = tolerance;
    }

    public void setMinInnerSideSize(float minSide) {
        if (minSide <= 0) {
            throw new IllegalArgumentException("Min dide must be greater than zero");
        }
        mMinSideSize = minSide;
    }

    public void unsetAspectRatio() {
        mFixAspectRatio = false;
        clearSelectState();
    }

    public boolean hasSelectedEdge() {
        return mMovingEdges != MOVE_NONE;
    }

    public static boolean checkCorner(int selected) {
        return selected == TOP_LEFT || selected == TOP_RIGHT || selected == BOTTOM_RIGHT
                || selected == BOTTOM_LEFT;
    }

    public static boolean checkEdge(int selected) {
        return selected == MOVE_LEFT || selected == MOVE_TOP || selected == MOVE_RIGHT
                || selected == MOVE_BOTTOM;
    }

    public static boolean checkBlock(int selected) {
        return selected == MOVE_BLOCK;
    }

    public static boolean checkValid(int selected) {
        return selected == MOVE_NONE || checkBlock(selected) || checkEdge(selected)
                || checkCorner(selected);
    }

    public void clearSelectState() {
        mMovingEdges = MOVE_NONE;
    }

    public int wouldSelectEdge(float x, float y) {
        int edgeSelected = calculateSelectedEdge(x, y);
        if (edgeSelected != MOVE_NONE && edgeSelected != MOVE_BLOCK) {
            return edgeSelected;
        }
        return MOVE_NONE;
    }

    public boolean selectEdge(int edge) {
        if (!checkValid(edge)) {
            // temporary
            throw new IllegalArgumentException("bad edge selected");
            // return false;
        }
        if ((mFixAspectRatio && !checkCorner(edge)) && !checkBlock(edge)) {
            // temporary
            throw new IllegalArgumentException("bad corner selected");
            // return false;
        }
        mMovingEdges = edge;
        return true;
    }

    public boolean selectEdge(float x, float y) {
        int edgeSelected = calculateSelectedEdge(x, y);
        if (mFixAspectRatio) {
            edgeSelected = fixEdgeToCorner(edgeSelected);
        }
        if (edgeSelected == MOVE_NONE) {
            return false;
        }
        return selectEdge(edgeSelected);
    }

    public boolean moveCurrentSelection(float dX, float dY) {
        if (mMovingEdges == MOVE_NONE) {
            return false;
        }
        RectF crop = mBoundedRect.getInner();

        float minWidthHeight = mMinSideSize;

        int movingEdges = mMovingEdges;
        if (movingEdges == MOVE_BLOCK) {
            mBoundedRect.moveInner(dX, dY);
            return true;
        } else {
            float dx = 0;
            float dy = 0;

            if ((movingEdges & MOVE_LEFT) != 0) {
                dx = Math.min(crop.left + dX, crop.right - minWidthHeight) - crop.left;
            }
            if ((movingEdges & MOVE_TOP) != 0) {
                dy = Math.min(crop.top + dY, crop.bottom - minWidthHeight) - crop.top;
            }
            if ((movingEdges & MOVE_RIGHT) != 0) {
                dx = Math.max(crop.right + dX, crop.left + minWidthHeight)
                        - crop.right;
            }
            if ((movingEdges & MOVE_BOTTOM) != 0) {
                dy = Math.max(crop.bottom + dY, crop.top + minWidthHeight)
                        - crop.bottom;
            }

            if (mFixAspectRatio) {
                float[] l1 = {
                        crop.left, crop.bottom
                };
                float[] l2 = {
                        crop.right, crop.top
                };
                if (movingEdges == TOP_LEFT || movingEdges == BOTTOM_RIGHT) {
                    l1[1] = crop.top;
                    l2[1] = crop.bottom;
                }
                float[] b = {
                        l1[0] - l2[0], l1[1] - l2[1]
                };
                float[] disp = {
                        dx, dy
                };
                float[] bUnit = GeometryMath.normalize(b);
                float sp = GeometryMath.scalarProjection(disp, bUnit);
                dx = sp * bUnit[0];
                dy = sp * bUnit[1];
                RectF newCrop = fixedCornerResize(crop, movingEdges, dx, dy);

                mBoundedRect.fixedAspectResizeInner(newCrop);
            } else {
                if ((movingEdges & MOVE_LEFT) != 0) {
                    crop.left += dx;
                }
                if ((movingEdges & MOVE_TOP) != 0) {
                    crop.top += dy;
                }
                if ((movingEdges & MOVE_RIGHT) != 0) {
                    crop.right += dx;
                }
                if ((movingEdges & MOVE_BOTTOM) != 0) {
                    crop.bottom += dy;
                }
                mBoundedRect.resizeInner(crop);
            }
        }
        return true;
    }

    // Helper methods

    private int calculateSelectedEdge(float x, float y) {
        RectF cropped = mBoundedRect.getInner();

        float left = Math.abs(x - cropped.left);
        float right = Math.abs(x - cropped.right);
        float top = Math.abs(y - cropped.top);
        float bottom = Math.abs(y - cropped.bottom);

        int edgeSelected = MOVE_NONE;
        // Check left or right.
        if ((left <= mTouchTolerance) && ((y + mTouchTolerance) >= cropped.top)
                && ((y - mTouchTolerance) <= cropped.bottom) && (left < right)) {
            edgeSelected |= MOVE_LEFT;
        }
        else if ((right <= mTouchTolerance) && ((y + mTouchTolerance) >= cropped.top)
                && ((y - mTouchTolerance) <= cropped.bottom)) {
            edgeSelected |= MOVE_RIGHT;
        }

        // Check top or bottom.
        if ((top <= mTouchTolerance) && ((x + mTouchTolerance) >= cropped.left)
                && ((x - mTouchTolerance) <= cropped.right) && (top < bottom)) {
            edgeSelected |= MOVE_TOP;
        }
        else if ((bottom <= mTouchTolerance) && ((x + mTouchTolerance) >= cropped.left)
                && ((x - mTouchTolerance) <= cropped.right)) {
            edgeSelected |= MOVE_BOTTOM;
        }
        return edgeSelected;
    }

    private static RectF fixedCornerResize(RectF r, int moving_corner, float dx, float dy) {
        RectF newCrop = null;
        // Fix opposite corner in place and move sides
        if (moving_corner == BOTTOM_RIGHT) {
            newCrop = new RectF(r.left, r.top, r.left + r.width() + dx, r.top + r.height()
                    + dy);
        } else if (moving_corner == BOTTOM_LEFT) {
            newCrop = new RectF(r.right - r.width() + dx, r.top, r.right, r.top + r.height()
                    + dy);
        } else if (moving_corner == TOP_LEFT) {
            newCrop = new RectF(r.right - r.width() + dx, r.bottom - r.height() + dy,
                    r.right, r.bottom);
        } else if (moving_corner == TOP_RIGHT) {
            newCrop = new RectF(r.left, r.bottom - r.height() + dy, r.left
                    + r.width() + dx, r.bottom);
        }
        return newCrop;
    }

    private static int fixEdgeToCorner(int moving_edges) {
        if (moving_edges == MOVE_LEFT) {
            moving_edges |= MOVE_TOP;
        }
        if (moving_edges == MOVE_TOP) {
            moving_edges |= MOVE_LEFT;
        }
        if (moving_edges == MOVE_RIGHT) {
            moving_edges |= MOVE_BOTTOM;
        }
        if (moving_edges == MOVE_BOTTOM) {
            moving_edges |= MOVE_RIGHT;
        }
        return moving_edges;
    }

}
