//
//  lcd_gui_create.h	  Part of GUI support library, Generic 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
//

#ifndef LCD_GUI_FIGURE_CREATE_H_
#define LCD_GUI_FIGURE_CREATE_H_

#include "lcd_gui_figure.h"
#include "lcd_draw.h"					// LCD_SCREEN_HEIGHT,WIDTH

//
//	API	- Static memory functions
//
// Initialization parameter macro
//	ex:	struct lcd_guiRect rect1 = LCD_GUI_INIT_RECT(NULL, NULL, 0,0, 10,10, LCD_COLOR_ROYALBLUE);
//		struct lcd_guiRect rect2 = LCD_GUI_INIT_RECT(&rect1,NULL, 20,0, 10,10, LCD_COLOR_ROYALBLUE);
#define LCD_GUI_INIT_SEG(next,prev,dispProg)														{(struct lcd_gui*)(next),(struct lcd_gui*)(prev),{1,0,0,0},dispProg}
#define LCD_GUI_INIT_RECT(next,prev,x,y,width,height,color)											{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayRect),{x,y,width,height},color}
#define LCD_GUI_INIT_LINE(next,prev,sx,sy,ex,ey,lineWidth,color)									{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayLine),{sx,sy},{ex,ey},lineWidth,color}
#define LCD_GUI_INIT_POLY(next,prev,point,n,m,lineWidth,color)										{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayPoly),point,n,m,lineWidth,color}
#define LCD_GUI_INIT_ARC(next,prev,x,y,r,srad,erad,lineWidth,color)									{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayArc),{x,y},r,srad,erad,lineWidth,color}
#define LCD_GUI_INIT_STR(next,prev,x,y,faceColor,backColor,str)										{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayStr),{x,y},{faceColor,backColor},str}
#define LCD_GUI_INIT_TEXT(next,prev,x,y,width,height,faceColor,backColor,hAlign,vAlign,str,font)	{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayText),{x,y,width,height},{faceColor,backColor},{hAlign,vAlign},str,font}
#define LCD_GUI_INIT_IMAGE(next,prev,x,y,width,height,image)										{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayImage),{x,y,width,height},image}
#define LCD_GUI_INIT_7SEG(next,prev,x,y,width,height,faceColor,backColor,lineWidth,column,pattern)	{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplay7seg),{x,y,width,height},{faceColor,backColor},lineWidth,column,pattern}
#define LCD_GUI_INIT_GAGE(next,prev,x,y,width,height,faceColor,backColor,vartical,value)			{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayGage),{x,y,width,height},{faceColor,backColor},{vartical},value}
#define LCD_GUI_INIT_BAR_CHART(next,prev,x,y,width,height,backColor,vartical,n,value,color)			{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayBarChart),{x,y,width,height},backColor,{vartical},n,value,color}
#define LCD_GUI_INIT_PARENT(next,prev,parent)														{LCD_GUI_INIT_SEG(next,prev,NULL),parent}
#define LCD_GUI_INIT_GROUP(next,prev,x,y,width,height,backColor,figures,eventProg)					{LCD_GUI_INIT_SEG(next,prev,lcd_guiDisplayGroup),{x,y,width,height},backColor,(struct lcd_gui*)(figures),eventProg}
#define LCD_GUI_INIT_ROOT(backColor,figures,eventProg)												{LCD_GUI_INIT_GROUP(NULL,NULL,0,0,LCD_SCREEN_WIDTH,LCD_SCREEN_HEIGHT,backColor,figures,(eventProg==NULL?lcd_guiDefaultActionRoot:eventProg)), NULL}

struct lcd_guiGroupSet {
	struct lcd_guiGroup		group;
	struct lcd_guiParent	p;
};
#define LCD_GUI_INIT_GROUP_SET(name,next,prev,x,y,width,height,backColor,figures,eventProg)			{LCD_GUI_INIT_GROUP(next,prev,x,y,width,height,backColor,&(name.p),eventProg), LCD_GUI_INIT_PARENT(figures,NULL,NULL)}

struct lcd_guiRootSet {
	struct lcd_guiRoot		root;
	struct lcd_guiParent	p;
};
#define LCD_GUI_INIT_ROOT_SET(name, backColor,figures,eventProg)									{LCD_GUI_INIT_ROOT(backColor,&(name.p),eventProg), LCD_GUI_INIT_PARENT(figures,NULL,NULL), }

