class Sequence {
  
  public static final int MODE_LINEAR = 0;
  public static final int MODE_SINUSOIDAL = 1;
  public static final int MODE_SINUSOIDAL_LONG = 2;
  private int MODE = MODE_LINEAR;
  
  public static final int OUTMODE_NORMAL = 0;
  public static final int OUTMODE_INVERT = 1;
  private int OUTMODE = OUTMODE_NORMAL;
  
  private boolean running = false;
  private boolean looping = false;
  private float time, length;
  
  Sequence() {
  }
  
  public void setLength(float l) {
    length = l;
  }
  
  public void setMode(int m) {
    MODE = m;
  }
  
  public void setOutMode(int om) {
    OUTMODE = om;
  }
  
  public void loop() {
    looping = true;
  }
  
  public void noLoop() {
    looping = false;
  }
  
  public void start() {
    time = 0;
    running = true;
  }
  
  public void stop() {
    time = 0;
    running = false;
  }
  
  public void toEnd() {
    time = length;
  }
  
  public void run() {
    running = true;
  }
  
  public void pause() {
    running = false;
  }
  
  public void reset() {
    time = 0;
  }
  
  public void step(float t) {
    if (running) {
      time += t;
      if (time>length) time = length;
      if (looping&&time==length) time=0;
    }
  }
  
  public float get() {
    float out = 0;
    if (MODE==MODE_LINEAR) {
      out = time/length;
    } else if (MODE==MODE_SINUSOIDAL) {
      out = 0.5+0.5*cos(PI + PI*time/length);
    } else if (MODE==MODE_SINUSOIDAL_LONG) {
      out = 1 + cos(PI + HALF_PI*time/length);
    }
    if (OUTMODE==OUTMODE_INVERT) {
      out = 1.0-out;
    }
    return out;
  }
  
}
