/*
* mouse_slider.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 __mouse_slider
#define __mouse_slider

#include "widget.h"
#include "arrow_button.h"
#include "checkbutton.h"

#include <list>

struct mouse_slider_listener {

	std::string name;
	enum {X, Y, NONE};
	int orient;
  double delta0, delta;
  checkbutton* vary;
  checkbutton* lim;
  void togger (checkbutton* cb, const char* str);
  void togvary ();
  void toglim ();
  mouse_slider_listener ();
	virtual void moused (int dir, double scl = 1.0) {}
	virtual void after_slide () {} 
};

struct mouse_slider : widget {

	int sz, sz_2, szn, szn_1;
	arrow_button axl, axr; 
	arrow_button ayb, ayt;
	void update_x_arrows ();
	void update_y_arrows ();

	static const int margin = 10;
	int lowx, highx, midx;
	int lowy, highy, midy;
	int prevx, prevy;
	int initx, inity, inityy;

	std::list<mouse_slider_listener*> mslx, msly;
	int nmslx, nmsly;
  void print (std::list<mouse_slider_listener*>&, std::list<mouse_slider_listener*>&);
  void print (std::list<mouse_slider_listener*>&);

	int dx, dy;

	int justx ();
	int justy ();

	int active;

  static int warp;

	int lmb_clicked;

	mouse_slider ();
	~mouse_slider ();
	int handle_input ();

	int pts [8];
	void draw ();

	void add (mouse_slider_listener* sl);
	void remove (mouse_slider_listener* sl);

  double base;
  int shift;
  struct scalet {
    enum {FIXED, CHANGING};
    int style;
    double value;
    void operator*= (const double& v) { value *= v; }
    void operator/= (const double& v) { value /= v; }
    void calcvalue (double& b, int s);
  } scale;

	int activate (int shft = 0, int scalestyle = scalet::CHANGING);
	int deactivate ();

};

void cant_mouse_slide ();
void activate_mouse_slider (int shift = 0, int scalestyle = mouse_slider::scalet::CHANGING);

extern mouse_slider mouse_slider0;

#define MAKE_MOUSE_SLIDER_LISTENER(name,var) struct name : mouse_slider_listener { void after_slide (); void moused (int dir, double scl); }; name var;
#define AFTER_SLIDE(scope,name) void scope::name::after_slide () 
#define MOUSED(scope,name) void scope::name::moused (int dir, double scl)

#endif
