//
//  lcd_gui_create_pulldown.c	  Part of GUI support library, Pull down list 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>						// strlen(),...
#include "lcd_gui_create_pulldown.h"	// My
#include "lcd_gui_manage.h"				// lcd_guiSetDurty...
#include "lcd_gui_create.h"				// lcd_guiInitGroup()
#include "lcd_gui_create_button.h"		// lcd_guiNewButton()
#include "lcd_color.h"					// LCD_COLOR*

// Inline function
#define MAX(a,b)	(((a) > (b)) ? (a) : (b))
#define MIN(a,b)	(((a) < (b)) ? (a) : (b))
#define ABS(a)		(((a) >  0 ) ? (a) : -(a))


//
//	Selection list
//
struct lcd_guiSelectionList {
	struct lcd_guiGroup 	grp;			// Essential item
	struct lcd_guiPullDown	*target;
};

struct lcd_guiSelectionList *lcd_guiNewSelectionList(
		struct lcd_guiGroup *parent,
		short			x,
		short			y,
		short			width,
		short			height,
		struct lcd_guiPullDown	*target,
		void			(*callBack)(struct lcd_guiButton *seg))
{
	struct lcd_guiSelectionList *alloc;

	alloc = (struct lcd_guiSelectionList *)lcd_guiAlloc(parent, sizeof(struct lcd_guiSelectionList));
	if (alloc) {
		struct lcd_guiArea		a;
		int						i;

		lcd_guiInitGroup(&(alloc->grp), x, y, width, height, LCD_COLOR_TRANSPARENT, NULL, NULL);
		alloc->target = target;

		a.width  = width;
		a.height = height / target->number;
		a.x      = 0;
		a.y      = 0;
		for(i = 0; i < target->number; i++) {
			lcd_guiNewButton(alloc,
					a.x, a.y, a.width, a.height,
					target->label[i],
					LCD_GUI_PULLDOWN_FONT,
					LCD_GUI_PULLDOWN_COLOR_FACE,
					LCD_GUI_PULLDOWN_COLOR_BACK,
					LCD_GUI_PULLDOWN_COLOR_TOUCH,
					LCD_GUI_BUTTON_MODE_MOMENTARY,
					(i == target->select) ? 1 : 0,
					callBack);
			a.y += a.height;
		}
	}
	return(alloc);
}

//
//	Pull down field
//
int lcd_guiSetPullDownSelect(struct lcd_guiPullDown *attr, int select){
	if ((select >= 0) && (select < attr->number)) {
		if (select != attr->select) {
			attr->select = select;
			attr->caption->str = attr->label[select];
			lcd_guiSetDirtys(attr->caption);
		}
		return(0);
	} else {
		return(1);
	}
}

void lcd_guiTouchPullDownList(struct lcd_guiButton *button){
	struct lcd_guiSelectionList	*list;
	struct lcd_guiPullDown		*field;
	struct lcd_gui				*b;
	int							select;
	struct lcd_guiGroup	*t;
	struct lcd_guiRoot	*root;

	list  = (struct lcd_guiSelectionList *)lcd_guiGetParent(button);
	field = (struct lcd_guiPullDown *)list->target;
	for(b = (struct lcd_gui *)button, select = -2; b != NULL; b = b->prev, select++);
	if (!lcd_guiSetPullDownSelect(field, select)) {
		if (field->actionProg) {
			field->actionProg(field);
		}
	}
	// Close pull down list
	for(t = (struct lcd_guiGroup *)list; t != NULL; t = lcd_guiGetParent(t)) {
		root = (struct lcd_guiRoot *)t;		// Search the root
	}
	lcd_guiDelete(root->popup);
	root->popup = NULL;
	return;
}

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

	field = (struct lcd_guiPullDown *)seg;
	switch(event){
	case LCD_GUI_EVENT_TOUCH:
		break;
	case LCD_GUI_EVENT_RELEASE:
		a.x = field->grp.area.width;
		a.y = 0;
		{
			int		max;
			int		i;
			int		w;

			max = 0;
			for(i = 0; i < field->number; i++) {
				max = MAX(max, strlen(field->label[i]));
			}
			max++;
			w = max * LCD_FONT_WIDTH;
			w = MIN(w, LCD_GUI_PULLDOWN_SIZE_W_MAX);
			w = MAX(w, LCD_GUI_PULLDOWN_SIZE_W_MIN);
			a.width = w;
		}
		a.height = LCD_GUI_PULLDOWN_SIZE_H * field->number;

		root = (struct lcd_guiRoot *)seg;
		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 + a.width) >= root->grp.area.width) {
			a.x -= field->grp.area.width;
			a.x -= a.width;
		}
		if ((a.y + a.height) >= root->grp.area.height) {
			a.y = root->grp.area.height - a.height;
		}

		if (root->popup != NULL) {
			lcd_guiDelete(root->popup);
		}
		root->popup = (struct lcd_gui *)
				lcd_guiNewSelectionList(
				(struct lcd_guiGroup *)root,
				a.x, a.y, a.width, a.height,
				field,
				lcd_guiTouchPullDownList);
		break;
	default:
		break;
	}
	return;
}

struct lcd_guiPullDown *lcd_guiInitPullDown(
		struct lcd_guiPullDown	*alloc,
		short			x,
		short			y,
		short			width,
		short			height,
		unsigned short	faceColor,
		unsigned short	backColor,
		char			**label,
		const struct lcd_font *font,
		int				number,
		int				select,
		void			(*actionProg)(struct lcd_guiPullDown *seg))
{
	unsigned short		darkColor;
	unsigned short		brightColor;
	struct lcd_guiText	*t;

	darkColor   = lcd_colorToDark(backColor);
	brightColor = lcd_colorToLight(backColor);
	lcd_guiInitGroup(&(alloc->grp), x, y, width, height, darkColor, NULL, lcd_guiTouchPullDown);
	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);
	t = lcd_guiNewText((struct lcd_guiGroup*)alloc, 1, 1, width-2, height-2, faceColor, backColor, LCD_GUI_TEXT_ALIGN_CENTER, LCD_GUI_TEXT_ALIGN_CENTER, "", font);
	alloc->label        = label;
	alloc->number       = number;
	alloc->select       = -1;
	alloc->actionProg   = actionProg;
	alloc->caption      = t;
	lcd_guiSetPullDownSelect(alloc, select);
	return(alloc);
}


