/*
* autorotator.cc
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/

#include "defvelaccel.h"
#include "autorotator.h"
#include "chrono.h"
#include "console.h"

autorotator::autorotator (defvelaccel& d) : dva(d), autoflip(d), autopause(d) {

  flipdir = 0;

  setyes (d.autos.rot.yes);
  autopause.setyes (autopause.yes, *this);

  int i = 0;
  if (d.autos.rot.dir == RANDOM) i = get_rand_bit (); else i = d.autos.rot.dir;
  static const int dirs [] = {-1, 1};
  dir = dirs[i];

  if (d.autos.rot.mov == RANDOM) 
    mov = get_rand_bit ();
  else 
    mov = d.autos.rot.mov;

  if (mov == SMOOTH) {
    set_rpm (d.autos.rot.rpm());
    deg = 6.0f;
    tps = 1.0f;
  } else {
    setdeg (d.autos.rot.dps());
    settps (d.autos.rot.tps());
    tik.start ();
    rpm = 0.0f;
  }

}

int autorotator::yess () {
  if (autopause.yes) autopause (*this);
  return yes;
}

void autorotator::setyes (int y) {
  yes = y;
  if (yes && autopause.yes) autopause.go ();
}

void autorotator::set_rpm (float r) {
  if (r > 0) {
    rpm = r;
    extern const float TWO_PI;
    angle.per = TWO_PI * r / 60.0f;
  } else {
    rpm = 0;
    angle.per = 0.0f;
  }
}

void autorotator::chgdeg (float d) {
  setdeg (deg + d);
}

void autorotator::chgtps (float t) {
  settps (tps + t);
  setdeg (deg);
}

void autorotator::calc (double dt) {

  if (mov == SMOOTH) 
    angle.theta = dt * angle.per;
  else {
    extern ui_clock ui_clk;
    if (tik (ui_clk())) {
      if (dva.autos.rot.uet.deg) setdeg (dva.autos.rot.dps());
      if (dva.autos.rot.uet.tps) settps (dva.autos.rot.tps());
      angle.theta = angle.per; 
    } else angle.theta = 0.0f;
  }

  if (autoflip.yes) flipdir = autoflip.calc (angle.theta, dva);

  angle.theta *= dir;

  if (flipdir) {
    dir *= -1;
    flipdir = 0;
  }

}

std::istream& operator>> (std::istream& file, autorotator& ar) {
  file >> ar.yes >> ar.dir >> ar.rpm >> ar.mov >> ar.deg >> ar.tps >> ar.autoflip >> ar.autopause;
  if (ar.mov == autorotator::SMOOTH)
    ar.set_rpm (ar.rpm);
  else {
    ar.setdeg (ar.deg);
    ar.settps (ar.tps);
  }
  ar.setyes (ar.yes);
  return file;
}

std::ostream& operator<< (std::ostream& file, autorotator& ar) {
  extern const char spc;
  file << ar.yes << spc << ar.dir << spc << ar.rpm << spc << ar.mov << spc << ar.deg << spc << ar.tps << spc << ar.autoflip << spc << ar.autopause;
  return file;
}
