// <pre>

package actor;

import render.Geometry;
import render.Material;
import render.Matrix;

/**
 * @author Robbins
 */
public class ActorGeometry
{
  //Maps keyframe animation points to verticess
  private int[] animationVertexMap = null;
  
  // Point3D vertex locations for non-animated shape
  private Point3D[] baseShape = null;

  // The actual underlying Geometry
  protected Geometry geometry; 
  
  public ActorGeometry()
  {
    this.geometry = new Geometry();
  }

  public int mapAnimationVertex(int v)
  {
    int physicalVertexIndex;
    
    if(animationVertexMap == null)
      physicalVertexIndex = v;   
    else 
      physicalVertexIndex = animationVertexMap[v];
      
    return physicalVertexIndex;
  }
  
  public int getVertexCount() 
  {
    return geometry.vertices.length;
  }

  public int[] getAnimationVertexMap()
  {
    return animationVertexMap;
  }

  public void setAnimationVertexMap(int[] animationVertexMap)
  {
    this.animationVertexMap = animationVertexMap;
  }
  
  public void updateVertices(Point3D[] VertexList) 
  {
    throw new RuntimeException("IMPLEMENT ME!");
  }

  /**
   * @return Returns the shape.
   */
  public Point3D[] getBaseShape()
  {
    return baseShape;
  }

  /**
   * @param shape The shape to set.
   */
  public void setBaseShape(Point3D[] shape)
  {
    this.baseShape = shape;
  }

  /**
   * @param src
   * @param m
   * @param dst
   */
  public static void transform(double[] src, Matrix m, double[] dst)
  {
    Geometry.transform(src, m, dst);
  }

  /**
   * @return
   */
  public Geometry add()
  {
    return geometry.add();
  }

  /**
   * @param s
   * @return
   */
  public Geometry add(Geometry s)
  {
    return geometry.add(s);
  }

  /**
   * @param n
   * @return
   */
  public Geometry child(int n)
  {
    return geometry.child(n);
  }

  /**
   * @return
   */
  public boolean computedMeshNormals()
  {
    return geometry.computedMeshNormals();
  }

  /**
   * 
   */
  public void computeMeshNormals()
  {
    geometry.computeMeshNormals();
  }

  /**
   * 
   */
  public void computePolyhedronNormals()
  {
    geometry.computePolyhedronNormals();
  }

  /**
   * @param s
   * @return
   */
  public boolean contains(Geometry s)
  {
    return geometry.contains(s);
  }

  /**
   * @param src
   * @param dst
   */
  public void copyVertex(double[] src, double[] dst)
  {
    geometry.copyVertex(src, dst);
  }

  /**
   * @param src
   * @return
   */
  public double[][] copyVertices(double[][] src)
  {
    return geometry.copyVertices(src);
  }

  /**
   * @param src
   * @param dst
   * @return
   */
  public double[][] copyVertices(double[][] src, double[][] dst)
  {
    return geometry.copyVertices(src, dst);
  }

  /**
   * @param s
   * @return
   */
  public Geometry delete(Geometry s)
  {
    return geometry.delete(s);
  }

  /**
   * @param n
   * @return
   */
  public Geometry delete(int n)
  {
    return geometry.delete(n);
  }

  /* (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  public boolean equals(Object obj)
  {
    return geometry.equals(obj);
  }

  /**
   * @return
   */
  public Matrix getMatrix()
  {
    return geometry.getMatrix();
  }

  /**
   * @return
   */
  public double[] getOffset()
  {
    return geometry.getOffset();
  }

  /**
   * @return
   */
  public Geometry getParent()
  {
    return geometry.getParent();
  }

  /* (non-Javadoc)
   * @see java.lang.Object#hashCode()
   */
  public int hashCode()
  {
    return geometry.hashCode();
  }

  /**
   * @return
   */
  public boolean isDoubleSided()
  {
    return geometry.isDoubleSided();
  }

  /**
   * 
   */
  public void recomputeMeshNormals()
  {
    geometry.recomputeMeshNormals();
  }

  /**
   * @param tf
   * @return
   */
  public Geometry setDoubleSided(boolean tf)
  {
    return geometry.setDoubleSided(tf);
  }

  /**
   * @param m
   * @return
   */
  public Geometry setMaterial(Material m)
  {
    return geometry.setMaterial(m);
  }

  /**
   * @param m
   */
  public void setMatrix(Matrix m)
  {
    geometry.setMatrix(m);
  }

  /**
   * @param x
   * @param y
   * @param z
   */
  public void setOffset(double x, double y, double z)
  {
    geometry.setOffset(x, y, z);
  }

  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  public String toString()
  {
    return geometry.toString();
  }

  /**
   * @param src
   * @param m
   * @param dst
   */
  public void transformVertex(double[] src, Matrix m, double[] dst)
  {
    for (int i = 0; i < 3; i++)
      dst[i] = src[0] * m.get(i, 0) + src[1] * m.get(i, 1) + src[2] * m.get(i, 2) + m.get(i, 3);
    dst[3] = src[3];
    dst[4] = src[4];
    dst[5] = src[5];
  }

  public Geometry getGeometry()
  {
    return geometry;
  }

  public void setGeometry(Geometry geometry)
  {
    this.geometry = geometry;
  }

}