package com.kurukurupapa.tryandroidui.dialog;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;

public class BoxHsvColorPickerSvHelper {
	// 明度、彩度の色と色の隙間
	private final float SV_SPACE = 2.0f;
	private final float SV_HARF_SPACE = SV_SPACE / 2.0f;

	// 明度、彩度の各々の色数
	private int svNum;
	// 描画範囲
	private float left;
	private float top;
	private float right;
	private float bottom;
	// 選択されているインデックス
	private int selectX;
	private int selectY;

	private Paint paint;
	private Paint selectPaint;

	public BoxHsvColorPickerSvHelper(float left, float top, float right,
			float bottom, int svNum) {
		this.left = left;
		this.top = top;
		this.right = right;
		this.bottom = bottom;

		paint = new Paint();
		paint.setStyle(Paint.Style.FILL);

		selectPaint = new Paint();
		selectPaint.setStyle(Paint.Style.STROKE);
		selectPaint.setColor(Color.WHITE);

		setColorNum(svNum);
	}

	public void setColorNum(int svNum) {
		this.svNum = svNum;
	}

	public void drawSVRegion(Canvas canvas, float selectHue) {
		double dx = (right - left) / svNum;
		double dy = (bottom - top) / svNum;

		for (int y = 0; y < svNum; y++) {
			for (int x = 0; x < svNum; x++) {

				// 位置
				RectF rect = new RectF();
				rect.left = (float) (left + x * dx + SV_HARF_SPACE);
				rect.right = (float) (left + (x + 1) * dx - SV_HARF_SPACE);
				rect.top = (float) (top + y * dy + SV_HARF_SPACE);
				rect.bottom = (float) (top + (y + 1) * dy - SV_HARF_SPACE);

				// 色
				paint.setColor(getColorFromIndex(selectHue, x, y));

				// 描画
				canvas.drawRect(rect, paint);

				// 選択枠
				if (x == selectX && y == selectY) {
					canvas.drawRect(rect.left - SV_HARF_SPACE, rect.top
							- SV_HARF_SPACE, rect.right + SV_HARF_SPACE,
							rect.bottom + SV_HARF_SPACE, selectPaint);
				}
			}
		}
	}

	private int getColorFromIndex(float selectHue, int xindex, int yindex) {
		return getHSVColor(selectHue, (float) xindex / (svNum - 1),
				(float) yindex / (svNum - 1));
	}

	private int getHSVColor(float hue, float saturation, float value) {
		float[] hsv = new float[3];
		if (hue >= 360)
			hue = 359;
		else if (hue < 0)
			hue = 0;

		if (saturation > 1)
			saturation = 1;
		else if (saturation < 0)
			saturation = 0;

		if (value > 1)
			value = 1;
		else if (value < 0)
			value = 0;

		hsv[0] = hue;
		hsv[1] = saturation;
		hsv[2] = value;

		return Color.HSVToColor(hsv);
	}

	public void setSelectColorFromXY(float x, float y) {
		selectX = (int) Math.floor(svNum * (x - left) / (right - left + 1));
		selectY = (int) Math.floor(svNum * (y - top) / (bottom - top + 1));
	}

	public void setSelectColorFromColor(int color) {
		float[] sv = getSv(color);
		selectX = Math.round(svNum * sv[0]);
		selectY = Math.round(svNum * sv[1]);
	}

	public boolean contains(float x, float y) {
		return x >= left && x < right && y >= top && y < bottom;
	}

	public int getSelectColor(float selectHue) {
		return getColorFromIndex(selectHue, selectX, selectY);
	}

	private float[] getSv(int color) {
		float hsv[] = new float[3];
		Color.colorToHSV(color, hsv);
		return new float[] { hsv[1], hsv[2] };
	}

}
