package de.greenrobot.multitouchtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnTouchListener;

/**
 * Demonstrates multitouch capabilities and visualizes MotionEvents.
 * 
 * @author Markus Junginger, greenrobot
 */
public class MultitouchActivity extends Activity implements OnTouchListener {

    private static final int MAX_POINTERS = 20;

    private TouchView touchView;
    private Paint paint;
    private Paint paintInfoText;

    private PointF[] points;
    private int[] lastActions;
    private int pointerCount;

    private float displayDensity;
    private int radius;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        displayDensity = getResources().getDisplayMetrics().density;

        points = new PointF[MAX_POINTERS];
        lastActions = new int[MAX_POINTERS];

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(calcDevicePixels(15));

        paintInfoText = new Paint();
        paintInfoText.setColor(Color.BLACK);
        paintInfoText.setAntiAlias(true);
        paintInfoText.setTextSize(calcDevicePixels(18));

        touchView = new TouchView(this);
        touchView.setOnTouchListener(this);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(touchView);

        radius = calcDevicePixels(80);
    }

    public int calcDevicePixels(int deviceIndependentPixel) {
        return (int) (deviceIndependentPixel * displayDensity + 0.5f);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction() & MotionEvent.ACTION_MASK;
        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
        pointerCount = event.getPointerCount();

        int actionId = event.getPointerId(pointerIndex);
        Log.d("greenrobot", "MotionEvent - pointer ID:  " + actionId + ", action: " + mapActionCodeToString(action)
                + ", pointer count: " + pointerCount);
        if (actionId < MAX_POINTERS) {
            lastActions[actionId] = action;
        }

        for (int i = 0; i < pointerCount; i++) {
            int pointerId = event.getPointerId(i);
            if (pointerId < MAX_POINTERS) {
                points[pointerId] = new PointF(event.getX(i), event.getY(i));
                if (action == MotionEvent.ACTION_MOVE) {
                    lastActions[pointerId] = action;
                }
            }
        }

        touchView.invalidate();
        return true;
    }

    private class TouchView extends View {

        public TouchView(Context context) {
            super(context);
            setBackgroundColor(Color.WHITE);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            for (int i = 0; i < MAX_POINTERS; i++) {
                PointF point = points[i];
                if (point != null) {
                    paint.setColor(getColor(i));
                    canvas.drawCircle(point.x, point.y, radius, paint);
                    String text = getActionText(i);
                    float textWidth = paint.measureText(text);
                    canvas.drawText(text, point.x - textWidth / 2, point.y - radius - calcDevicePixels(8), paint);
                }
            }
            canvas.drawText("Last pointer count: " + pointerCount, 10, calcDevicePixels(30), paintInfoText);
        }
    }

    public int getColor(int pointerId) {
        int color;
        switch (lastActions[pointerId]) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            color = 0xaa0000ff; // blue
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            color = 0xaa999999; // grey
            break;
        case MotionEvent.ACTION_MOVE:
            color = 0xaa00ff00; // green
            break;
        default:
            color = 0xaaFF0000; // red
        }
        return color;
    }

    public String getActionText(int pointerId) {
        String action = mapActionCodeToString(lastActions[pointerId]);
        return pointerId + ": " + action;
    }

    private String mapActionCodeToString(int actionCode) {
        String action;
        switch (actionCode) {
        case MotionEvent.ACTION_DOWN:
            action = "Down";
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            action = "Pointer Down";
            break;
        case MotionEvent.ACTION_UP:
            action = "Up";
            break;
        case MotionEvent.ACTION_POINTER_UP:
            action = "Pointer Up";
            break;
        case MotionEvent.ACTION_MOVE:
            action = "Move";
            break;
        default:
            action = "Other (" + actionCode + ")";
        }
        return action;
    }

}

