package curve;

import curve.*;
import java.awt.*;
import java.awt.event.*;

public class AnimatePanel extends Panel {
  private Button startButton,backPlayButton,pauseButton,playButton,endButton;
  private Scrollbar scrollbar;
  private int numPoints,sleepTime;
  private int playSpeed; //direction of current play
  private static final int BACKWARDS=-1,STOP=0,FORWARDS=1;
  private static final int startB=0,backPlayB=1,pauseB=2,playB=3,endB=4;
  private DrawCurve drawCurve;
  private AnimateDelayThread animateDelayThread1,animateDelayThread2;

  //Set up buttons and listeners
  public AnimatePanel(DrawCurve drawCurve,boolean twoLines) {
    FlowLayout flowLayout;

    this.drawCurve=drawCurve;
    if(drawCurve!=null) this.numPoints=drawCurve.setAnimatePanel(this);

    animateDelayThread1=animateDelayThread2=null;
    playSpeed=0;
    sleepTime=5000/numPoints; //5 seconds for animation
    if(twoLines)
    setLayout(new GridLayout(2,1)); //2 row animator
    else
    setLayout(new GridLayout(1,2)); //1 row animator
    Panel buttonPanel=new Panel(new GridLayout(1,5));
    Panel scrollbarPanel=new Panel(new BorderLayout());

    setBackground(Color.lightGray);
    startButton=new Button("|<<");
    startButton.addActionListener(new ButtonActionListener(startB));
    buttonPanel.add(startButton);
    backPlayButton=new Button("<");
    backPlayButton.addActionListener(new ButtonActionListener(backPlayB));
    buttonPanel.add(backPlayButton);
    pauseButton=new Button("||");
    pauseButton.addActionListener(new ButtonActionListener(pauseB));
    buttonPanel.add(pauseButton);
    playButton=new Button(">");
    playButton.addActionListener(new ButtonActionListener(playB));
    buttonPanel.add(playButton);
    endButton=new Button(">>|");
    endButton.addActionListener(new ButtonActionListener(endB));
    buttonPanel.add(endButton);
    scrollbar=new Scrollbar(Scrollbar.HORIZONTAL,0,
    10,0,numPoints+10);
    scrollbar.addAdjustmentListener(new MyAdjustmentListener());
    scrollbarPanel.add(scrollbar);

    add(buttonPanel);
    add(scrollbarPanel);
  };

  public void reset() {
    playSpeed=0;
    scrollbar.setValue(0);
  };

  protected void startButtonPressed() {
    scrollbar.setValue(0);
    scrollbar.dispatchEvent(new java.awt.event.AdjustmentEvent(
      scrollbar,AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
    AdjustmentEvent.TRACK,0));
  };

  protected void backPlayButtonPressed() {
    playSpeed=-1;
    if(scrollbar.getValue()==0) scrollbar.setValue(numPoints);
    scrollbar.setValue(scrollbar.getValue()-1);
    scrollbar.dispatchEvent(new java.awt.event.AdjustmentEvent(
      scrollbar,AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
    AdjustmentEvent.UNIT_DECREMENT,0));
  };

  protected void pauseButtonPressed() {
    playSpeed=0;
  };

  protected void playButtonPressed() {
    playSpeed=1;
    if(scrollbar.getValue()==numPoints) scrollbar.setValue(0);
    scrollbar.setValue(scrollbar.getValue()+1);
    scrollbar.dispatchEvent(new java.awt.event.AdjustmentEvent(
      scrollbar,AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
    AdjustmentEvent.UNIT_INCREMENT,0));
  };

  protected void endButtonPressed() {
    scrollbar.setValue(numPoints);
    scrollbar.dispatchEvent(new java.awt.event.AdjustmentEvent(
      scrollbar,AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
    AdjustmentEvent.TRACK,0));
  };

  protected synchronized void scrollbarAdjusted() {
    drawCurve.showAnimate(scrollbar.getValue());//Show curve
    if(playSpeed!=0) {
      if((playSpeed==-1 && scrollbar.getValue()==0) ||
      (playSpeed==1 && scrollbar.getValue()==numPoints)) {
        playSpeed=0; //stop animation
      } else {
        //This code ensures only 2 threads run; interface the calling one
        //and the newly created one
        if(animateDelayThread1==null)
          animateDelayThread1=new AnimateDelayThread
            (scrollbar,playSpeed,sleepTime);
        else if(animateDelayThread2==null)
          animateDelayThread2=new AnimateDelayThread
            (scrollbar,playSpeed,sleepTime);
        else if(animateDelayThread1.isFinished()==true)
          animateDelayThread1=new AnimateDelayThread
            (scrollbar,playSpeed,sleepTime);
        else if(animateDelayThread2.isFinished()==true)
          animateDelayThread2=new AnimateDelayThread
            (scrollbar,playSpeed,sleepTime);
      };
    };
  };

  protected class MyAdjustmentListener
  implements AdjustmentListener
  {
    public void adjustmentValueChanged(java.awt.event.AdjustmentEvent e) {
      scrollbarAdjusted();
    };
  };

  protected class ButtonActionListener implements java.awt.event.ActionListener
  {
    int buttonID; //Holds this listener's button ID
    public ButtonActionListener(int buttonID) {
      this.buttonID=buttonID;
    };

    public void actionPerformed(java.awt.event.ActionEvent event)
    {
      switch(buttonID) {
        case startB:startButtonPressed();break;
        case backPlayB:backPlayButtonPressed();break;
        case pauseB:pauseButtonPressed();break;
        case playB:playButtonPressed();break;
        case endB:endButtonPressed();break;
      };
    }; //Pass event to object
  }
};