/*
* field.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 __field
#define __field

#include "widget.h"

#include <string>
#include <list>

struct typing_listener;

struct field : widget { // a text field

	enum {dec3, dec4, dec6, inf};
	static const char* fmts [];
	int fmt;

  enum {pushback, insert, unknown};
  int mode;

  std::string text; // text of the field
  int len; // length of text
  int last; // last char
  
  int cursor; // cursor pos ie char position
  int offset; // offset from left

  // focus
  //
  int focus; // 1 - field has focus, 0 - lost focus
  int lmb_clicked;

  int edited; // edited?

  // listeners
  change_listener<field>* change_lsnr;
	typing_listener* typing_lsnr; 
	void call_listener ();
  
	int expr; // evaluate contents as TCL math expression?
	std::string type; // data type of expression

  field ();
  field (int x, int y, const std::string& str = "");
	void init ();

  void set_text (const std::string& txt, int _edited = 0);
  void set_text (int i, int _edited = 0);
  void set_text (float f, int _edited = 0);
  const std::string& get_text () {return text;}

  int handle_input ();
  int hittest (int x, int y);
  int has_focus () {return focus;}

  void calc_cursor ();
  void update ();
  void draw ();
  void draw_cursor (int x, int y);

  operator int() const;
  operator float() const;
	operator double() const;
	operator short() const;

  field& operator= (int i) {
    set_text (i);
    return *this;
  }

  field& operator= (float f) {
    set_text (f);
    return *this;
  };

};

struct typing_listener {
	virtual void typing (field& f) = 0;	
};


#define DECL_FIELD_LISTENER(name) struct name : change_listener<field> { void changed (field& f); };
#define MAKE_FIELD_LISTENER(name,var)\
	struct name : change_listener<field> { \
		void changed (field& f); \
	} var;
#define VALUE_CHANGED(scope,name) void scope::name::changed (field& f)

#endif
