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

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;

import com.android.gallery3d.R;

public class EclipseControl {
    private float mCenterX = Float.NaN;
    private float mCenterY = 0;
    private float mRadiusX = 200;
    private float mRadiusY = 300;
    private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips

    private float[] handlex = new float[9];
    private float[] handley = new float[9];
    private int mSliderColor;
    private int mCenterDotSize = 40;
    private float mDownX;
    private float mDownY;
    private float mDownCenterX;
    private float mDownCenterY;
    private float mDownRadiusX;
    private float mDownRadiusY;
    private Matrix mScrToImg;

    private boolean mShowReshapeHandles = true;
    public final static int HAN_CENTER = 0;
    public final static int HAN_NORTH = 7;
    public final static int HAN_NE = 8;
    public final static int HAN_EAST = 1;
    public final static int HAN_SE = 2;
    public final static int HAN_SOUTH = 3;
    public final static int HAN_SW = 4;
    public final static int HAN_WEST = 5;
    public final static int HAN_NW = 6;

    public EclipseControl(Context context) {
        mSliderColor = Color.WHITE;
    }

    public void setRadius(float x, float y) {
        mRadiusX = x;
        mRadiusY = y;
    }

    public void setCenter(float x, float y) {
        mCenterX = x;
        mCenterY = y;
    }

    public int getCloseHandle(float x, float y) {
        float min = Float.MAX_VALUE;
        int handle = -1;
        for (int i = 0; i < handlex.length; i++) {
            float dx = handlex[i] - x;
            float dy = handley[i] - y;
            float dist = dx * dx + dy * dy;
            if (dist < min) {
                min = dist;
                handle = i;
            }
        }

        if (min < MIN_TOUCH_DIST * MIN_TOUCH_DIST) {
            return handle;
        }
        for (int i = 0; i < handlex.length; i++) {
            float dx = handlex[i] - x;
            float dy = handley[i] - y;
            float dist = (float) Math.sqrt(dx * dx + dy * dy);
        }

        return -1;
    }

    public void setScrToImageMatrix(Matrix scrToImg) {
        mScrToImg = scrToImg;
    }

    public void actionDown(float x, float y, Oval oval) {
        float[] point = new float[] {
                x, y };
        mScrToImg.mapPoints(point);
        mDownX = point[0];
        mDownY = point[1];
        mDownCenterX = oval.getCenterX();
        mDownCenterY = oval.getCenterY();
        mDownRadiusX = oval.getRadiusX();
        mDownRadiusY = oval.getRadiusY();
    }

