package com.kurukurupapa.tryandroidui.dialog;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

/**
 * 比較的少ない色数から色を選択するビュー
 */
public class SimpleColorPicker extends ImageView {
	public interface OnColorChangedListener {
		void onColorChanged(int color);
	}

	public OnColorChangedListener listener;
	public int selectedColor;

	private static final int STROKE_WIDTH = 5;
	private Paint boxPaint;
	private Paint framePaint;
	private Paint selectedPaint;
	private ArrayList<Integer> monoList;
	private ArrayList<Integer> color1List;
	private ArrayList<Integer> color2List;
	private ArrayList<Integer> allList;

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

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

	private void setup(Context context) {
		boxPaint = new Paint();
		boxPaint.setStyle(Style.FILL);

		framePaint = new Paint();
		framePaint.setStyle(Style.STROKE);
		framePaint.setColor(Color.BLACK);
		framePaint.setStrokeWidth(STROKE_WIDTH);

		selectedPaint = new Paint();
		selectedPaint.setStyle(Style.STROKE);
		selectedPaint.setColor(Color.WHITE);
		selectedPaint.setStrokeWidth(STROKE_WIDTH);

		monoList = new ArrayList<Integer>();
		monoList.add(Color.BLACK);
		monoList.add(Color.rgb(0x80, 0x80, 0x80));
		monoList.add(Color.rgb(0xC0, 0xC0, 0xC0));
		monoList.add(Color.WHITE);

		color1List = new ArrayList<Integer>();
		color1List.add(Color.rgb(0xFF, 0x00, 0x00));
		color1List.add(Color.rgb(0xFF, 0xFF, 0x00));
		color1List.add(Color.rgb(0x00, 0xFF, 0x00));
		color1List.add(Color.rgb(0x00, 0xFF, 0xFF));
		color1List.add(Color.rgb(0x00, 0x00, 0xFF));
		color1List.add(Color.rgb(0xFF, 0x00, 0xFF));

		color2List = new ArrayList<Integer>();
		color2List.add(Color.rgb(0x80, 0x00, 0x00));
		color2List.add(Color.rgb(0x80, 0x80, 0x00));
		color2List.add(Color.rgb(0x00, 0x80, 0x00));
		color2List.add(Color.rgb(0x00, 0x80, 0x80));
		color2List.add(Color.rgb(0x00, 0x00, 0x80));
		color2List.add(Color.rgb(0x80, 0x00, 0x80));

		allList = new ArrayList<Integer>();
		allList.addAll(monoList);
		allList.addAll(color1List);
		allList.addAll(color2List);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		// 引数で渡された、可能な最大サイズを設定する。
		int width = MeasureSpec.getSize(widthMeasureSpec);
		int height = MeasureSpec.getSize(heightMeasureSpec);
		setMeasuredDimension(width, height);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		int right = getWidth() - 1;
		int bottom = getHeight() - 1;

		List<RectF> rectList = getVerticalRectList(0, 0, right, bottom,
				allList.size());
		drawBox(canvas, rectList, allList);
	}

	private List<RectF> getVerticalRectList(float left, float top, float right,
			float bottom, int colorNum) {
		List<RectF> list = new ArrayList<RectF>();

		double dy = getBoxHeight(top, bottom, colorNum);
		for (int i = 0; i < colorNum; i++) {
			float t = (float) (top + dy * i);
			float b = (float) (top + dy * (i + 1) - 1);
			list.add(new RectF(left, t, right, b));
		}

		return list;
	}

	private void drawBox(Canvas canvas, List<RectF> rectList,
			List<Integer> colorList) {

		int num = colorList.size();
		int selectedIndex = -1;
		for (int i = 0; i < num; i++) {
			int color = colorList.get(i);
			drawBox(canvas, rectList.get(i), color);

			if (color == selectedColor) {
				selectedIndex = i;
			}
		}

		if (selectedIndex >= 0) {
			drawSelectedFrame(canvas, rectList.get(selectedIndex));
		}
	}

	private double getBoxHeight(float top, float bottom, int num) {
		return (double) (bottom - top + 1) / num;
	}

	private void drawBox(Canvas canvas, RectF rect, int color) {
		boxPaint.setColor(color);
		canvas.drawRect(rect, boxPaint);
		canvas.drawRect(rect, framePaint);
	}

	private void drawSelectedFrame(Canvas canvas, RectF rect) {
		canvas.drawRect(rect, selectedPaint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_UP) {
			double dy = getBoxHeight(0, getHeight() - 1, allList.size());
			float y = event.getY();
			int selectedIndex = (int) (y / dy);
			selectedColor = allList.get(selectedIndex);
			invalidate();
			if (listener != null) {
				listener.onColorChanged(selectedColor);
			}
		}

		return true;
	}

}
