/*
* command.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 __command
#define __command

#include "help.h"

struct tokenizer;

struct command {

  std::string longname;
  std::string shortname;

  command (const std::string& ln, const std::string& sn) : longname (ln), shortname (sn) {}
  virtual int operator() (tokenizer& tz) { return 1; }
  virtual ~command () {}

};

struct cmdlist {

  std::vector<command*> cmds;
  int ncmds;

  std::string result; // holds last run command output

  void add (command* cmd);
  ~cmdlist ();

};

extern cmdlist cmdlst;

struct din;
struct i_binaural_drones;

struct set_var : command { // set var
  din* d;
	set_var (din* dd, const std::string& ln, const std::string& sn) : command (ln, sn), d(dd) {}
	int operator() (tokenizer& tz);
	int set_scroll (std::string& varn, tokenizer& tz);
	int set_zoom_pan (int& rate, float& amount, std::string& varn, tokenizer& tz);
	~set_var () {}
};

struct get_var : command { // get var
  din* d;
	get_var (din* dd, const std::string& ln, const std::string& sn) : command (ln, sn), d(dd) {}
	int operator() (tokenizer& tz);
	~get_var () {}
};

struct delay;
struct set_delay: command { // set delay time
  delay* left;
  delay* right;
	set_delay (delay* l, delay* r, const std::string& ln, const std::string& sn) : command (ln, sn), left(l), right(r) {}
	int operator() (tokenizer& tz);
	~set_delay () {}
};

struct get_delay: command { // get delay time
  delay* left;
  delay* right;
	get_delay (delay* l, delay* r, const std::string& ln, const std::string& sn) : command (ln, sn), left(l), right(r) {}
	int operator() (tokenizer& tz);
	~get_delay () {}
};

struct beat2value;

// bpm
//
struct bpm_com {
  static const int NUM = 4;
  static const char* str [NUM];
  static beat2value* bv [NUM];
  int get_bpm_id_from_name (const std::string& name);
};

struct ls_bpm: command, bpm_com { // list bpmable components
  ls_bpm (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~ls_bpm () {}
};

struct set_bpm: command, bpm_com {
  set_bpm (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_bpm () {}
};

struct get_bpm: command, bpm_com {
  get_bpm (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~get_bpm () {}
};

struct set_style : command, bpm_com {
  set_style (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_style () {}
};

struct get_style : command, bpm_com {
  get_style (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~get_style () {}
};

struct set_beat : command, bpm_com {
  set_beat (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_beat () {}
};

struct get_beat : command, bpm_com {
  get_beat (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~get_beat () {}
};

struct add_scale: command {
	add_scale (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator () (tokenizer& tz);
	~add_scale () {}
};

struct remove_scale : command {
	remove_scale (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator () (tokenizer& tz);
	~remove_scale () {}
};

struct ls_scales: command {
	ls_scales (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator () (tokenizer& tz);
	~ls_scales () {}
};

struct ls_notes: command {
	ls_notes (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator () (tokenizer& tz);
	~ls_notes () {}
};

struct load_scale : command {
  din* d;
  int reentry;
	load_scale (din* dd, const std::string& ln, const std::string& sn) : command (ln, sn), d(dd) {}
	int operator () (tokenizer& tz);
	~load_scale () {}
};

struct key : command {
  din* d;
	key (din* dd, const std::string& ln, const std::string& sn) : command (ln, sn), d(dd) {}
	int operator() (tokenizer& tz);
	~key () {}
};

struct notation : command {
  din* d;
  notation (din* dd, const std::string& ln, const std::string& sn) : command (ln, sn), d(dd) {}
  int operator() (tokenizer& tz);
  ~notation () {}
};

struct note_distance: command {
	note_distance (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~note_distance () {}
};

struct chord: command {
	chord (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~chord () {}
};

struct set_font_size: command {
	set_font_size (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~set_font_size () {}
};

struct get_font_size: command {
	get_font_size (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~get_font_size () {}
};

struct set_kern: command {
	set_kern (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~set_kern () {}
};

struct get_kern: command {
	get_kern (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~get_kern () {}
};

struct curve_name : command { // change picked curve name
  curve_name (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~curve_name () {}
};

struct scale_curve : command { 
  scale_curve (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~scale_curve () {}
};


struct multi_curve;

struct paste_gater: command {
  paste_gater (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~paste_gater () {}
};

struct curve_value : command { // change curve value (vertex, tangent)
  curve_value (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  ~curve_value () {}
  int operator() (tokenizer& tz);
};

struct curve__library : command { // edit curve library attached to current curve editor
  curve__library (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~curve__library () {}
};

struct set_curve_editor : command {
  set_curve_editor (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_curve_editor () {}
};

struct set_scope : command {
  din* d;
	i_binaural_drones* sb;
  set_scope (const std::string& ln, const std::string& sn, din* _d, i_binaural_drones* _sb) : command (ln, sn), d(_d), sb(_sb) {}
  int operator() (tokenizer& tz);
  ~set_scope () {}
};

struct get_scope : command {
  din* d;
  get_scope (const std::string& ln, const std::string& sn, din* dd) : command (ln, sn), d(dd) {}
  int operator() (tokenizer& tz);
  ~get_scope () {}
};

struct echo : command {
  echo (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~echo () {}
};

struct set_text_color: command {
  set_text_color (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_text_color () {}
};

struct get_selection : command {
  get_selection (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~get_selection () {}
};

struct set_drone : command {
  din& d;
  set_drone (const std::string& ln, const std::string& sn, din& dd) : command (ln, sn), d(dd) {}
  int operator() (tokenizer& tz);
  ~set_drone () {}
};

struct get_drone : command {
  din& d;
  get_drone (const std::string& ln, const std::string& sn, din& dd) : command (ln, sn), d(dd) {}
  int operator() (tokenizer& tz);
  ~get_drone () {}
};

struct get_intervals : command {
  get_intervals (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~get_intervals () {}
};

struct num_octaves : command {
  din& d;
  num_octaves (const std::string& ln, const std::string& sn, din& dd) : command (ln, sn), d(dd) {}
  int operator() (tokenizer& tz);
  ~num_octaves () {}
};

struct set_kb_layout : command {
  std::string layout;
  set_kb_layout (const std::string& ln, const std::string& sn) : command (ln, sn), layout ("us") {}
  int operator() (tokenizer& tz);
  ~set_kb_layout () {}
};

struct list_midi : command {
  list_midi (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~list_midi () {}
};

struct set_midi : command {
  set_midi (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_midi () {}
};

struct set_audio : command {
  set_audio (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_audio () {}
};

struct gravity : command {
  gravity (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~gravity () {}
};

#ifdef __SVG__

struct write_svg : command {
  write_svg (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~write_svg () {}
};

struct write_trail : command {
  write_trail (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~write_trail () {}
};

#endif

#ifdef __HPGL__
struct write_hpgl : command {
	write_hpgl (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~write_hpgl () {}
};
#endif

struct cmd_binaural_drone : command {
  cmd_binaural_drone (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~cmd_binaural_drone () {}
};

struct set_sine_mixer : command {
  set_sine_mixer (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~set_sine_mixer () {}
};

struct change_sine_mixer : command {
  change_sine_mixer (const std::string& ln, const std::string& sn) : command (ln, sn) {}
  int operator() (tokenizer& tz);
  ~change_sine_mixer () {}
};

struct update_sine_mixer : command {
	update_sine_mixer (const std::string& ln, const std::string& sn) : command (ln, sn) {}
	int operator() (tokenizer& tz);
	~update_sine_mixer () {}
};


#endif
