package jp.agentec.abook.abv.ui.viewer.view;

import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class TouchDrawView extends View {

	public static final int PEN = 0; // ペン定数
	public static final int MARKER = 1; // マーカー定数
	public static final int ERASER = 2; // 消しゴム定数

	public boolean editFlg; // 編集フラグ何か書いたらtrue
	public int mode; // 現在モード

	private static final float TOUCH_TOLERANCE = 0;

	private Canvas mCanvas; // マーキング用Canvas
	public Bitmap mBitmap = null; // 表示用ビットマップ
	private Bitmap srcImage;

	private Paint mBitmapPaint; // ビットマップ用ペイント
	public Paint mPaint; // メインペイント
	private Paint eraserCursorPaint; // 消しゴム用ペイント
	private Path mPath; // パス

	private float mX;
    private float mY; // タッチポイント
	private boolean isTouching;

	private OnDrawMarkingListener listener;
	public boolean drawable;

	public interface OnDrawMarkingListener {
		void onDrawMarking(int action, float x, float y);
	}

	public TouchDrawView(Context context, Bitmap image, OnDrawMarkingListener listener) {
		super(context);

		this.listener = listener;

		// ビットマップペイント初期化
		mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		// パス初期化
		mPath = new Path();
		editFlg = false;
		this.srcImage = image;
		initEraserCursorPaint();

		setFocusable(true);
		setWillNotDraw(false);
	}

	// 消しゴムカーソルペイント初期化
	private void initEraserCursorPaint() {
		eraserCursorPaint = new Paint();
		eraserCursorPaint.setColor(Color.BLUE);
		eraserCursorPaint.setStyle(Paint.Style.STROKE);
		eraserCursorPaint.setStrokeWidth(5);
		eraserCursorPaint.setAntiAlias(true);
	}

	// タッチイベント
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(drawable){
			drawMarking(event.getAction(), event.getX(), event.getY());
		}
		return drawable;
	}

	// 描画
	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        if (mode == ERASER) {
            if (isTouching) {
                canvas.drawCircle(mX, mY, mPaint.getStrokeWidth() / 2, eraserCursorPaint);
            }
        } else {
            canvas.drawPath(mPath, mPaint);
        }
	}

	// 画面サイズ変更時
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		try {
			mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
			mCanvas = new Canvas(mBitmap);
			drawSrcBitmap();
		} catch (OutOfMemoryError e) {
			Logger.e("", "onSizeChanged failed.", e);
			ABVToastUtil.showMakeText(getContext(), R.string.OUT_OF_MEMORY, Toast.LENGTH_SHORT);
		}
	}

	private void drawMarking(int action, float x, float y) {
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			isTouching = true;
			touch_start(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			isTouching = true;
			touch_move(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			isTouching = false;
			touch_up();
			invalidate();
			break;
		}

		if (listener != null) {
			listener.onDrawMarking(action, x, y);
		}
	}

	public void remoteDrawMarking(int action, float x, float y) {
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			isTouching = true;
			touch_start(x, y);
			break;
		case MotionEvent.ACTION_MOVE:
			isTouching = true;
			touch_move(x, y);
			break;
		case MotionEvent.ACTION_UP:
			isTouching = false;
			touch_up();
			break;
		}
	}

	// タッチ開始
	private void touch_start(float x, float y) {
		// 編集フラグをtrue
		editFlg = true;
		mPath.reset();
		mPath.moveTo(x, y);
		mX = x;
		mY = y;
	}

	// タッチ移動
	private void touch_move(float x, float y) {
		float dx = Math.abs(x - mX);
		float dy = Math.abs(y - mY);
		if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
			mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);

			if (mode == ERASER) {
				mCanvas.drawPath(mPath, mPaint);
			}

			mX = x;
			mY = y;
		}
	}

	// タッチ終了
	private void touch_up() {
		if (mode != ERASER) {
			mPath.lineTo(mX, mY);
			mCanvas.drawPath(mPath, mPaint);
		}
		mPath.reset();
	}

	// マーキングクリア
	public void clear() {
		editFlg = true;
		mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
		invalidate();
	}

	// ファイルロード
	private void drawSrcBitmap() {
		if (srcImage != null) {
			// 表示領域いっぱいにリサイズ
			Rect srcRect = new Rect(0, 0, srcImage.getWidth(), srcImage.getHeight());
			Rect dstRect = new Rect(0, 0, getWidth(), getHeight());
			mCanvas.drawBitmap(srcImage, srcRect, dstRect, mBitmapPaint);
			invalidate();
			srcImage.recycle();
		}
	}

	public void setPaint(Paint paint, int mode) {
		this.mode = mode;
		mPaint = paint;
	}
}
