/*
 * Created on Mar 3, 2004
 *  
 */
package actor;

import render.Matrix;

/**
 * @author Robbins
 *  
 */

public class SpiralActorBehavior extends AbstractBehavior
{

  public final int SPIRAL_IN = 0, SPIRAL_OUT = 1;
  private double maxRadius, minRadius;
  private Matrix rotationMatrix = new Matrix();
  private MotionChange returnValue = new MotionChange();
  private int spiralType = SPIRAL_IN;
  private Actor target;

  // Constructors =====================================

  public SpiralActorBehavior(Actor target)
  {
    this(target, 2.5, 1.0);
  }

  public SpiralActorBehavior(Actor target, double maxRadius, double minRadius)
  {
    this.target = target;
    this.maxRadius = maxRadius;
    this.minRadius = minRadius;
  }

  // Public Methods =====================================

  public MotionChange doBehavior(WorldState world, InvariantActor actor)
  {

    double currentRadius =
      Point3D.subtract(actor.getPosition(), target.getPosition()).norm();

    double newActorYRotation =
      actor.getDirection().getYRotation()
        + actor.getSize().y * (actor.getAnimationTravel() / currentRadius);

    double newRadius = currentRadius;

    if (spiralType == SPIRAL_IN)
    {
      if (currentRadius > minRadius)
      {
        newRadius =
          currentRadius
            - (actor.getSize().y * 0.075 * actor.getAnimationTravel());
      }
      else
      {
        spiralType = SPIRAL_OUT;
      }
    }
    else if (spiralType == SPIRAL_OUT)
    {
      if (currentRadius < maxRadius)
      {
        newRadius =
          currentRadius
            + (actor.getSize().y * 0.075 * actor.getAnimationTravel());
      }
      else
      {
        spiralType = SPIRAL_IN;
      }
    }

    rotationMatrix.identity();
    rotationMatrix.rotateY(newActorYRotation);

    Point3D actorRotation = Point3D.createDirectionVector(rotationMatrix);
    Point3D actorPosition =
      Point3D.add(
        target.getPosition(),
        Point3D.matrixTransform(rotationMatrix, -newRadius, 0, 0));

    returnValue.setOldValues(actor);
    returnValue.setNewDirection(actorRotation);
    returnValue.setNewPosition(actorPosition);

    return returnValue;
  }

}