// Argument is converted to control block
extern struct lcd_guiRect		*lcd_guiInitRect(struct lcd_guiRect *alloc, short x, short y, short width, short height, unsigned short color);
extern struct lcd_guiLine		*lcd_guiInitLine(struct lcd_guiLine *alloc, short sx, short sy, short ex, short ey, short lineWidth, unsigned short color);
extern struct lcd_guiPoly		*lcd_guiInitPoly(struct lcd_guiPoly *alloc, struct lcd_guiCoordinate *point, int n, int m, short lineWidth, unsigned short color);
extern struct lcd_guiArc		*lcd_guiInitArc(struct lcd_guiArc *alloc, short x, short y, short r, float srad, float erad, short lineWidth, unsigned short color);
extern struct lcd_guiStr		*lcd_guiInitStr(struct lcd_guiStr *alloc, short x, short y, unsigned short faceColor, unsigned short backColor, char *str);
extern struct lcd_guiText		*lcd_guiInitText(struct lcd_guiText *alloc, short x, short y, short width, short height, unsigned short faceColor, unsigned short backColor, int hAlign, int vAlign, char *str, const struct lcd_font *font);
extern struct lcd_guiImage		*lcd_guiInitImage(struct lcd_guiImage *alloc, short x, short y, short width, short height, unsigned short *image);
extern struct lcd_gui7seg		*lcd_guiInit7seg(struct lcd_gui7seg *alloc, short x, short y, short width, short height, unsigned short faceColor, unsigned short backColor, short lineWidth, int column, unsigned char *pattern);
extern struct lcd_guiGage		*lcd_guiInitGage(struct lcd_guiGage *alloc, short x, short y, short width, short height, unsigned short faceColor, unsigned short backColor, int vartical, float value);
extern struct lcd_guiBarChart	*lcd_guiInitBarChart(struct lcd_guiBarChart *alloc, short x, short y, short width, short height, unsigned short backColor, int vartical, int n, float *value, unsigned short *color);
extern struct lcd_guiGroup		*lcd_guiInitGroup(struct lcd_guiGroup *alloc, short x, short y, short width, short height, unsigned short backColor, struct lcd_gui *figures, void (*eventProg)(enum lcd_guiEvent event, struct lcd_guiCoordinate *touch, struct lcd_guiGroup *seg));
extern struct lcd_guiParent		*lcd_guiInitParent(struct lcd_guiParent *alloc, struct lcd_guiGroup *parent);
extern struct lcd_guiRoot		*lcd_guiInitRoot(struct lcd_guiRoot *alloc, unsigned short backColor, struct lcd_gui *figures, void (*eventProg)(enum lcd_guiEvent event, struct lcd_guiCoordinate *touch, struct lcd_guiGroup *seg));


//
//	API	- Dynamic memory functions
//

// Allocation
//extern struct lcd_guiRect		*lcd_guiAllocRect(struct lcd_guiGroup *group);
//extern struct lcd_guiLine		*lcd_guiAllocLine(struct lcd_guiGroup *group);
//extern struct lcd_guiPoly		*lcd_guiAllocPoly(struct lcd_guiGroup *group);
//extern struct lcd_guiArc		*lcd_guiAllocArc(struct lcd_guiGroup *group);
//extern struct lcd_guiStr		*lcd_guiAllocStr(struct lcd_guiGroup *group);
//extern struct lcd_guiText		*lcd_guiAllocText(struct lcd_guiGroup *group);
//extern struct lcd_guiImage	*lcd_guiAllocImage(struct lcd_guiGroup *group);
//extern struct lcd_gui7seg		*lcd_guiAlloc7seg(struct lcd_guiGroup *group);
//extern struct lcd_guiGage		*lcd_guiAllocGage(struct lcd_guiGroup *group);
//extern struct lcd_guiBarChart	*lcd_guiAllocBarChart(struct lcd_guiGroup *group);
//extern struct lcd_guiGroup	*lcd_guiAllocGroup(struct lcd_guiGroup *group);
//extern struct lcd_guiRoot		*lcd_guiAllocRoot(void);

// Alloc + Init
//extern struct lcd_guiRect		*lcd_guiNewRect(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short color);
//extern struct lcd_guiLine		*lcd_guiNewLine(struct lcd_guiGroup *group, short sx, short sy, short ex, short ey, short lineWidth, unsigned short color);
//extern struct lcd_guiPoly		*lcd_guiNewPoly(struct lcd_guiGroup *group, struct lcd_guiCoordinate *point, int n, int m, short lineWidth, unsigned short color);
//extern struct lcd_guiArc		*lcd_guiNewArc(struct lcd_guiGroup *group, short x, short y, short r, float srad, float erad, short lineWidth, unsigned short color);
//extern struct lcd_guiStr		*lcd_guiNewStr(struct lcd_guiGroup *group, short x, short y, unsigned short faceColor, unsigned short backColor, char *str);
//extern struct lcd_guiText		*lcd_guiNewText(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short faceColor, unsigned short backColor, int hAlign, int vAlign, char *str, const struct lcd_font *font);
//extern struct lcd_guiImage	*lcd_guiNewImage(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short *image);
//extern struct lcd_gui7seg		*lcd_guiNew7seg(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short faceColor, unsigned short backColor, short lineWidth, int column, unsigned char *pattern);
//extern struct lcd_guiGage		*lcd_guiNewGage(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short faceColor, unsigned short backColor, int vartical, float value);
//extern struct lcd_guiBarChart	*lcd_guiNewBarChart(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short backColor, int vartical, int n, float *value, unsigned short *color);
//extern struct lcd_guiGroup	*lcd_guiNewGroup(struct lcd_guiGroup *group, short x, short y, short width, short height, unsigned short backColor, struct lcd_gui *figures, void (*eventProg)(enum lcd_guiEvent event, struct lcd_guiCoordinate *touch, struct lcd_guiGroup *seg));
//extern struct lcd_guiRoot		*lcd_guiNewRoot(unsigned short backColor, struct lcd_gui *figures, void (*eventProg)(enum lcd_guiEvent event, struct lcd_guiCoordinate *touch, struct lcd_guiGroup *seg));

