package juloo.keyboard2;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

public class Keyboard2View extends View
	implements View.OnTouchListener
{
	private static final float	KEY_PER_ROW = 10;
	private static final float	KEY_MARGIN_DPI = 2;
	private static final float	KEY_PADDING_DPI = 6;
	private static final float	KEY_HEIGHT_DPI = 40;
	private static final float	KEY_LABEL_DPI = 16;
	private static final float	KEY_SUBLABEL_DPI = 12;

	private Keyboard2		_ime;
	private KeyboardData	_keyboard;

	private float			_keyWidth;
	private float			_keyHeight;
	private float			_keyMargin;
	private float			_keyPadding;

	private Paint			_keyBgPaint;
	private Paint			_keyDownBgPaint;
	private Paint			_keyLabelPaint;
	private Paint			_keySubLabelPaint;

	public Keyboard2View(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		DisplayMetrics dm = context.getResources().getDisplayMetrics();
		_keyMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, KEY_MARGIN_DPI, dm);
		_keyHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, KEY_HEIGHT_DPI, dm);
		_keyPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, KEY_PADDING_DPI, dm);
		_keyWidth = (dm.widthPixels - _keyMargin) / KEY_PER_ROW - _keyMargin;
		_keyBgPaint = new Paint();
		_keyBgPaint.setColor(getResources().getColor(R.color.key_bg));
		_keyDownBgPaint = new Paint();
		_keyDownBgPaint.setColor(getResources().getColor(R.color.key_down_bg));
		_keyLabelPaint = new Paint();
		_keyLabelPaint.setColor(getResources().getColor(R.color.key_label));
		_keyLabelPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, KEY_LABEL_DPI, dm));
		_keyLabelPaint.setTextAlign(Paint.Align.CENTER);
		_keySubLabelPaint = new Paint();
		_keySubLabelPaint.setColor(getResources().getColor(R.color.key_label));
		_keySubLabelPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, KEY_SUBLABEL_DPI, dm));
		_keySubLabelPaint.setTextAlign(Paint.Align.CENTER);
		setOnTouchListener(this);
	}

	public void			setKeyboard(Keyboard2 ime, KeyboardData keyboardData)
	{
		_ime = ime;
		_keyboard = keyboardData;
	}

	@Override
	public boolean		onTouch(View v, MotionEvent event)
	{
		float				x;
		float				y;
		float				keyW;
		int					p;

		switch (event.getActionMasked())
		{
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			onTouchUp(event.getPointerId(event.getActionIndex()));
			break ;
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
			p = event.getActionIndex();
			onTouchDown(event.getX(p), event.getY(p), event.getPointerId(p));
			break ;
		case MotionEvent.ACTION_MOVE:
			for (p = 0; p < event.getPointerCount(); p++)
				onTouchMove(event.getX(p), event.getY(p), event.getPointerId(p));
			break ;
		default:
			return (false);
		}
		return (true);
	}

	private void		onTouchMove(float moveX, float moveY, int pointerId)
	{
		for (KeyboardData.Row row : _keyboard.getRows())
		{
			for (KeyboardData.Key k : row)
			{
				if (k.downPointer == pointerId)
				{
					KeyValue v = k.getDownValue(moveX, moveY);
					if (v != k.downValue)
					{
						k.downValue = v;
						Keyboard2.log("Key down " + v.getName());
					}
				}
			}
		}
	}

	private void		onTouchDown(float touchX, float touchY, int pointerId)
	{
		float				x;
		float				y;
		float				keyW;

		y = -_keyHeight;
		for (KeyboardData.Row row : _keyboard.getRows())
		{
			y += _keyHeight + _keyMargin;
			if (touchY < y || touchY >= (y + _keyHeight))
				continue ;
			x = (KEY_PER_ROW * (_keyMargin + _keyWidth) - _keyMargin - row.getWidth(_keyWidth, _keyMargin)) / 2 + _keyMargin;
			for (KeyboardData.Key k : row)
			{
				keyW = _keyWidth * k.width;
				if (touchX >= x && touchX < (x + keyW) && k.downPointer == -1)
				{
					if (k.key0 != null)
						Keyboard2.log("Key down " + k.key0.getName());
					k.downPointer = pointerId;
					k.downValue = k.key0;
					k.downX = touchX;
					k.downY = touchY;
					invalidate();
					return ;
				}
				x += keyW + _keyMargin;
			}
		}
	}

	private void		onTouchUp(int pointerId)
	{
		for (KeyboardData.Row row : _keyboard.getRows())
		{
			for (KeyboardData.Key k : row)
			{
				if (k.downPointer == pointerId)
				{
					if (k.downValue != null)
						Keyboard2.log("Key up " + k.downValue.getName());
					k.downPointer = -1;
					invalidate();
				}
			}
		}
	}

	@Override
	public void			onMeasure(int wSpec, int hSpec)
	{
		int					height;

		if (_keyboard.getRows() == null)
			height = 0;
		else
			height = (int)((_keyHeight + _keyMargin) * ((float)_keyboard.getRows().size()) + _keyMargin);
		setMeasuredDimension(MeasureSpec.getSize(wSpec), height);
	}

	@Override
	protected void		onDraw(Canvas canvas)
	{
		float				x;
		float				y;

		y = _keyMargin;
		for (KeyboardData.Row row : _keyboard.getRows())
		{
			x = (KEY_PER_ROW * (_keyMargin + _keyWidth) - _keyMargin - row.getWidth(_keyWidth, _keyMargin)) / 2 + _keyMargin;
			for (KeyboardData.Key k : row)
			{
				float keyW = _keyWidth * k.width;
				if (k.downPointer != -1)
					canvas.drawRect(x, y, x + keyW, y + _keyHeight, _keyDownBgPaint);
				else
					canvas.drawRect(x, y, x + keyW, y + _keyHeight, _keyBgPaint);
				if (k.key0 != null)
					canvas.drawText(new char[]{k.key0.getChar()}, 0, 1,
						keyW / 2 + x, (_keyHeight + _keyLabelPaint.getTextSize()) / 2 + y, _keyLabelPaint);
				if (k.key1 != null)
					canvas.drawText(new char[]{k.key1.getChar()}, 0, 1,
						x + _keyPadding, y + _keyPadding, _keySubLabelPaint);
				if (k.key2 != null)
					canvas.drawText(new char[]{k.key2.getChar()}, 0, 1,
						x + keyW - _keyPadding, y + _keyPadding, _keySubLabelPaint);
				if (k.key3 != null)
					canvas.drawText(new char[]{k.key3.getChar()}, 0, 1,
						x + _keyPadding, y + _keyHeight - _keyPadding, _keySubLabelPaint);
				if (k.key4 != null)
					canvas.drawText(new char[]{k.key4.getChar()}, 0, 1,
						x + keyW - _keyPadding, y + _keyHeight - _keyPadding, _keySubLabelPaint);
				x += keyW + _keyMargin;
			}
			y += _keyHeight + _keyMargin;
		}
	}
}
