//
//  lcd_gui_create_floatfield.c	  Part of GUI support library, Float number field object
//  Copyright(C)2014 Toyohiko Togashi tog001@nifty.com
//
//
//  This program is free software; you can redistribute it and/or modify it under the terms of the
//  GNU General Public License as published by the Free Software Foundation; either version 3
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//  See the GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License along with this program.
//  If not, see <http://www.gnu.org/licenses/>
//
//
//    Update history
//    ---------- ----- -------------------------------------------
//    2014.02.15 v0.0  First cording
//    2014.03.15 v0.2  Commit
//

#include <stddef.h>						// NULL,...
#include <string.h>						// strcpy(),...
#include <stdio.h>						// sprintf(),...
#include <stdlib.h>						// atof(),...
#include "lcd_gui_create_floatfield.h"	// My structure
#include "lcd_gui_manage.h"				// lcd_guiSetDirtys()...
#include "lcd_gui_create.h"				// lcd_guiNew...
#include "lcd_gui_create_keypad.h"		// Key pad function
#include "lcd_color.h"					// LCD_COLOR*

int lcd_guiSetFloatFieldValue(struct lcd_guiFloatField *field, float f) {
	if ((f >= field->min) && (f <= field->max)) {
		field->value = f;
		sprintf(field->buff, field->format, f);
		lcd_guiSetDirtys(field);
		return(0);
	} else {
		return(1);
	}
}

void lcd_guiTouchFloatPad(struct lcd_guiButton *button){
	struct lcd_guiKeyPad		*keyPad;
	char						*caption;
	struct lcd_guiFloatField	*field;
	int							keyClose;

	keyClose = 0;
	keyPad   = (struct lcd_guiKeyPad *)lcd_guiGetParent(button);
	field    = (struct lcd_guiFloatField *)keyPad->targetField;
	caption  = button->capSeg->str;
	if (!strcmp(caption, "=")) {
		if (!lcd_guiSetFloatFieldValue(field, atof(field->buff))) {
			if (field->actionProg) {
				field->actionProg(field);
			}
			keyClose = 1;
		}
	} else if (!strcmp(caption, "Esc")){
		lcd_guiSetFloatFieldValue(field, field->value);
		keyClose = 1;
	} else if (!strcmp(caption, "C")){
		field->buff[0] = '\0';
		lcd_guiSetDirtys(field);
	} else if (caption[0] != '+'){
		if (strlen(field->buff) < (sizeof(field->buff)-2)) {
			strcat(field->buff, caption);
			lcd_guiSetDirtys(field);
		}
	}
	if (keyClose) {
		struct lcd_guiGroup	*t;
		struct lcd_guiRoot	*root;

		for(t = (struct lcd_guiGroup *)keyPad; t != NULL; t = lcd_guiGetParent(t)) {
			root = (struct lcd_guiRoot *)t;		// Search the root
		}
		lcd_guiDelete(root->popup);
		root->popup = NULL;
	}
	return;
}

void lcd_guiTouchFloatField(enum lcd_guiEvent event, struct lcd_guiCoordinate *touch, struct lcd_guiGroup *seg){
	struct lcd_guiFloatField	*field;
	struct lcd_guiGroup			*t;
	struct lcd_guiRoot			*root;
	struct lcd_guiArea			a;

	field = (struct lcd_guiFloatField *)seg;
	switch(event){
	case LCD_GUI_EVENT_TOUCH:
		break;
	case LCD_GUI_EVENT_RELEASE:
		a.x      = 0;
		a.y      = field->grp.area.height;
		a.width  = LCD_GUI_FLOAT_FIELD_TENKEY_SIZE_W;
		a.height = LCD_GUI_FLOAT_FIELD_TENKEY_SIZE_H;
		for(t = seg; t != NULL; t = lcd_guiGetParent(t)) {	// Search the root
			a.x += t->area.x;		// Calculate the field coordinate on root window
			a.y += t->area.y;
			root = (struct lcd_guiRoot *)t;
		}
		if ((a.x + LCD_GUI_FLOAT_FIELD_TENKEY_SIZE_W) >= root->grp.area.width) {	// off screen
			a.x = root->grp.area.width - LCD_GUI_FLOAT_FIELD_TENKEY_SIZE_W;
		}
		if ((a.y + LCD_GUI_FLOAT_FIELD_TENKEY_SIZE_H) >= root->grp.area.height) {
			a.y = a.y - LCD_GUI_FLOAT_FIELD_TENKEY_SIZE_H - field->grp.area.height;
		}
		if (root->popup != NULL) {	// Already open
			lcd_guiDelete(root->popup);
		}
		root->popup = (struct lcd_gui *)lcd_guiNewKeyPad(
				root, a.x, a.y, a.width, a.height,
				LCD_GUI_KEYPAD_TYPE_TENKEY,
				lcd_guiTouchFloatPad,
				field);
		break;
	default:
		break;
	}

	return;
}

struct lcd_guiFloatField *lcd_guiInitFloatField(
		struct lcd_guiFloatField *alloc,
		short			x,
		short			y,
		short			width,
		short			height,
		unsigned short	faceColor,
		unsigned short	backColor,
		char			*format,
		const struct lcd_font *font,
		float			min,
		float			max,
		float			value,
		void			(*actionProg)(struct lcd_guiFloatField *seg))
{
	unsigned short		darkColor;
	unsigned short		brightColor;

	darkColor   = lcd_colorToDark(backColor);
	brightColor = lcd_colorToLight(backColor);
	lcd_guiInitGroup(&(alloc->grp), x, y, width, height, darkColor, NULL, lcd_guiTouchFloatField);
	lcd_guiNewRect((struct lcd_guiGroup*)alloc, width-1, 0, 1, height-1, brightColor);
	lcd_guiNewRect((struct lcd_guiGroup*)alloc, 0, height-1, width, 1, brightColor);
	lcd_guiNewText((struct lcd_guiGroup*)alloc, 1, 1, width-2, height-2, faceColor, backColor, LCD_GUI_TEXT_ALIGN_RIGHT, LCD_GUI_TEXT_ALIGN_CENTER, alloc->buff, font);
	alloc->format       = format;
	alloc->min          = min;
	alloc->max          = max;
	alloc->actionProg   = actionProg;
	lcd_guiSetFloatFieldValue(alloc, value);
	return(alloc);
}
