/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.vostan.banvor.board;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

import org.vostan.banvor.model.PuzzleChoreographer;
import org.vostan.banvor.model.Puzzle;
import org.vostan.banvor.model.XYPair;

//import android.support.v4.view.GestureDetectorCompat;

/**
 *
 * @author vahagnk
 */
public class PuzzleControl extends PuzzleView
						implements GestureDetector.OnGestureListener
								, GestureDetector.OnDoubleTapListener
								, ScaleGestureDetector.OnScaleGestureListener
								, Animator.AnimationLister
{
	protected GestureDetector simpled;
	protected ScaleGestureDetector scaled;
	protected PuzzleChoreographer choregrapher;
	protected Animator animator;
	protected PuzzleAnimator puzzleAnimator;
	protected PuzzleControlLister lister;

	protected float lastSpan;
	protected XYPair singleTapTile = new XYPair();
	
	public interface PuzzleControlLister
	{
		public void onSolved();
		public void onLongPress();
		public void onTouch();
	}
	
	public PuzzleControl(Context c, AttributeSet attributeSet)
	{
		super(c,attributeSet);
		choregrapher = new PuzzleChoreographer();
		animator = new Animator( this );
		animator.setAnimationLister(this);
		puzzleAnimator = new PuzzleAnimator(animator);

		simpled = new GestureDetector( c, this );
		simpled.setOnDoubleTapListener(this);
		scaled = new ScaleGestureDetector( c, this );
	}
	
	public void setPuzzle( Puzzle p )
	{
		super.setPuzzle(p);
		choregrapher.setPuzzle(p);
	}

	public void setPuzzleControlLister( PuzzleControlLister l )
	{
		lister = l;
	}

	public void undoLastMove(){
		if ( getPuzzle().isUndoable() ){
			getPuzzle().restore();
			invalidate();
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		//
		//	Stop any pending animations.
		//
		animator.stop();
		animator.clear();
		//
		//	Pass this event to scale and gesture detectors.
		//
		boolean r = scaled.onTouchEvent(event);
		r = simpled.onTouchEvent(event) || r;
		//r = super.onTouchEvent(event) || r;
		return r;
	}
	
	public boolean onDown(MotionEvent e)
	{
		return true;
	}
	public void onLongPress(MotionEvent e)
	{
		if ( lister != null )
			lister.onLongPress();
	}
	public void onShowPress(MotionEvent e)
	{
	}
	public boolean onSingleTapUp(MotionEvent e)
	{
		return true;
	}
	public boolean onDoubleTap(MotionEvent e)
	{
		return true;
	}
	public boolean onDoubleTapEvent(MotionEvent e)
	{
		return true;
	}

	public boolean onSingleTapConfirmed(MotionEvent e)
	{
		//
		//	Translate the tap point into tile column and row.
		//
		getTile( e.getX(), e.getY(), singleTapTile );
		//
		//	If the tap is not on a valid tile then there is not point to
		//	continue.
		//
		if ( !puzzle.isValid(singleTapTile) )
			return true;
		//
		//	Create sequence of steps and then animate it.
		//
		if ( choregrapher.createSteps(puzzleAnimator, singleTapTile))
		{
			puzzle.save();
			animator.play();
		}
		//
		//	Notify that we were touched.
		//
		if ( lister != null )
			lister.onTouch();
		//
		//	This event is processed.
		//
		return true;
	}
		
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
	{
		return true;
	}

	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
	{
		scrollViewport( distanceX, distanceY );
		return true;
	}
	
	public boolean onScaleBegin(ScaleGestureDetector detector)
	{
		lastSpan = scaled.getCurrentSpan();
		return true;
	}
	
	public boolean onScale(ScaleGestureDetector detector)
	{
		float span = scaled.getCurrentSpan();
		float focusX = scaled.getFocusX();
		float focusY = scaled.getFocusY();
		scaleViewport(focusX,focusY,lastSpan/span);
		lastSpan = span;
		return true;
	}
	
	public void onScaleEnd(ScaleGestureDetector detector)
	{
		scaleViewportDone();
	}
	
	public void onAnimationEnd()
	{
		if ( puzzle.isDone() )
			if ( lister != null )
				lister.onSolved();
	}
}
