/*
* keyboard_keyboard.h
* 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/
*/


#ifndef __keyboard_keyboard
#define __keyboard_keyboard

#include "ui.h"
#include "instrument.h"
#include "note.h"
#include "solver.h"
#include "play.h"
#include "multi_curve.h"
#include "curve_editor.h"
#include "listeners.h"
#include "random.h"
#include "color.h"
#include "triggered_note.h"
#include "curve_library.h"
#include <SDL/SDL.h>

struct key_info {

  Uint8 id; // from SDL

  // visual
  char ch; // character
  int x, y; // position
  float r, g, b; // color

  int attacked; // attacked?

  key_info (int i = -1, char c = '.', int a = 0) : id (i), ch (c), attacked (a) {r = g = b = 1;}

};

struct keyboard_keyboard : instrument, scale_listener {

  multi_curve wave; // waveform
  curve_editor waved; // waveform shape editor
  wave_listener wavlis; // waveform edit listener
  void update_waveform (multi_curve& crv);

  std::vector<note> notes; // notes of the scale 
  void setup_notes (int overwrite = 1);

  int num_triggered_notes;
  std::list <triggered_note> triggered_notes; // currently active notes
	int trig_what;

  void remove_finished_notes ();
  void attack_note (int ky);
  void decay_note (int ky);
  int render_audio (float* L, float* R);

  std::map <int, std::vector<key_info> > scale2keybd;
  static const int MAX_KEYS = 256; // assume no keycode exceeds 255
  int keybd2notes [MAX_KEYS];
  std::vector<key_info> keys;

  // attack & decay curve
  multi_curve attackcrv, decaycrv;
  curve_editor attacked, decayed;
  attack_listener attacklis;
  decay_listener decaylis;
  void update_attack ();
  void update_decay ();

  int handle_input ();

  // visual
	
	int pts[8]; // for opengl

  float recent_note_hz;
  int show_nearby_notes;

	// mouse based pitch bend
	//
	int last_mousex, last_mousey;
	int marker_x;
	void mouse_bend ();
	void calc_mouse_bend (triggered_note& ti);
	int turn_off_bend (); 

	int pressx, hearx; // for the words Press and Hear (see draw ())
  int arm, ymarker, ychars, ynotes, spacing;
  void calc_visual_params ();

  void draw ();

	std::string fname;
  keyboard_keyboard ();
	~keyboard_keyboard ();

  void setup ();

  help helptext;

  // MIDI
  //
  static const int MIDI_MAX = 128;
  static const int color_index [];
  note midi_notes [MIDI_MAX];
  void setup_midi_notes ();
  void note_on (unsigned char id, unsigned char vel);
  void note_off (unsigned char id);
  void pitch_bend (float v);

  // MIDI velocity curve
  multi_curve velcrv;
  velocity_listener vellis;
  curve_editor veled;
  curve_library vellib;
  solver velsol;

  void enter ();
  void bg ();

	void load_scale (int dummy = 0);
	void scale_changed ();
	void scale_loaded ();
	void tonic_changed ();

};

extern keyboard_keyboard keybd2;
extern float ATTACK_TIME;
extern float DECAY_TIME;
extern int PITCH_BEND;
extern float PITCH_BEND_PER_PIXEL;
extern float NOTE_VOLUME;

#endif