    public void actionMove(int handle, float x, float y, Oval oval) {
        float[] point = new float[] {
                x, y };
        mScrToImg.mapPoints(point);
        x = point[0];
        y = point[1];

        // Test if the matrix is swapping x and y
        point[0] = 0;
        point[1] = 1;
        mScrToImg.mapVectors(point);
        boolean swapxy = (point[0] > 0.0f);

        int sign = 1;
        switch (handle) {
            case HAN_CENTER:
                float ctrdx = mDownX - mDownCenterX;
                float ctrdy = mDownY - mDownCenterY;
                oval.setCenter(x - ctrdx, y - ctrdy);
                // setRepresentation(mVignetteRep);
                break;
            case HAN_NORTH:
                sign = -1;
            case HAN_SOUTH:
                if (swapxy) {
                    float raddx = mDownRadiusY - Math.abs(mDownX - mDownCenterY);
                    oval.setRadiusY(Math.abs(x - oval.getCenterY() + sign * raddx));
                } else {
                    float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY);
                    oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy));
                }
                break;
            case HAN_EAST:
                sign = -1;
            case HAN_WEST:
                if (swapxy) {
                    float raddy = mDownRadiusX - Math.abs(mDownY - mDownCenterX);
                    oval.setRadiusX(Math.abs(y - oval.getCenterX() + sign * raddy));
                } else {
                    float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX);
                    oval.setRadiusX(Math.abs(x - oval.getCenterX() - sign * raddx));
                }
                break;
            case HAN_SE:
            case HAN_NE:
            case HAN_SW:
            case HAN_NW:
                float sin45 = (float) Math.sin(45);
                float dr = (mDownRadiusX + mDownRadiusY) * sin45;
                float ctr_dx = mDownX - mDownCenterX;
                float ctr_dy = mDownY - mDownCenterY;
                float downRad = Math.abs(ctr_dx) + Math.abs(ctr_dy) - dr;
                float rx = oval.getRadiusX();
                float ry = oval.getRadiusY();
                float r = (Math.abs(rx) + Math.abs(ry)) * sin45;
                float dx = x - oval.getCenterX();
                float dy = y - oval.getCenterY();
                float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad);
                oval.setRadius(rx * nr / r, ry * nr / r);

                break;
        }
    }

    public void paintGrayPoint(Canvas canvas, float x, float y) {
        if (x == Float.NaN) {
            return;
        }

        Paint paint = new Paint();

        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE);
        int[] colors3 = new int[] {
                Color.GRAY, Color.LTGRAY, 0x66000000, 0 };
        RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
                0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
        paint.setShader(g);
        canvas.drawCircle(x, y, mCenterDotSize, paint);
    }

    public void paintPoint(Canvas canvas, float x, float y) {
        if (x == Float.NaN) {
            return;
        }

        Paint paint = new Paint();

        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE);
        int[] colors3 = new int[] {
                mSliderColor, mSliderColor, 0x66000000, 0 };
        RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
                0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
        paint.setShader(g);
        canvas.drawCircle(x, y, mCenterDotSize, paint);
    }

    void paintRadius(Canvas canvas, float cx, float cy, float rx, float ry) {
        if (cx == Float.NaN) {
            return;
        }
        int mSliderColor = 0xFF33B5E5;
        Paint paint = new Paint();
        RectF rect = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(6);
        paint.setColor(Color.BLACK);
        paintOvallines(canvas, rect, paint, cx, cy, rx, ry);

        paint.setStrokeWidth(3);
        paint.setColor(Color.WHITE);
        paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
    }

    public void paintOvallines(
            Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry) {
        canvas.drawOval(rect, paint);
        float da = 4;
        float arclen = da + da;
        if (mShowReshapeHandles) {
            paint.setStyle(Paint.Style.STROKE);

            for (int i = 0; i < 361; i += 90) {
                float dx = rx + 10;
                float dy = ry + 10;
                rect.left = cx - dx;
                rect.top = cy - dy;
                rect.right = cx + dx;
                rect.bottom = cy + dy;
                canvas.drawArc(rect, i - da, arclen, false, paint);
                dx = rx - 10;
                dy = ry - 10;
                rect.left = cx - dx;
                rect.top = cy - dy;
                rect.right = cx + dx;
                rect.bottom = cy + dy;
                canvas.drawArc(rect, i - da, arclen, false, paint);
            }
        }
        da *= 2;
        paint.setStyle(Paint.Style.FILL);

        for (int i = 45; i < 361; i += 90) {
            double angle = Math.PI * i / 180.;
            float x = cx + (float) (rx * Math.cos(angle));
            float y = cy + (float) (ry * Math.sin(angle));
            canvas.drawRect(x - da, y - da, x + da, y + da, paint);
        }
        paint.setStyle(Paint.Style.STROKE);
        rect.left = cx - rx;
        rect.top = cy - ry;
        rect.right = cx + rx;
        rect.bottom = cy + ry;
    }

    public void fillHandles(Canvas canvas, float cx, float cy, float rx, float ry) {
        handlex[0] = cx;
        handley[0] = cy;
        int k = 1;

        for (int i = 0; i < 360; i += 45) {
            double angle = Math.PI * i / 180.;

            float x = cx + (float) (rx * Math.cos(angle));
            float y = cy + (float) (ry * Math.sin(angle));
            handlex[k] = x;
            handley[k] = y;

            k++;
        }
    }

    public void draw(Canvas canvas) {
        paintRadius(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
        fillHandles(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
        paintPoint(canvas, mCenterX, mCenterY);
    }

    public boolean isUndefined() {
        return Float.isNaN(mCenterX);
    }

    public void setShowReshapeHandles(boolean showReshapeHandles) {
        this.mShowReshapeHandles = showReshapeHandles;
    }
}
