package com.kurukurupapa.tryandroidui.dialog;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 色選択ビュー
 *
 * 元ネタ<br>
 * Y.A.M の 雑記帳: Android　ColorPickerDialog を作った
 * http://y-anz-m.blogspot.com/2010/05/androidcolorpickerdialog.html
 */
public class BoxHsvColorPicker extends View {
	public interface OnColorListener {
		void onColorChanging(int color);

		void onColorChanged(int color);
	}

	private static final int CENTER_X = 100;
	private static final int CENTER_Y = 100;
	private static final float OK_X0 = -CENTER_X / 2;
	private static final float OK_X1 = CENTER_X / 2;
	private static final float OK_Y0 = (float) (CENTER_X * 1.2);
	private static final float OK_Y1 = (float) (CENTER_X * 1.5);

	private OnColorListener mListener;

	private boolean mTrackingOK;
	private boolean mHighlightOK;

	BoxHsvColorPickerHueHelper hueHelper;
	BoxHsvColorPickerSvHelper svHelper;

	public BoxHsvColorPicker(Context context) {
		super(context);
		setup();
	}

	public BoxHsvColorPicker(Context context, AttributeSet attrs) {
		super(context, attrs);
		setup();
	}

	private void setup() {
		hueHelper = new BoxHsvColorPickerHueHelper(CENTER_X, 24);
		svHelper = new BoxHsvColorPickerSvHelper(OK_X0, OK_X0, OK_X1, OK_X1, 5);
		setSelectColor(Color.RED);
	}

	public void setColorNum(int hueNum, int svNum) {
		hueHelper.setColorNum(hueNum);
		svHelper.setColorNum(svNum);
	}

	public void setSelectColor(int color) {
		hueHelper.setSelectColorFromColor(color);
		svHelper.setSelectColorFromColor(color);
		invalidate();
	}

	public int getSelectColor() {
		return svHelper.getSelectColor(hueHelper.getHue());
	}

	public void setOnColorListener(OnColorListener l) {
		mListener = l;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.translate(CENTER_X, CENTER_X);
		hueHelper.drawOval(canvas);
		svHelper.drawSVRegion(canvas, hueHelper.getHue());
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		setMeasuredDimension(CENTER_X * 2, CENTER_Y * 2);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		float x = event.getX() - CENTER_X;
		float y = event.getY() - CENTER_Y;
		float r = (float) (java.lang.Math.sqrt(x * x + y * y));
		boolean inOK = false;
		boolean inOval = false;
		boolean inRect = false;

		if (r <= CENTER_X) {
			if (hueHelper.contains(r)) {
				inOval = true;
			} else if (svHelper.contains(x, y)) {
				inRect = true;
			}
		} else if (x >= OK_X0 && x < OK_X1 && y >= OK_Y0 && y < OK_Y1) {
			inOK = true;
		}

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mTrackingOK = inOK;
			if (inOK) {
				mHighlightOK = true;
				invalidate();
				break;
			}
			// 続けてACTION_MOVEの処理を実施する

		case MotionEvent.ACTION_MOVE:
			if (mTrackingOK) {
				if (mHighlightOK != inOK) {
					mHighlightOK = inOK;
					invalidate();
				}
			} else if (inOval) {
				// 色相環を操作されている場合
				hueHelper.setSelectColorFromXY(x, y);
				invalidate();

			} else if (inRect) {
				// 明度、彩度を操作されている場合
				svHelper.setSelectColorFromXY(x, y);
				invalidate();
			}

			// リスナーへ通知
			if (mListener != null) {
				mListener.onColorChanging(getSelectColor());
			}
			break;

		case MotionEvent.ACTION_UP:
			if (mTrackingOK) {
				if (inOK) {
					mListener.onColorChanged(getSelectColor());
				}
				mTrackingOK = false; // so we draw w/o halo
				invalidate();
			}

			// リスナーへ通知
			if (mListener != null) {
				mListener.onColorChanged(getSelectColor());
			}
			break;
		}
		return true;
	}

}
