public class WolfAttackMovie {
  /**
   * The root of the scene data structure
   **/
  Branch sceneRoot;
  
  /**
   * FrameSequence where the animation
   * is created
   **/
  FrameSequence frames;
  
  /** 
   * The nodes we need to track between methods
   **/
  MoveBranch wolfentry, wolfretreat, hero;
  
  /**
   * Return the sceneRoot
   * @return sceneRoot
   **/
  public Branch root(){ return sceneRoot;}
  
  /**
   * Set up all the pieces of the tree.
   **/
  public void setUp(){
    Picture wolf = new Picture(FileChooser.getMediaPath("dog-blue.jpg"));
    Picture house = new Picture(FileChooser.getMediaPath("house-blue.jpg"));
    Picture tree = new Picture(FileChooser.getMediaPath("tree-blue.jpg"));
    Picture monster = new Picture(FileChooser.getMediaPath("monster-face3.jpg"));

    //Make the forest
    MoveBranch forest = new MoveBranch(10,400); // forest on the bottom
    HBranch trees = new HBranch(50); // Spaced out 50 pixels between
    BlueScreenNode treenode;
    for (int i=0; i < 8; i++) // insert 8 trees
    {treenode = new BlueScreenNode(tree.scale(0.5));
      trees.addChild(treenode);}
    forest.addChild(trees);
    
    // Make the cluster of attacking "wolves"
    wolfentry = new MoveBranch(10,50); // starting position
    VBranch wolves = new VBranch(20); // space out by 20 pixels between
    BlueScreenNode wolf1 = new BlueScreenNode(wolf.scale(0.5));
    BlueScreenNode wolf2 = new BlueScreenNode(wolf.scale(0.5));
    BlueScreenNode wolf3 = new BlueScreenNode(wolf.scale(0.5));
    wolves.addChild(wolf1);wolves.addChild(wolf2);wolves.addChild(wolf3);
    wolfentry.addChild(wolves);
    
    // Make the cluster of retreating "wolves"
    wolfretreat = new MoveBranch(400,50); // starting position
    wolves = new VBranch(20); // space them out by 20 pixels between
    wolf1 = new BlueScreenNode(wolf.scale(0.5).flip());
    wolf2 = new BlueScreenNode(wolf.scale(0.5).flip());
    wolf3 = new BlueScreenNode(wolf.scale(0.5).flip());
    wolves.addChild(wolf1);wolves.addChild(wolf2);wolves.addChild(wolf3);
    wolfretreat.addChild(wolves);
    
    // Make the village
    MoveBranch village = new MoveBranch(300,450); // Village on bottom
    HBranch hhouses = new HBranch(40); // Houses are 40 pixels apart across
    BlueScreenNode house1 = new BlueScreenNode(house.scale(0.25));
    BlueScreenNode house2 = new BlueScreenNode(house.scale(0.25));
    BlueScreenNode house3 = new BlueScreenNode(house.scale(0.25));
    VBranch vhouses = new VBranch(-50); // Houses move UP, 50 pixels apart
    BlueScreenNode house4 = new BlueScreenNode(house.scale(0.25));
    BlueScreenNode house5 = new BlueScreenNode(house.scale(0.25));
    BlueScreenNode house6 = new BlueScreenNode(house.scale(0.25));
    vhouses.addChild(house4); vhouses.addChild(house5); vhouses.addChild(house6);
    hhouses.addChild(house1); hhouses.addChild(house2); hhouses.addChild(house3);
    hhouses.addChild(vhouses); // Yes, a VBranch can be a child of an HBranch!
    village.addChild(hhouses);
    
    // Make the monster
    hero = new MoveBranch(400,300);
    BlueScreenNode heronode = new BlueScreenNode(monster.scale(0.75).flip());
    hero.addChild(heronode);
    
    //Assemble the base scene
    sceneRoot = new Branch();
    sceneRoot.addChild(forest);
    sceneRoot.addChild(village);
    sceneRoot.addChild(wolfentry);
  }


  /**
   * Render just the first scene
   **/
  public void renderScene() {
    Picture bg = new Picture(500,500);
    sceneRoot.drawOn(bg);
    bg.show();
  }
  
  /**
   * Render the whole animation
   **/
  public void renderAnimation() {
    frames = new FrameSequence("C:/Temp/");
    frames.show();
    Picture bg;
    
    // First, the nasty wolvies come closer to the poor village
    // Cue the scary music
    for (int i=0; i<25; i++)
    {
      // Render the frame
      bg = new Picture(500,500);
      sceneRoot.drawOn(bg);
      frames.addFrame(bg);
      
      // Tweak the data structure
      wolfentry.moveTo(wolfentry.getXPos()+5,wolfentry.getYPos()+10);
    }
    
    // Now, our hero arrives!
    this.root().addChild(hero);
    // Render the frame
    bg = new Picture(500,500);
    sceneRoot.drawOn(bg);
    frames.addFrame(bg);
    
    // Remove the wolves entering, and insert the wolves retreating
    this.root().children.remove(wolfentry);
    this.root().addChild(wolfretreat);
    // Make sure that they retreat from the same place that they were at
    wolfretreat.moveTo(wolfentry.getXPos(),wolfentry.getYPos());
    // Render the frame
    bg = new Picture(500,500);
    sceneRoot.drawOn(bg);
    frames.addFrame(bg);
    
    // Now, the cowardly wolves hightail it out of there!
    // Cue the triumphant music
    for (int i=0; i<10; i++)
    {
      // Render the frame
      bg = new Picture(500,500);
      sceneRoot.drawOn(bg);
      frames.addFrame(bg);
      
      // Tweak the data structure
      wolfretreat.moveTo(wolfretreat.getXPos()-10,wolfretreat.getYPos()-20);
    }
  }
  
  /**
   * Replay the animation
   **/
  public void replay() {
    // Probably about 5 frames per second will work
    frames.replay(200);
  }
  
  public static void main(String[]args){
    WolfAttackMovie wam = new WolfAttackMovie();
    wam.setUp();
    wam.renderAnimation();
    wam.replay();
  }
}
