/*
* basic_editor.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 __basic_editor
#define __basic_editor

#include "viewwin.h"
#include "point.h"
#include "mocap.h"
#include "ui.h"
#include "textboard.h"

#include <map>

struct click_point_t {
	point<float> pt;
	int noted;
	click_point_t ();
	void note (float x, float y);
};

struct basic_editor : ui {
	
  window win; // edit window

  // object space <> window space mapping
  point<int> win_chunk;
  point<float> obj_chunk;
  point<float> win_per_obj;
  point<float> obj_per_win;
  int win_resolution;
  float obj_resolution;

	void obj2win (const point<float>& p, float& wx, float& wy);
	void obj2win (const float& ox, const float& oy, float& wx, float& wy);
  void obj2win (float* oxa, float* oya, float* wxa, float* wya, int n);
  void objx2winx (float& xo, float& xw);
	void obj2view (const float& ox, const float& oy, int& vx, int& vy);
	void obj2mouse (const float& ox, const float& oy);
	void view2obj (const int& vx, const int& vy, float& ox, float& oy);
	void win2obj (const float& dx, const float& dy, float& cx, float& cy);

  // snapping support
	click_point_t shft_clk, ctrl_clk;
	point<float> clk;
  struct snapaxist {
    int x, y;
    snapaxist ();
  } snapaxis;
  void snap (float& x, float& y);
	void do_snapx (float& x);
	void do_snapy (float& y);
  std::vector<int> xlines, ylines;
  int nx, ny, nx2, ny2;
  int startx, endx, starty, endy;
  void update_snaps ();
  void draw_snaps ();
  void set_snap (int x, int y);

  std::string cursor_mesg;
	float cursor_x, cursor_y;

  mocap mocap0;
  void toggle_mouse_capture ();
  void start_mouse_capture ();
  void stop_mouse_capture ();

  int pan, zoom; // pan & zoom deltas to control pan and zoom speed
  void do_panx (int dir);
  void do_pany (int dir);
  void do_zoom (int dir);

  basic_editor ();
  virtual ~basic_editor ();

  void calc_win_mouse ();

  inline const point<float>& get_obj_chunk () {
    return obj_chunk;
  }

  inline float get_obj_resolution () {
    return obj_resolution;
  }

  void load (const std::string& fname);
  void load (std::ifstream& file);
  void save (std::ofstream& file);

  void set_win_chunk (int x, int y);
  int handle_input ();
	int lmb_clicked;

  void project ();
  void unproject ();

  void draw ();

  static int hide_cursor;
	int draw_guide;
  void draw_cursor ();

  textboard tb;
  int ntexts;
  
	int kbkb_attack_editor;
	int edit_sustain;
  float susx, susy;
  box<float> susbox;
  void update_sustain (float s);
  void calc_visual_params ();

	static float* gl_pts;
	static int n_pts;
	static int ref;
	inline static void alloc_gl_pts (int n) {
		if (n > n_pts) {
			if (gl_pts) delete[] gl_pts;
			gl_pts = new float [2 * n];
			n_pts = n;
		}
	}

};


#endif
