/*
* number.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 __NUMBER
#define __NUMBER

#include "options_list.h"
#include "slider.h"
#include "label_field.h"
#include "plugin.h"
#include "spinner.h"
#include "bit_display.h"
#include "checkbutton.h"
#include <vector>
#include <string>

struct ucolor_t {
	unsigned char r, g, b;
};

struct number : plugin, change_listener< slider<int> >, change_listener <bit_display>, option_listener {
	//
	// convert any number into pattern
	//
	enum {CHAR, SHORT, INT, FLOAT, DOUBLE, COLOR}; // different types of number/data we can convert
	int type;
	std::vector<std::string> types;

	unsigned char uchar; // character
	short short_; // short integer
	int int_; // integer
	float float_; // single precision floating point number
	double double_; // double precision floating point number
	ucolor_t ucolor; // 24-bit color

	void reverse (unsigned char* reversed, unsigned char* original, int n); // to handle endianness

	int slw, slh; // slider width & height
	options_list ol_bitsof; // choose number type
	slider<int> sl_red, sl_green, sl_blue; // color sliders
	label_field lf_value; // editable value of number
	spinner<float> sp_scale; // beat/scale, relevant for non-shapeforms

	bit_display bd_bits; // the bit display
	spinner<float> sp_1equals; // 1 maps to ?
	spinner<float> sp_0equals; // 0 maps to ?
	float y[2]; // 0 and 1 mapping becomes y

	int make_shapeform;
	checkbutton cb_make_shapeform;

	// bit ops
	button b_flip;
	void flip ();

	button b_left_shift, b_right_shift;
	void shift (int i, int d);
	checkbutton cb_wrap;

  number ();
  ~number ();

  void load_params ();
  void save_params ();
  void setup ();
  void render ();

	void changed (slider<int>& s);
	void changed (field& f);
	void changed (bit_display& bd);
	void changed (checkbutton& cb);
	void clicked (button& b);
	

	void picked (label& l, int dir);
	void set_type (int t);

	template <class T> void set_bit_display (T* t) {
		T t_ = *t;
		int sz = sizeof (T); 
		reverse ((unsigned char*) t, (unsigned char*) &t_, sz);
		bd_bits.set (t, sz);
	}

	template <class T> void set_value (T t) {
		ss.clear(); ss.str(""); ss << t;
		lf_value.set_text (ss.str());
		set_bit_display (&t);
	}

	template <class T> void set_value_ (T t) {
		ss.clear(); ss.str(""); ss << t;
		lf_value.set_text (ss.str());
	}

	void make_value_from_color ();
	
};

#endif
