#include <controls.h>
#include <image.h>
#include <virtkeyb.h>
#include <utility.h>

#define DLG_BACKSPACE	400
#define DLG_CAPS	    401
#define DLG_LSHIFT	  402
#define DLG_RSHIFT	  403
#define DLG_LARR  	  404
#define DLG_RARR  	  405
#define DLG_F2				406
#define DLG_BASE  	  500

bool TVirtual_keyboard::handler(TMask_field& f, KEY key)
{
	if (key == K_SPACE)
	{
		const short id = f.dlg();
		TVirtual_keyboard & m = (TVirtual_keyboard &) f.mask();
		static  bool vk_shift = false;
		static  bool vk_caps = false;
		int & pos = m.pos();
		TMask_field & target = m.field(101);

		target.set_focus();

		switch (id)
		{
		case DLG_BACKSPACE :
			if (pos > 0)
			{
				TString val(m.get(101));

			  if (pos == val.len())
					val.rtrim(1);
				else
				{
					const TString v = val.mid(pos);

					val.cut(pos - 1);
					val << v;
				}
				pos--;
				target.set(val);
			}
			break;
		case DLG_F2 :
				pos = 0;
				target.reset();
			break;
		case DLG_CAPS :
				vk_caps = !vk_caps;
			break;
		case DLG_RSHIFT :
		case DLG_LSHIFT :
				vk_shift = true;
			break;
		case DLG_LARR :
			if (pos > 0)
				pos--;
			break;
		case DLG_RARR:
			if (pos < target.get().len())
				pos++;
			break;
		default :
			if (id >= DLG_BASE + ' ' && pos < target.size())
			{
				char k = id - DLG_BASE;

				if (vk_caps || vk_shift)
					  k = toupper(k);
				vk_shift = false;

				TString val(target.get());

				val.insert(format("%c", k), pos++);
				target.set(val);
			}
			break;
		}
		target.set_caret_pos(pos);
	}
	return true;
}

void TVirtual_keyboard::create_keyboard_row(int y, const char * keyboard_row)
{
	const TString80 row(keyboard_row);
	const int len = row.len();
	RCT rw;
	short id;
	int x;
	TString16 prompt;

	xvt_vobj_get_client_rect(win(), &rw);
  const int width = xvt_rect_get_width(&rw);

	x = 0;
	for (int i = 0; i < len; i++)
	{
		unsigned char k = row[i];
		
		switch (k)
		{
		case '\b' :
			id = DLG_BACKSPACE;
			prompt = "<<";
			break;
		case '\n' :
			id = DLG_OK;
			prompt = "Invio";
			break;
		case '\01' :
			id = DLG_CAPS;
			prompt = "Mai";
			break;
		case '\02' :
			id = DLG_RSHIFT;
			prompt = "Shift";
			break;
		case '\03' :
			id = DLG_LSHIFT;
			prompt = "Shift";
			break;
		case '\04' :
			id = DLG_LARR;
			prompt = "<-";
			break;
		case '\05' :
			id = DLG_RARR;
			prompt = "->";
			break;
		case '\06' :
			id = DLG_F2;
			prompt = "Azzera";
			break;
		case '\27' :
			id = DLG_CANCEL;
			prompt = "Esc";
			break;
		default :
			if (k >= ' ')
			{
				id = DLG_BASE + k;
				prompt = " "; prompt[0] = k;
			}
			break;
		}
		
		const int w = prompt.len() > 2 ? 2 : 1;
		prompt.insert("@g");
		TButton_field & b = add_button(id, 0, "", x, y, w, 2, "");
		TFilename bmp(prompt);

		if (TImage::build_filename(bmp))
			b.set_bmp(bmp);
		else
			b.set_prompt(prompt);

		set_handler(id, handler);
		
		RCT r;

		r.left = x * (width / buttons_per_row() -  4);
		r.right = r.left + w * width / buttons_per_row() ;
		r.top = (ROWY - 2) * y;
		r.bottom = r.top + ROWY * 2;
		b.set_rect(r);
		x += w;
	}
}

KEY TVirtual_keyboard::run()
{
	if (id2pos(500 + '0') < 0)
		init();
	set(101, fld().get());
	_pos = fld().get().len();
	field(101).set_caret_pos(_pos);

	KEY k = TMask::run();

	if (k == K_ENTER)
	{
		TMask & mask = fld().mask();

		fld().set(get(101));
		fld().set_focus();
		mask.send_key(K_TAB, 0);
		mask.send_key(K_F12, 0);
	}
	else
		_fld.set_focus();
	return k;
}

void TVirtual_keyboard::init()
{
	TString flags;

	if (fld().password())
		flags << '*';
	if (fld().roman())
		flags << 'M';
	if (fld().right_justified())
		flags << 'R';
  if (fld().uppercase())
		flags << 'U';
	
	byte trim = fld().trim();

	if (trim == 0)
	  flags << '_';
	else
		if (trim == 1)
			flags << '@';
		else
			if (trim == 2)
				flags << '#';

	TEdit_field & e = add_string(101, 0, "", 1, 0, fld().size(), flags);

	e.set_read_only(true);
  e.allow_pipe(fld().pipe_allowed());

	create_keyboard_row(1, "1234567890'�\b\27");
	create_keyboard_row(3, "qwertyuiop�+\n\06");
	create_keyboard_row(5, "\01asdfghjkl���\04\05");
	create_keyboard_row(7,"\02<zxcvbnm,.- \03");
}

TVirtual_keyboard::TVirtual_keyboard(TMask_field & fld, int cols, int rows)
									: TMask(fld.prompt(), 1, cols, rows), _fld(fld)

{
	int size = fld.size();
	
  RCT f, m, k;

	fld.get_rect(f);
	xvt_vobj_get_client_rect(fld.parent(), &m);
	xvt_vobj_get_outer_rect(win(), &k);

	int height = xvt_rect_get_height(&k);
  int width = xvt_rect_get_width(&k);
	int ypos = f.bottom + 3;
	int xpos = f.left ;

	if (ypos + height > m.bottom)
		ypos = f.top - 10 - height - xvt_vobj_get_attr(win(), ATTR_TITLE_HEIGHT); // attualmente wxWidget ignora i titoli


	if (xpos + width > m.right)
		xpos = f.right - width;
	if (xpos < 0)
		xpos = 20;

	k.top = ypos;
	k.bottom = ypos + height;
	k.left = xpos;
	k.right = xpos + width;
	xvt_vobj_move(win(), &k);
}

void TVirtual_numpad::init()
{
	TString flags;

	if (fld().password())
		flags << '*';
	if (fld().roman())
		flags << 'M';
	if (fld().right_justified())
		flags << 'R';
  if (fld().uppercase())
		flags << 'U';
  	
	byte trim = fld().trim();

	if (trim == 0)
	  flags << '_';
	else
		if (trim == 1)
			flags << '@';
		else
			if (trim == 2)
				flags << '#';

	if (_currency )
		add_currency(101, 0, "", 1, 0, fld().size(), flags);
	else
		add_number(101, 0, "", 1, 0, fld().size(), flags, ((TReal_field& )fld()).decimals());

	field(101).set_read_only(true);
  field(101).allow_pipe(fld().pipe_allowed());

	create_keyboard_row(1, "789\b");
	create_keyboard_row(3, "456-\06");
	create_keyboard_row(5, "123\04\05");
	create_keyboard_row(7, "0,\n\27");
}


TVirtual_numpad::TVirtual_numpad(TMask_field & fld, bool currency, int cols, int rows)
								: TVirtual_keyboard(fld, cols, rows), _currency(currency)

{
}