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


#include "lissajous.h"
#include "vector2d.h"
#include "ui_list.h"
#include "mouse_slider.h"
#include <vector>
using namespace std;

extern ui_list uis;

extern const float PI_BY_180;

lissajous::lissajous () : center (0.5f, 0.0f) {
  name = "Lissajous";
  load_params ();
}

lissajous::~lissajous () {
  widget_save ("d_lissajous", ctrls);
  save_params ();
}

void lissajous::load_params () {
  ifstream f (make_fname().c_str(), ios::in);
  string ignore;
  f >> ignore >> speed.x >> ignore >> speed.y >> ignore >> angle.start >> ignore >> angle.end >> ignore >> num_points;
}

void lissajous::save_params () {
  ofstream f (make_fname().c_str(), ios::out);
  string ignore;
  f << "speed.x " << speed.x << endl << "speed.y " << speed.y << endl << "angle.start " << angle.start << endl << "angle.end " << angle.end << endl << "num_points " << num_points << endl;
}


void lissajous::setup () {

  plugin::setup ();

  widget* _ctrls [] = {&sp.speed.x, &sp.speed.y, &sp.angle.start, &sp.angle.end, &sp.num_points};
  for (int i = 0; i < 5; ++i) {
    ctrls.push_back (_ctrls[i]); 
  }
  num_ctrls = ctrls.size ();
  /*for (int i = 0; i < num_ctrls; ++i) {
    ctrls[i]->set_moveable(1);
  }*/


	spinner<float>* spn [] = {&sp.speed.x, &sp.speed.y, &sp.angle.start, &sp.angle.end};
  const char* lbl [] = {"X Speed", "Y Speed", "Start angle", "End angle"};
	int ori [] = {mouse_slider_listener::X, mouse_slider_listener::Y, mouse_slider_listener::Y, mouse_slider_listener::Y};
	float val [] = {speed.x, speed.y, angle.start, angle.end};
  float dta [] = {0.01f, 0.01f, 1.0f, 1.0f};
  for (int i = 0; i < 4; ++i) {
    spinner<float>* spi = spn[i];
		spi->set (lbl[i], dta[i], -MILLION, MILLION, this, 0);
		spi->set_value (val[i]);
		spi->orient = ori[i];
  }

	sp.num_points.set ("Points", 1, 0, MILLION, this, 0);
	sp.num_points.set_value (num_points);

  widget_load ("d_lissajous", ctrls);

  render ();

}

void lissajous::render () {

  num_points = sp.num_points.f_value;
  if (num_points == 0) return;

  speed.x = sp.speed.x.f_value;
  speed.y = sp.speed.y.f_value;
  angle.start = sp.angle.start.f_value;
  angle.end = sp.angle.end.f_value;

  theta = angle.start * PI_BY_180;
  dtheta = (angle.end - angle.start) / num_points * PI_BY_180;

	int j = num_points + 1;
	points.resize (j);
  for (int i = 0; i < j; ++i) {
		float rtheta = theta;
    float rtheta1 = speed.x * rtheta;
		float rtheta2 = speed.y * rtheta;
		point<float>& pi = points[i];
    pi.x = center.x + sin (rtheta1);
    pi.y = center.y + sin (rtheta2);
    theta += dtheta;
  }

  ss.str("");
  ss << "lissajous_" << speed.x << '_' << speed.y;
	gen_pts ();

}
