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

import android.support.v4.view.ViewCompat;
import java.util.LinkedList;

/**
 *
 * @author vahagnk
 */
public class Animator implements Runnable
{
	protected PuzzleView view;
	protected LinkedList<Action> actions = new LinkedList<Action>();
	protected boolean stop;
	protected int step;
	protected Action currentAction;
	protected AnimationLister theLister;
	
	public interface AnimationLister
	{
		public void onAnimationEnd();
	}
	
	public Animator( PuzzleView v)
	{
		view = v;
	}
	
	public void setAnimationLister( AnimationLister lister )
	{
		theLister = lister;
	}
	
	public void queue( Action a )
	{
		actions.addLast(a);
	}
	
	public void play()
	{
		//
		//	If no actions exist then nothing to do.
		//
		if ( actions.size() == 0 )
			return;
		//
		//	Get the first action an play it.
		//
		stop = false;
		step = 0;
		currentAction = actions.removeFirst();
		ViewCompat.postOnAnimation(view, this);
	}
	
	public void stop()
	{
		stop = true;
		view.removeCallbacks(this);
		if ( theLister != null )
			theLister.onAnimationEnd();
	}
	
	public void clear()
	{
		actions.clear();
		currentAction = null;
	}
	
	public void run()
	{
		if ( currentAction == null )
			return;
		else if ( currentAction.steps > step )
		{
			currentAction.intermediate(this,step);
			step++;
			ViewCompat.postOnAnimation(view, this);
		}
		else
		{
			currentAction.last(this);
			step = 0;
			currentAction = null;
			if ( !stop && actions.size() > 0 )
			{
				currentAction = actions.removeFirst();
				step = 0;
				ViewCompat.postOnAnimation(view, this);
			}
			else
			{
				if ( theLister != null )
					theLister.onAnimationEnd();
			}
		}	
	}
	
	public static abstract class Action
	{
		public int steps;
		
		public Action()
		{
			steps = 0;
		}
		
		public abstract void intermediate( Animator ap, int step );
		public abstract void last( Animator ap );
	}
			
	protected static abstract class XYAction extends Action
	{
		int x;
		int y;
		
		public XYAction( int _x, int _y )
		{
			x = _x;
			y = _y;
		}
	}

	public static class Move extends XYAction
	{
		public Move( int x, int y )
		{
			super(x,y);
		}
		
		public void intermediate( Animator ap, int step )
		{}
		
		public void last( Animator ap )
		{
			ap.view.getPuzzle().walk(x,y);
			ap.view.invalidate();
		}
	}

	public static class Push extends XYAction
	{
		public Push( int x, int y )
		{
			super(x,y);
		}
		
		public void intermediate( Animator ap, int step )
		{
		}
		
		public void last( Animator ap )
		{
			ap.view.getPuzzle().push(x,y);
			ap.view.invalidate();
		}
	}

	public static class Select extends XYAction
	{
		public Select(int x, int y )
		{
			super(x,y);
		}
		
		public void intermediate( Animator ap, int step )
		{
		}
		
		public void last( Animator ap )
		{
			ap.view.getPuzzle().select(x,y);
			ap.view.invalidate();
		}
	}

	public static class Unselect extends Action
	{	
		public Unselect()
		{}
		
		public void intermediate( Animator ap, int step )
		{}
		
		public void last( Animator ap )
		{
			ap.view.getPuzzle().unselect();
			ap.view.invalidate();
		}
	}

	public static class NoMove extends XYAction
	{
		public NoMove( int x, int y )
		{
			super(x,y);
		}
		
		public void intermediate( Animator ap, int step )
		{}
		
		public void last( Animator ap )
		{}
	}
}