// Delete
//extern void					lcd_guiDelete(struct lcd_gui *alloc);


//
//	Internals
//
extern struct lcd_gui	*lcd_guiAlloc(struct lcd_guiGroup *group, size_t len);
extern void				lcd_guiDealloc(struct lcd_gui *alloc);
extern void				lcd_guiDefaultActionRoot(enum lcd_guiEvent event, struct lcd_guiCoordinate *touch, struct lcd_guiGroup *seg);
#define lcd_guiAllocRect(g)			(struct lcd_guiRect *)lcd_guiAlloc((g), sizeof(struct lcd_guiRect))
#define lcd_guiAllocLine(g)			(struct lcd_guiLine *)lcd_guiAlloc((g), sizeof(struct lcd_guiLine))
#define lcd_guiAllocPoly(g)			(struct lcd_guiPoly *)lcd_guiAlloc((g), sizeof(struct lcd_guiPoly))
#define lcd_guiAllocStr(g)			(struct lcd_guiStr *)lcd_guiAlloc((g), sizeof(struct lcd_guiStr))
#define lcd_guiAllocImage(g)		(struct lcd_guiImage *)lcd_guiAlloc((g), sizeof(struct lcd_guiImage))
#define lcd_guiAllocText(g)			(struct lcd_guiText *)lcd_guiAlloc((g), sizeof(struct lcd_guiText))
#define lcd_guiAlloc7seg(g)			(struct lcd_gui7seg *)lcd_guiAlloc((g), sizeof(struct lcd_gui7seg))
#define lcd_guiAllocGage(g)			(struct lcd_guiGage *)lcd_guiAlloc((g), sizeof(struct lcd_guiGage))
#define lcd_guiAllocBarChart(g)		(struct lcd_guiBarChart *)lcd_guiAlloc((g), sizeof(struct lcd_guiBarChart))
#define lcd_guiAllocGroup(g)		(struct lcd_guiGroup *)lcd_guiAlloc((g), sizeof(struct lcd_guiGroup))
#define lcd_guiAllocParent(g)		(struct lcd_guiParent *)lcd_guiAlloc((g), sizeof(struct lcd_guiParent))
#define lcd_guiAllocRoot()			(struct lcd_guiRoot *)lcd_guiAlloc(NULL, sizeof(struct lcd_guiRoot))
#define lcd_guiNewRect(g,x,y,w,h,c)						lcd_guiInitRect(lcd_guiAllocRect(g),x,y,w,h,c)
#define lcd_guiNewLine(g,sx,sy,ex,ey,c,lw)				lcd_guiInitLine(lcd_guiAllocLine(g),sx,sy,ex,ey,c,lw)
#define lcd_guiNewPoly(g,c,lw,n,m,pnt)					lcd_guiInitPoly(lcd_guiAllocPoly(g),c,lw,n,m,pnt)
#define lcd_guiNewStr(g,x,y,fc,bc,str)					lcd_guiInitStr(lcd_guiAllocStr(g),x,y,fc,bc,str)
#define lcd_guiNewImage(g,x,y,w,h,img)					lcd_guiInitImage(lcd_guiAllocImage(g),x,y,w,h,img)
#define lcd_guiNewText(g,x,y,w,h,fc,bc,ha,va,str,font)	lcd_guiInitText(lcd_guiAllocText(g),x,y,w,h,fc,bc,ha,va,str,font)
#define lcd_guiNew7seg(g,x,y,w,h,fc,bc,lw,col,pat)		lcd_guiInit7seg(lcd_guiAlloc7seg(g),x,y,w,h,fc,bc,lw,col,pat)
#define lcd_guiNewGage(g,x,y,w,h,fc,bc,a,val)			lcd_guiInitGage(lcd_guiAllocGage(g),x,y,w,h,fc,bc,a,val)
#define lcd_guiNewBarChart(g,x,y,w,h,bc,a,n,val,c)		lcd_guiInitBarChart(lcd_guiAllocBarChart(g),x,y,w,h,bc,a,n,val,c)
#define lcd_guiNewGroup(g,x,y,w,h,c,f,e)				lcd_guiInitGroup(lcd_guiAllocGroup((struct lcd_guiGroup*)(g)),x,y,w,h,c,f,e)
#define lcd_guiNewParent(g)								lcd_guiInitParent(lcd_guiAllocParent(g),g)
#define lcd_guiNewRoot(c,f,e)							lcd_guiInitRoot(lcd_guiAllocRoot(),c,f,e)
#define lcd_guiDelete(a)			(lcd_guiSetHidden((struct lcd_gui*)(a),1), lcd_guiDealloc((struct lcd_gui*)(a)))

#endif /* LCD_GUI_FIGURE_CREATE_H_ */
