// <pre> 

package actor;

import java.util.Iterator;

import render.Geometry;

/**
 * $Id: AbstractActor.java,v 1.18 2004/03/03 23:12:47 robbins Exp $
 */
public abstract class AbstractActor implements Actor
{
  protected ActorArbitrator arbitrator;
  protected BehaviorList behaviors = new BehaviorList();  
  protected Point3D direction = new Point3D();
  protected Point3D position = new Point3D();
  protected Point3D size = new Point3D();
  protected ActorGeometry model;
  protected double travel = 0;
  
  // Just travel applied to direction?
  protected Point3D velocity = new Point3D(); 
  
  // Public Methods =====================================
  
  public abstract void update(WorldState ws);
    
  /** 
   * Traverses the tree of possible Arbitrators and returns
   * the non-null one at highest-level.
   */
  public BehaviorArbitrator getCurrentArbitrator()
  {
    if (this.arbitrator != null)  
    {  
      return arbitrator;
    }
    // else traverse the Arbitrator hierarchy 
    // starting with the Behavior with top priority 
    else 
    { 
      int highestPriority = 0;
      AbstractBehavior result = null;
      for (Iterator iter = behaviors.iterator(); iter.hasNext();)
      {
        AbstractBehavior aB = (AbstractBehavior)iter.next();        
        if (aB.isEnabled() && aB.getPriority() >= highestPriority) 
          result = aB;   
      }
      return result.getArbitrator();
    }    
  }

  public void addBehavior(Behavior behavior)
  {
    this.behaviors.add(behavior);
  }
  
  public void removeBehavior(Behavior behavior)
  {
    this.behaviors.remove(behavior);
  }
  
  public void removeAllBehaviors()
  {
    this.behaviors.clear();
  }
  
  // Getters and Setters =================================  
  
  public ActorArbitrator getArbitrator()
  {
    return arbitrator;      
  }

  public void setArbitrator(ActorArbitrator arbitrator)
  {
    this.arbitrator = arbitrator;
  }

  public BehaviorList getBehaviors()
  {
    return behaviors;
  }

  public void setBehaviors(BehaviorList behaviors)
  {
    this.behaviors = behaviors;
  }

  public Point3D getDirection()
  {
    return direction;
  }

  public void setDirection(Point3D direction)
  {
    this.direction = direction;
  }

  public ActorGeometry getModel()
  {
    return model;
  }
  
  public Geometry getGeometry()
  {
    return model.geometry;
  }

  public void setModel(ActorGeometry model)
  {
    this.model = model;
  }

  public Point3D getPosition()
  {
    return position;
  }

  public void setPosition(Point3D position)
  {
    this.position = position;
  }

  public Point3D getSize()
  {
    return size;
  }

  public void setSize(Point3D size)
  {
    this.size = size;
  }

  public Point3D getVelocity()
  {
    return velocity;
  }

  public void setVelocity(Point3D velocity)
  {
    this.velocity = velocity;
  }

  public double getAnimationTravel()
  {
    return travel;
  }

  public void setAnimationTravel(double animationTravel)
  {
    this.travel = animationTravel;
  }
  
  public double getX()
  {
    return position.getX();
  }

  public double getY()
  {
    return position.getY();
  }

  public double getZ()
  {
    return position.getZ();
  }
  
  public double getUniformSize()
  {
    return(Math.max(Math.max(size.x, size.y), Math.max(size.y, size.z)));
  }
  
  public void setUniformSize(double size)
  {
    this.size = new Point3D(size, size, size);
  }

}// end