/*
* ui_sin_cos_radius.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 "ui_sin_cos_radius.h"
#include "plugin.h"
#include "console.h"
#include "ui_list.h"
#include "curve_library.h"
#include <fstream>
using namespace std;
extern string user_data_dir;
extern ofstream dlog;
extern curve_library sin_lib, cos_lib;
extern int line_height;

ui_sin_cos_radius::ui_sin_cos_radius (
    ui_sin_cos_radius_listener* _lis, 
    const std::string&  _scr_fname, 
    const std::string&  _cp_sin_fname, const std::string&  _cp_cos_fname, const std::string& _cp_rad_fname, 
    const std::string&  _sin_ed_fname, const std::string&  _cos_ed_fname, const std::string& _rad_ed_fname, 
    int inc
  ) : 
  cp_sin (_cp_sin_fname), cp_cos (_cp_cos_fname), cp_rad (_cp_rad_fname), 
  sin_ed (_sin_ed_fname), cos_ed (_cos_ed_fname), rad_ed (_rad_ed_fname) {

  lis = _lis;
  fname = _scr_fname;
  sin = cos = radius = 0;
  inc_radius = inc;
  sin_ed.add (&cp_sin.crv, this);
  cos_ed.add (&cp_cos.crv, this);
  sin_ed.attach_library (&sin_lib);
  cos_ed.attach_library (&cos_lib);
  if (inc_radius) {
    rad_ed.add (&cp_rad.crv, this);
  }
  load ();
}

ui_sin_cos_radius::~ui_sin_cos_radius () {
  save ();
}

void ui_sin_cos_radius::load () {
  ifstream fin ((user_data_dir + fname).c_str());
  if (fin) {
    fin >> sin >> cos >> radius; 
  } else {
    sin = cos = radius = 0;
  }
}

void ui_sin_cos_radius::save () {
  ofstream fout ((user_data_dir + fname).c_str());
  fout << sin << ' ' << cos << ' ' << radius;
}

void ui_sin_cos_radius::setup () {
  options_list* ol [] = {&ol_sin, &ol_cos, &ol_radius};
  int n = 2; if (inc_radius) n = 3;
  for (int i = 0; i < n; ++i) ol[i]->set_listener (this);
  button* b [] = {&b_sin, &b_cos, &b_radius};
  for (int i = 0; i < 3; ++i) {
    button* bi = b[i];
    bi->set_text ("Edit");
    bi->set_listener (this);
  }
  if (sin) set_option (ol_sin.option, " Custom sin", &pf_sin, &cp_sin, b_sin, 1); else set_option (ol_sin.option, " Standard sin", &pf_sin, &st_sin, b_sin, 0);
  if (cos) set_option (ol_cos.option, " Custom cos", &pf_cos, &cp_cos, b_cos, 1); else set_option (ol_cos.option, " Standard cos", &pf_cos, &st_cos, b_cos, 0);
  if (inc_radius) {
    if (radius) set_option (ol_radius.option, " Custom radius", &pf_radius, &cp_rad, b_radius, 1); else set_option (ol_radius.option, " Standard radius", &pf_radius, &st_radius, b_radius, 0);
  }
}

void ui_sin_cos_radius::set_pos (int x, int y) {
  int lh = line_height;
  posx = x;
  posy = y;
  int yw = posy - lh;
  widget* wo [] = {&ol_sin, &ol_cos, &ol_radius};
  int n; if (inc_radius) n = 3; else n = 2;
  for (int i = 0; i < n; ++i) {
    widget* woi = wo[i];
    woi->set_pos (x, yw);
    yw -= lh;
  }
}

int ui_sin_cos_radius::handle_input () {
  widget* wo [] = {&ol_sin, &ol_cos, &ol_radius}; int n; if (inc_radius) n = 3; else n = 2;
  button* wb [] = {&b_sin, &b_cos, &b_radius};
  int ret = 0; 
  for (int i = 0; i < n; ++i) ret |= wo[i]->handle_input ();
  for (int i = 0; i < n; ++i) {
    button* bi = wb[i];
    if (bi->visible) ret |= bi->handle_input ();
  }
  return ret;
}

void ui_sin_cos_radius::draw () {
  widget* wo [] = {&ol_sin, &ol_cos, &ol_radius}; int n; if (inc_radius) n = 3; else n = 2;
  button* wb [] = {&b_sin, &b_cos, &b_radius};
  for (int i = 0; i < n; ++i) wo[i]->draw ();
  for (int i = 0; i < n; ++i) {
    button* bi = wb[i];
    if (bi->visible) bi->draw ();
  }
}

void ui_sin_cos_radius::set_option (label& lbl, const string& text, funktion** pf, funktion* pfv, button& bt, int vis) {
  lbl.set_text (text);
  *pf = pfv;
  if (vis) {
    bt.show (); 
    int spacer = 10; bt.set_pos (lbl.extents.right + spacer, lbl.extents.bottom);
  } else bt.hide ();
}

void ui_sin_cos_radius::picked (label& l, int dir) {
  if (&l == &ol_sin.option) {
    sin = !sin;
    if (sin) set_option (l, " Custom sin", &pf_sin, &cp_sin, b_sin, 1); else set_option (l, " Standard sin", &pf_sin, &st_sin, b_sin, 0);
  } else if (&l == &ol_cos.option) {
    cos = !cos;
    if (cos) set_option (l, " Custom cos", &pf_cos, &cp_cos, b_cos, 1); else set_option (l, " Standard cos", &pf_cos, &st_cos, b_cos, 0);
  } else {
    radius = !radius;
    if (radius) set_option (l, " Custom radius", &pf_radius, &cp_rad, b_radius, 1); else set_option (l, " Standard radius", &pf_radius, &st_radius, b_radius, 0);
  }
  lis->sin_cos_radius_optioned ();
}

void ui_sin_cos_radius::clicked (button& b) {
  if (&b == &b_sin) edit_sin (); 
  else if (&b == &b_cos) edit_cos ();
  else edit_radius ();
}

void ui_sin_cos_radius::edit_sin () {
  uis.set_current (&sin_ed);
}

void ui_sin_cos_radius::edit_cos () {
  uis.set_current (&cos_ed);
}

void ui_sin_cos_radius::edit_radius () {
  uis.set_current (&rad_ed);
}

void ui_sin_cos_radius::edited (curve_editor* e, int i) {
  multi_curve* crv = e->curveinfo[i].curve;
  if (crv == &cp_sin.crv) cp_sin.sol.update ();
  else if (crv == &cp_cos.crv) cp_cos.sol.update ();
  else cp_rad.sol.update ();
  lis->sin_cos_radius_edited ();
}
