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

import androidx.core.view.ViewCompat;

import org.vostan.banvor.model.XYPair;

import java.util.LinkedList;

/**
 *
 * @author vahagnk
 */
public class Animator implements Runnable
{
	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
	{
		protected XYPair _xy = new XYPair();

		public XYAction( XYPair xy ){
			_xy.set(xy);
		}
	}

	public static class Move extends XYAction
	{
		public Move( XYPair xy ){
			super(xy);
		}

		public void intermediate( Animator ap, int step )
		{}

		public void last( Animator ap )
		{
			ap.view.getPuzzle().walk(_xy);
			ap.view.invalidate();
		}
	}

	public static class Push extends XYAction
	{
		public Push( XYPair xy ){
			super(xy);
		}

		public void intermediate( Animator ap, int step )
		{
		}

		public void last( Animator ap )
		{
			ap.view.getPuzzle().push(_xy);
			ap.view.invalidate();
		}
	}

	public static class Select extends XYAction
	{
		public Select( XYPair xy ){
			super(xy);
		}

		public void intermediate( Animator ap, int step )
		{
		}

		public void last( Animator ap )
		{
			ap.view.getPuzzle().select(_xy);
			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( XYPair xy ){
			super(xy);
		}

		public void intermediate( Animator ap, int step )
		{}

		public void last( Animator ap )
		{}
	}

	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();
			}
		}	
	}
}
