/*
* levels.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 __levels__
#define __levels__

#include "widget.h"
#include "box.h"
#include "button.h"
#include "checkbutton.h"
#include "plus_button.h"
#include "minus_button.h"
#include "cross_button.h"
#include "filled_button.h"
#include "mouse_slider.h"
#include "state_button.h"

#include <string>
#include <vector>

struct levels;

struct paint_listener {
  virtual void paint (levels&) = 0;
};

struct shift_listener {
  virtual void shifted (levels&) = 0;
};

struct bookmark : state_button {
  std::vector<int> ids;
};

struct levels : widget, move_listener {

  int n; 
  int last;

  int elem; // element width
  int height;

  int lev; // edited level
  float val; // edited val
  int hgt; // edited height

  int saveable;
	int editable;

	enum {STARTED=1, FINISH};
  int editing; // editing element?
	int stop_editing ();

	int paint; // paint levels with mouse?
  paint_listener* paintl;

  std::vector<float> values; // 0 to 1 for each level
  std::vector<int> heights; // 0 to height

	bool* selection;
	int nsel;
	int sel_sz;

  std::vector<bookmark*> bmk; // bookmarks of selections
  void addbookmark ();
  void removebookmark ();
  void removeallbookmarks ();
  void clearbookmarks ();

  MAKE_STATE_LISTENER (bmlis, bml)

  levels (const std::string& s);
  void load (); 

  void save ();
  ~levels ();

  int handle_input ();

  float a, a0;
  void draw ();

  void clear_hgt_val ();
  void calc_lev ();
	void calc_hgt_val ();
  int set (int i, float v, int h = -1);
	void set_only (int i, float v);
	int change (int i, float d);
	int update_mul_lev (int dy);

	void update ();

  change_listener<levels>* chgl;

	int rshift ();
	int lshift ();
  shift_listener* shftl;

  void chkpos ();
	void reheight ();

  // manipulation
  button ball, binvert, bnone;
  button bslide, blshift, brshift;
  checkbutton cbwrap;
  MAKE_CLICK_LISTENER(alllis, alll)
  MAKE_CLICK_LISTENER(invlis, invl)
  MAKE_CLICK_LISTENER(nonlis, nonl)
  MAKE_CLICK_LISTENER(lshiftlis, lsl)
  MAKE_CLICK_LISTENER(rshiftlis, rsl)

  struct slide : click_listener, mouse_slider_listener {
    void clicked (button& b);
    void moused (int dir, double scl); 
  } sll;

  void selall ();
  void selnon ();
  void invsel ();

  plus_button plus;
  MAKE_CLICK_LISTENER(pluslis, pll)
  minus_button minus;
  MAKE_CLICK_LISTENER(minuslis, mil)
  cross_button cross;
  MAKE_CLICK_LISTENER (crosslis, crol)

  filled_button szr;
  //MAKE_MOVE_LISTENER (szrlis, szl)
  void moved ();

  void moused (int dir, double scl);

  void set_pos (int x, int y);

  int lmb_clicked;
  int prev_mousey;


};

#endif
