package com.savoirfairelinux.sflphone.model;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener
{
	private static final String TAG = BubblesView.class.getSimpleName();

	private BubblesThread thread = null;
	private BubbleModel model;

	private Paint attractor_paint = new Paint();
	private Paint name_paint = new Paint(Paint.ANTI_ALIAS_FLAG);

	private float density;
	private float textDensity;

	private boolean dragging_bubble = false;

	public BubblesView(Context context, AttributeSet attrs)
	{
		super(context, attrs);

		density = getResources().getDisplayMetrics().density;
		textDensity = getResources().getDisplayMetrics().scaledDensity;

		SurfaceHolder holder = getHolder();
		holder.addCallback(this);

		// create thread only; it's started in surfaceCreated()
		createThread();

		setOnTouchListener(this);
		setFocusable(true);

		attractor_paint.setColor(Color.RED);
		//attractor_paint.set
		name_paint.setTextSize(18 * textDensity);
		name_paint.setColor(0xFF303030);
		name_paint.setTextAlign(Align.CENTER);
	}

	private void createThread()
	{
		if (thread != null)
			return;
		thread = new BubblesThread(getHolder(), getContext(), new Handler() {
			@Override
			public void handleMessage(Message m)
			{
				/*  mStatusText.setVisibility(m.getData().getInt("viz"));
				  mStatusText.setText(m.getData().getString("text"));*/
			}
		});
		if (model != null)
			thread.setModel(model);
	}

	public void setModel(BubbleModel model)
	{
		this.model = model;
		thread.setModel(model);
	}

	/*@Override
	public void onWindowFocusChanged(boolean hasWindowFocus) {
		if (!hasWindowFocus) {
			thread.pause();
		}
	}*/

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
	{
		Log.w(TAG, "surfaceChanged");
		thread.setSurfaceSize(width, height);
	}

	/*
	 * Callback invoked when the Surface has been created and is ready to be
	 * used.
	 */
	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		// start the thread here so that we don't busy-wait in run()
		// waiting for the surface to be created
		createThread();

		Log.w(TAG, "surfaceCreated");
		thread.setRunning(true);
		thread.start();
	}

	/*
	 * Callback invoked when the Surface has been destroyed and must no longer
	 * be touched. WARNING: after this method returns, the Surface/Canvas must
	 * never be touched again!
	 */
	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		// we have to tell thread to shut down & wait for it to finish, or else
		// it might touch the Surface after we return and explode
		Log.w(TAG, "surfaceDestroyed");
		boolean retry = true;
		thread.setRunning(false);
		while (retry) {
			try {
				thread.join();
				retry = false;
			} catch (InterruptedException e) {
			}
		}
		thread = null;
	}

	@Override
	public boolean onTouch(View v, MotionEvent event)
	{
		Log.w(TAG, "onTouch " + event.getAction());

		int action = event.getActionMasked();

		synchronized (model) {
			List<Bubble> bubbles = model.getBubbles();
			final int n_bubbles = bubbles.size();

			if (action == MotionEvent.ACTION_DOWN) {
				for (int i = 0; i < n_bubbles; i++) {
					Bubble b = bubbles.get(i);
					if (b.intersects(event.getX(), event.getY())) {
						b.dragged = true;
						b.last_drag = System.nanoTime();
						b.setPos(event.getX(), event.getY());
						b.target_scale = .8f;
						dragging_bubble = true;
					}
				}
			} else if (action == MotionEvent.ACTION_MOVE) {
				long now = System.nanoTime();
				for (int i = 0; i < n_bubbles; i++) {
					Bubble b = bubbles.get(i);
					if (b.dragged) {
						float x = event.getX(), y = event.getY();
						float dt = (float) ((now - b.last_drag) / 1000000000.);
						float dx = x - b.getPosX(), dy = y - b.getPosY();
						b.last_drag = now;

						b.setPos(event.getX(), event.getY());
						/*int hn = event.getHistorySize() - 2;
						Log.w(TAG, "event.getHistorySize() : " + event.getHistorySize());
						if(hn > 0) {
						float dx = x-event.getHistoricalX(hn);
						float dy = y-event.getHistoricalY(hn);
						float dt = event.getHistoricalEventTime(hn)/1000.f;*/
						b.speed.x = dx / dt;
						b.speed.y = dy / dt;
						//Log.w(TAG, "onTouch dx:" + b.speed.x + " dy:" + b.speed.y);
						//}
						return true;
					}
				}
			} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
				for (int i = 0; i < n_bubbles; i++) {
					Bubble b = bubbles.get(i);
					if (b.dragged) {
						b.dragged = false;
						b.target_scale = 1.f;
					}
				}
				dragging_bubble = false;
			}
		}

		return true;
	}

	public boolean isDraggingBubble()
	{
		return dragging_bubble;
	}

	class BubblesThread extends Thread
	{
		private boolean running = false;
		private SurfaceHolder surfaceHolder;

		BubbleModel model = null;

		public BubblesThread(SurfaceHolder holder, Context context, Handler handler)
		{
			surfaceHolder = holder;
		}

		public void setModel(BubbleModel model)
		{
			this.model = model;
		}

		@Override
		public void run()
		{
			while (running) {
				Canvas c = null;
				try {
					c = surfaceHolder.lockCanvas(null);

					// for the case the surface is destroyed while already in the loop
					if (c == null || model == null)
						continue;

					synchronized (surfaceHolder) {
						//Log.w(TAG, "Thread doDraw");
						model.update();
						doDraw(c);
					}
				} finally {
					if (c != null)
						surfaceHolder.unlockCanvasAndPost(c);
				}
			}
		}

		public void setRunning(boolean b)
		{
			running = b;
		}

		public void setSurfaceSize(int width, int height)
		{
			synchronized (surfaceHolder) {
				if (model != null) {
					model.width = width;
					model.height = height;
				}
			}
		}

		private void doDraw(Canvas canvas)
		{
			canvas.drawColor(Color.WHITE);

			synchronized (model) {
				List<Bubble> bubbles = model.getBubbles();
				List<Attractor> attractors = model.getAttractors();

				for (int i = 0, n = attractors.size(); i < n; i++) {
					Attractor a = attractors.get(i);
					canvas.drawBitmap(a.getBitmap(), null, a.getBounds(), null);
				}

				for (int i = 0, n = bubbles.size(); i < n; i++) {
					Bubble b = bubbles.get(i);
					canvas.drawBitmap(b.getBitmap(), null, b.getBounds(), null);
					canvas.drawText(b.contact.getmDisplayName(), b.getPosX(), b.getPosY() - 50 * density, name_paint);
				}
			}
		}
	}

}
