/*
* ui_list.h
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/


#ifndef __ui_list
#define __ui_list


#include "fader.h"
#include "filled_button.h"
#include "checkbutton.h"
#include "font_editor.h"
#include "field.h"
#include "label.h"
#include "settings.h"
#include "spinner.h"
#include "curve_display.h"
#include "plugin_browser.h"
#include "menu.h"

#include <SDL/SDL.h>
#include <map>

#define DEFINE_PARAMETERS \
static const int npars = 17;\
widget* pw [npars] = {\
	&d_parameters,\
	&ab_parameters,\
	&sp_voices,\
	&sp_attack_time, \
	&sp_decay_time,\
	&sp_pitch_bend,\
	&cb_show_nearby_notes,\
	&l_waveform_display,\
	&cd_waveform_display,\
	&ab_prev_wav,\
	&ab_next_wav,\
	&l_octave_shift,\
	&ab_octave_up,\
	&ab_octave_down,\
	&sp_octave_shift_bpm,\
	&b_abort_octave_shift,\
	&ol_trig_what,\
};

struct curve_editor;
struct din;
struct drone;

DECL_FIELD_LISTENER (attack_val)
DECL_FIELD_LISTENER (decay_val)
DECL_FIELD_LISTENER (voices_val)
DECL_STATE_LISTENER (compress__listener)
DECL_STATE_LISTENER (show_pitch_volume_listener)
DECL_CLICK_LISTENER (settings__listener)
DECL_CLICK_LISTENER (waveform_display_listener)
DECL_CLICK_LISTENER (parameters_listener)
DECL_CLICK_LISTENER (scroll_arrow_listener)

struct fade_button_listener : state_listener, fade_listener {
	checkbutton* cb;
	fader* f;
	int* target;
	state_listener* lsnr;
	fade_button_listener ();
	fade_button_listener (checkbutton* cb, fader* f, int* target);
  void changed (checkbutton& c);
	void after_fade (fader& f);
};

struct voice_listener : fade_button_listener {
	voice_listener (checkbutton* cb, fader* f, int* target) : fade_button_listener (cb, f, target) {}
	void changed (checkbutton& c);
};


struct pitch_bend_listener : state_listener, change_listener<field> {
  void changed (checkbutton& b);
  void changed (field& f);
};

struct ui_list : ui {

  std::vector<ui*> uis;
  ui *current, *prev;

  curve_editor* crved;


  static const int MAX_EDITORS = 7;
  static const Uint8 key [MAX_EDITORS]; // short cuts keys 2, 3, 4, 5, 6, 7 and 8 => MAX_EDITORS = 7
  static ui* ed [MAX_EDITORS];

  double esct;

  ui_list ();

	void set_current (ui* u);
  int set_editor (const std::string& name, int screen);
	void load_editor (ui* e);

	int rmb_clicked;
  int handle_input ();

  void bg ();
  void draw ();
  int escape_from_things ();

  menu main_menu;

  std::map<ui*, std::vector<widget*> > widgets_of; // every ui
	void show_hide_widgets (int sh);

  plugin_browser plugin__browser;

  // common bottom line
  checkbutton cb_delay;
  fader fdr_delay;

  checkbutton cb_compress;
  compress__listener clis;

	checkbutton cb_record;

	// on microtonal keyboard
	options_list ol_voice_is;
	MAKE_OPTION_LISTENER (ol_voice_is_lis, vivl)

  checkbutton cb_voice;
  fader fdr_voice;

	checkbutton cb_gater;
	fader fdr_gater;
	void flash_gater ();

	arrow_button ab_scroll_left, ab_scroll_right, ab_scroll_up, ab_scroll_down;
	scroll_arrow_listener sal;
	checkbutton cb_show_pitch_volume_board, cb_show_pitch_volume_drones;
	show_pitch_volume_listener spvl;

	voice_listener vlis;
	fade_button_listener glis, dlis;

	// on mondrian
	button l_mondrian_voices;

	// on settings
	button b_settings;
	settings__listener slis;
	settings settings_scr;

  // keyboard-keyboard ui 
	//
  label d_parameters;
  arrow_button ab_parameters;
  parameters_listener pal;

	// attack/decay times
	spinner<float> sp_attack_time, sp_decay_time;
	spinner<int> sp_voices;
	attack_val atv;
	decay_val dkv;
	voices_val vov;

	// pitch bend
  spinner<float> sp_pitch_bend;
  checkbutton cb_show_nearby_notes;
  pitch_bend_listener pbl;

	// preset waveforms 
  label l_waveform_display;
  curve_display cd_waveform_display;
  arrow_button ab_prev_wav, ab_next_wav;
  waveform_display_listener wdl;

	// octave shift over bpm
  label l_octave_shift;
  arrow_button ab_octave_down, ab_octave_up;
  spinner<float> sp_octave_shift_bpm;
	button b_abort_octave_shift;
	octave_shift_listener osl;

	// keys trigger what? notes or noise?
	options_list ol_trig_what;
	MAKE_OPTION_LISTENER (trig_what_lis, twl);

	void setup ();
	void add_widgets ();
	void update_widgets (int wnow = -1, int hnow = -1, int wprev = -1, int hprev = -1);
	int update_bottom_line ();

  float eval_fade (fader& fdr, checkbutton& cb);
  int is_widget_on_screen (widget* w, ui* scr);
  void dofft ();
  void handle_plugin (widget* which, int what);
	void set_edit_labels (); // see fractaliser, warper
	int remove (widget* w);
	void add (ui* u, widget* w);

	MAKE_FIELD_LISTENER (dpeu_lis, dpeul)
	struct drone_pend_ed_ui_t {
		spinner<float> depth;
		spinner<float> bpm;
	} dpeu;

  ~ui_list ();

};

extern ui_list uis;
extern string user_data_dir;

#define UISP &uis

#endif
