// <pre>

package actor;

import java.io.*;
import java.util.Properties;

/**
  $Id: AnimationFactory.java,v 1.5 2004/03/08 06:09:06 dhowe Exp $  
  make singleton?
 */
public abstract class AnimationFactory
{   
  public static final KeyFrameAnimation IDLE;
  public static final KeyFrameAnimation SCAMPER;
  public static final KeyFrameAnimation SWAGGER;
  public static final KeyFrameAnimation BROADJUMP;
  public static final KeyFrameAnimation PROWL;
  public static final KeyFrameAnimation LUMBER;
  public static final KeyFrameAnimation DEJECTED;
  public static final KeyFrameAnimation NO;
  public static final KeyFrameAnimation YES;
  public static final KeyFrameAnimation HOTFEET;
  public static final KeyFrameAnimation SPRINT;
  public static final KeyFrameAnimation HOP;
  public static final KeyFrameAnimation SCAMPER_BACKWARDS;

  // Tests loading/storing properties from files
  public static void main(String[] args)
  {
    //KeyFrameAnimation kf = getAnimationByName("SCAMPER");
    //System.out.println(kf.getProperties());    
    //AnimationFactory.storeProperties(kf);
    System.out.println(getAnimationByFile("scamper.properties"));
  }
  
  public static KeyFrameAnimation getAnimationByName(String a)
  {
    for(int i = 0; i < name.length; i++)
      if(a.equalsIgnoreCase(name[i]+""))
        return getAnimationByIndex(i);
    throw new RuntimeException("Unable to match animation name: "+a);
  }
  
  public static KeyFrameAnimation getAnimationByFile(String fileName)  
  {
    return new KeyFrameAnimation(loadProperties(fileName));
  }

  private static KeyFrame[] getFramesByIdx(int idx)
  {
    KeyFrame[] frames = new KeyFrame[4];
    for (int i = 0; i < 4; i++)
    {
      Point3D[] pts = new Point3D[6];
      for (int j = 0; j < 6; j++)
        pts[j] =
          new Point3D(
            actions[idx][(18 * i) + (3 * j)],
            actions[idx][(18 * i) + (3 * j) + 1],
            actions[idx][(18 * i) + (3 * j) + 2]);
      frames[i] = new KeyFrame((i * .25), pts);
    }
    return frames;
  } 
  
  public static KeyFrameAnimation getAnimationByIndex(int idx)
  {
    KeyFrame[] frames = new KeyFrame[4];
    for (int i = 0; i < 4; i++)
    {
      Point3D[] pts = new Point3D[6];
      for (int j = 0; j < 6; j++)
        pts[j] =
          new Point3D(
            actions[idx][(18 * i) + (3 * j)],
            actions[idx][(18 * i) + (3 * j) + 1],
            actions[idx][(18 * i) + (3 * j) + 2]);
      frames[i] = new KeyFrame((i*.25), pts);      
    }    
    return new KeyFrameAnimation(name[idx], frames, rate[idx], travel[idx]);
  }
  
  public static int getStockAnimationCount() 
  {
    return name.length;
  }

  public static void storeProperties(KeyFrameAnimation kf)
  {
    storeProperties(kf, kf.getName()+".properties");
  }

  public static void storeProperties(KeyFrameAnimation kf, String fName)
  {
    try
    {
      BufferedOutputStream bos = new BufferedOutputStream
        (new FileOutputStream(fName));
      kf.getProperties().store(bos, null);
      bos.flush();
      bos.close();
    }
    catch (IOException e) 
    {
      e.printStackTrace();
    }
  }
  
  /**
   * Creates a File by name and writes the String contents to it
   * @param FileName by which to create the File
   * @param Contents of the file as String
   */
//  static void writeProperties(String fileName, String contents)
//  {
//    File file = new File(fileName);
//    BufferedWriter writer;
//    try
//    {
//      writer = new BufferedWriter
//        (new FileWriter(file));
//      writer.write(contents);
//      writer.flush();
//      writer.close();
//    }
//    catch (IOException e) 
//    {
//      e.printStackTrace();
//    }
//  }
  
