package guistuff;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import breadboards.Breadboard;
import breadboards.GCompound;
import breadboards.GImage;
import spinning.SpinningBall;

public class Animation extends GCompound {

  public static final int LOOPS = 0;
  public static final int REMOVES_ITSELF_WHEN_COMPLETE = 1;

  // Note: frameDir is the package path to the .png images
  // of the various frames of the animation. They should be named
  // "frame_#_delay-#s.png" where digits appearing at the first "#" indicate
  // the frame number (starts at zero), and the digits appearing between the
  // "-" and "s" indicate how many seconds (possibly a decimal value) that
  // frame should last. 

  private String frameDir;
  private GImage frames[];
  private int frameDelays[];
  private boolean framesLoaded;

  private Timer timer;
  private int currentFrame;
  private int millisecondsToNextFrame;

  public void loadFrames() {
    ResourceReader rr = new ResourceReader(frameDir);
    String[] resourceList = rr.getResourceFileNames();
    frameDelays = new int[resourceList.length];
    frames = new GImage[resourceList.length];
    for (int i = 0; i < resourceList.length; i++) {
      int frameNum = Integer.parseInt(resourceList[i].split("_")[1]);
      frameDelays[frameNum] = (int) (1000.0 * Double.parseDouble(resourceList[i].split("-")[1].split("s")[0]));
      frames[frameNum] = GImage.getFromResource(frameDir + resourceList[i], SpinningBall.class);
    }
    framesLoaded = true;
  }

  public boolean framesLoaded() {
    return framesLoaded;
  }

  public Animation(String frameDir, int mode) {
    this.frameDir = frameDir;

    if (!framesLoaded) {
      loadFrames();
    }

    timer = new Timer(1, new ActionListener() {

      public void actionPerformed(ActionEvent arg0) {
        if ((millisecondsToNextFrame == 0) && (currentFrame < frames.length - 1)) {
          millisecondsToNextFrame = frameDelays[currentFrame];
          currentFrame++;
          Animation.this.removeAll();
          frames[currentFrame].setLocation(-frames[currentFrame].getWidth() / 2, -frames[currentFrame].getHeight() / 2);
          Animation.this.add(frames[currentFrame]);
        } else if (currentFrame < frames.length - 1) {
          millisecondsToNextFrame--;
        } else {
          switch (mode) {
          case LOOPS:
            currentFrame = 0;
            break;

          case REMOVES_ITSELF_WHEN_COMPLETE:
            Breadboard bb = Animation.this.getBreadboard();
            bb.remove(Animation.this);
            Animation.this.timer.stop();
            break;
          }
        }
      }
    });

    timer.start();
  }
}