  /**
   * Utility method to load properties from property file. 
   * @param filename from which to load Properties
   * @return Properties Object loaded from file
   */
  static Properties loadProperties(String fileName)
  {
    Properties props = null;
    try
    {
      props = new Properties();
      props.load(new BufferedInputStream
        (new FileInputStream(new File(fileName))));
      return props;
    }
    catch(FileNotFoundException e)
    {
      if (props == null)
        System.err.println("Unable to load '"+ fileName+"'");
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }
  
  // ADD static String array of names for each one ***************************
  static String name[] =
  {
      "idle",
      "scamper",
      "swagger",
      "broadjump",
      "prowl",
      "lumber",
      "dejected",
      "no",
      "yes",
      "hotfeet",
      "sprint",
      "hop",
      "scamper_backwards" 
  };
  
  // BEATS PER SECOND FOR EACH ACTION
  static double rate[] = {4, 8, 6, 7, 2, 2, 2, 10, 12, 10, 9, 10, 4};

  // HOW MUCH DISTANCE EACH ACTION TRAVELS PER BEAT
  static double travel[] = {0, .5, .5, .45, .45, .5, .3, 0, 0, 0, .7, 0, -.5};

  // AN ACTION HAS FOUR KEY POSES.  EACH POSE HAS SIX (X,Y,Z) VERTICES.
  static double actions[][] = {
    { //idle
       0.01, 0.00, 0.00,  0.00, 0.00, 0.00,  0.02, 0.00, 0.01,  0.02, 0.00, 0.03,  0.00, 0.00, 0.00,  0.01, 0.00, 0.03, 
       0.03, 0.00, 0.02,  0.00, 0.00, 0.00,  0.00, 0.03, 0.03,  0.01, 0.00, 0.02,  0.00, 0.00, 0.00,  0.00, 0.03, 0.00, 
       0.01, 0.00, 0.01,  0.00, 0.00, 0.00,  0.01, 0.00, 0.00,  0.03, 0.00, 0.00,  0.00, 0.00, 0.00,  0.03, 0.00, 0.01, 
       0.02, 0.00, 0.01,  0.00, 0.00, 0.00,  0.00,-0.03, 0.02,  0.00, 0.00, 0.01,  0.00, 0.00, 0.00,  0.02,-0.03, 0.02, 
    },
    { //scamper
       0.00, 0.03, 0.00,  0.10, 0.00, 0.50,  0.00, 0.03, 0.00,  0.00, 0.17, 0.00, -0.10, 0.00,-0.50,  0.00, 0.17, 0.00, 
       0.00, 0.17, 0.00,  0.00, 0.20, 0.00,  0.00, 0.17, 0.00,  0.00, 0.03, 0.00, -0.10, 0.00, 0.00,  0.00, 0.03, 0.00, 
       0.00, 0.17, 0.00,  0.10, 0.00,-0.50,  0.00, 0.17, 0.00,  0.00, 0.03, 0.00, -0.10, 0.00, 0.50,  0.00, 0.03, 0.00, 
       0.00, 0.03, 0.00,  0.10, 0.00, 0.00,  0.00, 0.03, 0.00,  0.00, 0.17, 0.00,  0.00, 0.20, 0.00,  0.00, 0.17, 0.00, 
    },
    { //swagger
       0.00, 0.00, 0.00,  0.10, 0.00, 0.50,  0.00, 0.00, 0.00,  0.00, 0.00,-0.10, -0.10, 0.00,-0.50,  0.00,-0.10, 0.00, 
       0.20, 0.50, 0.00,  0.00, 0.50,-0.20,  0.20, 0.50, 0.00,  0.20, 0.00, 0.00, -0.10, 0.00,-0.20,  0.20, 0.00, 0.00, 
       0.00, 0.00,-0.10,  0.10, 0.00,-0.50,  0.00, 0.00,-0.10,  0.00, 0.00, 0.00, -0.10, 0.00, 0.50,  0.00, 0.00, 0.00, 
      -0.20, 0.00, 0.00,  0.10, 0.00,-0.20, -0.20, 0.00, 0.00, -0.20, 0.50, 0.00,  0.00, 0.50,-0.20, -0.20, 0.50, 0.00, 
    },
    { //broadjump
       0.00,-0.60, 0.10,  0.00, 0.00, 0.40,  0.00,-0.30, 0.00,  0.00,-0.60, 0.10,  0.00, 0.00, 0.40,  0.00,-0.30, 0.00, 
       0.00, 0.90, 0.00,  0.10, 0.70, 0.00,  0.00, 0.80, 0.00,  0.00, 0.90, 0.00, -0.10, 0.70, 0.00,  0.00, 0.80, 0.00, 
       0.00, 0.90, 0.00,  0.10, 0.50,-0.50,  0.00, 0.60, 0.00,  0.00, 0.90, 0.00, -0.10, 0.50,-0.50,  0.00, 0.60, 0.00, 
       0.00, 0.00, 0.00,  0.00, 0.00,-0.20,  0.00, 0.00, 0.00,  0.00, 0.00, 0.00,  0.00, 0.00,-0.20,  0.00, 0.00, 0.00, 
    },
    { //prowl
       0.00,-0.40,-0.10,  0.20, 0.00, 0.40,  0.00, 0.00, 0.00,  0.00,-0.20,-0.10, -0.20, 0.00,-0.50,  0.00, 0.00,-0.20, 
       0.10, 0.00, 0.00,  0.00, 0.30,-0.40,  0.10,-0.20, 0.00,  0.10, 0.00, 0.00, -0.20, 0.00,-0.05,  0.10,-0.20, 0.00, 
       0.00,-0.20,-0.10,  0.20, 0.00,-0.50,  0.00, 0.00,-0.20,  0.00,-0.40,-0.10, -0.20, 0.00, 0.40,  0.00, 0.00, 0.00, 
      -0.10, 0.00, 0.00,  0.20, 0.00,-0.05, -0.10,-0.20, 0.00, -0.10, 0.00, 0.00,  0.00, 0.30,-0.40, -0.10,-0.20, 0.00, 
    },
    { //lumber
       0.00, 0.00, 0.00,  0.10, 0.00, 0.50,  0.00, 0.00, 0.00,  0.00, 0.00,-0.10, -0.10, 0.00,-0.50,  0.00,-0.10, 0.00, 
       0.00, 0.20, 0.00,  0.00, 0.10, 0.00,  0.00, 0.20, 0.00,  0.00, 0.00, 0.00, -0.10, 0.00, 0.00,  0.00, 0.00, 0.00, 
       0.00, 0.00,-0.10,  0.10, 0.00,-0.50,  0.00, 0.00,-0.10,  0.00, 0.00, 0.00, -0.10, 0.00, 0.50,  0.00, 0.00, 0.00, 
       0.00, 0.00, 0.00,  0.10, 0.00, 0.00,  0.00, 0.00, 0.00,  0.00, 0.20, 0.00,  0.00, 0.10, 0.00,  0.00, 0.20, 0.00, 
    },
    { //dejected
       0.00,-0.50, 0.00,  0.10, 0.00, 0.30,  0.00, 0.00, 0.00,  0.00,-0.30,-0.10, -0.10, 0.00,-0.30,  0.00,-0.05, 0.00, 
       0.00,-0.20, 0.00,  0.00, 0.10, 0.00,  0.00, 0.05, 0.00,  0.00,-0.30, 0.00, -0.10, 0.00, 0.00,  0.00, 0.00, 0.00, 
       0.00,-0.30,-0.10,  0.10, 0.00,-0.30,  0.00, 0.00,-0.10,  0.00,-0.50, 0.00, -0.10, 0.00, 0.30,  0.00, 0.00, 0.00, 
       0.00,-0.30, 0.00,  0.10, 0.00, 0.00,  0.00,-0.05, 0.00,  0.00,-0.20, 0.00,  0.00, 0.10, 0.00,  0.00, 0.05, 0.00, 
    },
    { //no
       0.10,-0.10,-0.10,  0.00, 0.00, 0.00, -0.10, 0.10,-0.10,  0.10,-0.10, 0.10,  0.00, 0.00, 0.00, -0.10, 0.10, 0.10, 
       0.10,-0.10,-0.10,  0.00, 0.00, 0.00, -0.10, 0.10,-0.10,  0.10,-0.10, 0.10,  0.00, 0.00, 0.00, -0.10, 0.10, 0.10, 
      -0.10,-0.10, 0.10,  0.00, 0.00, 0.00,  0.10, 0.10, 0.10, -0.10,-0.10,-0.10,  0.00, 0.00, 0.00,  0.10, 0.10,-0.10, 
      -0.10,-0.10, 0.10,  0.00, 0.00, 0.00,  0.10, 0.10, 0.10, -0.10,-0.10,-0.10,  0.00, 0.00, 0.00,  0.10, 0.10,-0.10, 
    },
    { //yes
       0.00,-0.10,-0.10,  0.00, 0.00, 0.00,  0.00, 0.05, 0.00,  0.00,-0.10,-0.10,  0.00, 0.00, 0.00,  0.00, 0.05, 0.00, 
       0.00, 0.15,-0.10,  0.00, 0.00, 0.00,  0.00,-0.07, 0.00,  0.00, 0.15,-0.10,  0.00, 0.00, 0.00,  0.00,-0.07, 0.00, 
       0.00, 0.15,-0.10,  0.00, 0.00, 0.00,  0.00,-0.07, 0.00,  0.00, 0.15,-0.10,  0.00, 0.00, 0.00,  0.00,-0.07, 0.00, 
       0.00,-0.10,-0.10,  0.00, 0.00, 0.00,  0.00, 0.05, 0.00,  0.00,-0.10,-0.10,  0.00, 0.00, 0.00,  0.00, 0.05, 0.00, 
    },
    { //hotfeet
       0.00, 0.20, 0.10,  0.00, 0.30, 0.00,  0.00, 0.20, 0.00,  0.00, 0.20, 0.00,  0.00, 0.30, 0.00,  0.00, 0.20, 0.00, 
       0.00, 0.30, 0.00,  0.20, 0.50, 0.00,  0.00, 0.30, 0.00,  0.00, 0.10, 0.00,  0.00,-0.10, 0.00,  0.00, 0.10, 0.00, 
       0.00, 0.20, 0.00,  0.00, 0.30, 0.00,  0.00, 0.20, 0.00,  0.00, 0.20, 0.10,  0.00, 0.30, 0.00,  0.00, 0.20, 0.00, 
       0.00, 0.10, 0.00,  0.00,-0.10, 0.00,  0.00, 0.10, 0.00,  0.00, 0.30, 0.00, -0.20, 0.50, 0.00,  0.00, 0.30, 0.00, 
    },
    { //sprint
       0.00, 0.10, 0.10,  0.20, 0.30, 0.50,  0.00, 0.20, 0.00,  0.00, 0.10, 0.00, -0.20, 0.30,-0.30,  0.00, 0.20, 0.00, 
       0.00, 0.00, 0.00, -0.10, 0.50, 0.10,  0.00, 0.10, 0.00,  0.00, 0.20, 0.00, -0.20,-0.10, 0.10,  0.00, 0.30, 0.00, 
       0.00, 0.10, 0.00,  0.20, 0.30,-0.30,  0.00, 0.20, 0.00,  0.00, 0.10, 0.10, -0.20, 0.30, 0.50,  0.00, 0.20, 0.00, 
       0.00, 0.20, 0.00,  0.20,-0.10, 0.10,  0.00, 0.30, 0.00,  0.00, 0.00, 0.00,  0.10, 0.50, 0.10,  0.00, 0.10, 0.00, 
    },
    { //hop
       0.70, 0.30, 0.00,  0.20, 0.40, 0.00,  0.70, 0.30, 0.00,  0.40, 0.00, 0.00,  0.00, 0.00, 0.00,  0.40, 0.00, 0.00, 
       0.70, 0.40, 0.00,  0.20, 0.50, 0.00,  0.70, 0.40, 0.00,  0.50,-0.10, 0.00,  0.00, 0.00, 0.00,  0.50, 0.00,-0.10, 
       0.70, 0.50, 0.00,  0.20, 0.60, 0.00,  0.70, 0.50, 0.00,  0.60,-0.20, 0.00,  0.00, 0.20, 0.00,  0.60, 0.00,-0.20, 
       0.70, 0.40, 0.00,  0.20, 0.50, 0.00,  0.70, 0.40, 0.00,  0.50,-0.10, 0.00,  0.00, 0.00, 0.00,  0.50, 0.00,-0.10, 
    },
    { //scamper backward
       0.00, 0.03, 0.00,  0.10, 0.00, 0.50,  0.00, 0.03, 0.00,  0.00, 0.17, 0.00, -0.10, 0.00,-0.50,  0.00, 0.17, 0.00, 
       0.00, 0.03, 0.00,  0.10, 0.00, 0.00,  0.00, 0.03, 0.00,  0.00, 0.17, 0.00,  0.00, 0.20, 0.00,  0.00, 0.17, 0.00, 
       0.00, 0.17, 0.00,  0.10, 0.00,-0.50,  0.00, 0.17, 0.00,  0.00, 0.03, 0.00, -0.10, 0.00, 0.50,  0.00, 0.03, 0.00, 
       0.00, 0.17, 0.00,  0.00, 0.20, 0.00,  0.00, 0.17, 0.00,  0.00, 0.03, 0.00, -0.10, 0.00, 0.00,  0.00, 0.03, 0.00, 
    },
  };
  
  static {
     IDLE = getAnimationByIndex(0);
     SCAMPER = getAnimationByIndex(1);
     SWAGGER = getAnimationByIndex(2);
     BROADJUMP = getAnimationByIndex(3);
     PROWL = getAnimationByIndex(4);
     LUMBER = getAnimationByIndex(5);
     DEJECTED = getAnimationByIndex(6);
     NO = getAnimationByIndex(7);
     YES = getAnimationByIndex(8);
     HOTFEET = getAnimationByIndex(9);
     SPRINT = getAnimationByIndex(10);
     HOP = getAnimationByIndex(11);
     SCAMPER_BACKWARDS = getAnimationByIndex(12);
  }
  
}// end