/*  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 2 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, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
// (C) PicoPeta Simputers Pvt. Ltd. 
// Author: Santhosh N

#include "picoapi.h"
#include <frame.h>
#include <display.h>
#include <string.h>
#include <stdlib.h>

picoapi* api = NULL;

int picoapi_get_ui_constant(const picoapi*, ui_constants);
const char* picoapi_get_theme_constant(const picoapi*, theme_constants);
const char* picoapi_get_store_location(const picoapi*, store_locations);
const char* picoapi_get_lang_constant(const picoapi*, lang_constants);

void top_toolbar_redraw(px_widget*);
void toolbar_show(px_widget*);
void bottom_toolbar_redraw(px_widget*);
void bottom_toolbar_show(px_widget*);
Bool bottom_toolbar_configure(px_widget*, px_event*);

void toolbar_disable(toolbar*);
void toolbar_enable(toolbar*);
void toolbar_destroy(toolbar*);

picoapi* picoapi_get_picoapi()
{
	if (api == NULL)
	{
		unsigned int count;
		char buffer[1024];
		FILE* f;
		
		api = (picoapi*)malloc(sizeof(picoapi));
		
		api->get_ui_constant = picoapi_get_ui_constant;
		api->get_theme_constant = picoapi_get_theme_constant;
		api->get_store_location = picoapi_get_store_location;
		api->get_lang_constant = picoapi_get_lang_constant;

		// Load the UI constants.
		
		for (count = 0; count < NR_UI_CONSTANTS; count++)
			api->ui[count] = 0;
		
		f = fopen("/usr/local/etc/ui_constants", "r");

		if (f != NULL)
		{
			char ctemp[20], val;
			
			while (fgets(buffer, 1024, f) != NULL)
			{
				char* equal = strchr(buffer, '=');
				buffer[strlen(buffer) - 1] = '\0';

				if (equal != NULL)
				{
					int len = equal - buffer; 
					strncpy(ctemp, buffer, len);
					ctemp[len] = '\0';
					val = atoi(equal+1);
					
					if (strcmp(ctemp, "v11") == 0)
						api->ui[V11] = val;
					if (strcmp(ctemp, "v12") == 0)
						api->ui[V12] = val;
					if (strcmp(ctemp, "v13") == 0)
						api->ui[V13] = val;
					if (strcmp(ctemp, "v21") == 0)
						api->ui[V21] = val;
					if (strcmp(ctemp, "v21") == 0)
						api->ui[V21] = val;
					if (strcmp(ctemp, "v22") == 0)
						api->ui[V22] = val;
					if (strcmp(ctemp, "v23") == 0)
						api->ui[V23] = val;
					if (strcmp(ctemp, "v31") == 0)
						api->ui[V31] = val;
					if (strcmp(ctemp, "v32") == 0)
						api->ui[V32] = val;
					if (strcmp(ctemp, "v33") == 0)
						api->ui[V33] = val;
					if (strcmp(ctemp, "v41") == 0)
						api->ui[V41] = val;
					if (strcmp(ctemp, "v42") == 0)
						api->ui[V42] = val;
					if (strcmp(ctemp, "v43") == 0)
						api->ui[V43] = val;
					if (strcmp(ctemp, "v51") == 0)
						api->ui[V51] = val;
					if (strcmp(ctemp, "v52") == 0)
						api->ui[V52] = val;
					if (strcmp(ctemp, "v53") == 0)
						api->ui[V53] = val;
				}
			}

			fclose(f);
		}
				
		// Load theme constants

		for (count = 0; count < NR_THEME_CONSTANTS; count++)
			api->theme[count] = NULL;
		
		f = fopen("/usr/local/etc/tk_theme", "r");

		if (f != NULL)
		{
			char ctemp[512], *vtemp;
			
			while (fgets(buffer, 1024, f) != NULL)
			{
				char* equal = strchr(buffer, '=');
				buffer[strlen(buffer) - 1] = '\0';

				if (equal != NULL)
				{
					int len = equal - buffer; 
					strncpy(ctemp, buffer, len);
					ctemp[len] = '\0';
					vtemp = strdup(equal+1);

					if (strcmp(ctemp, "toolbar_background") == 0)
						api->theme[TOOLBAR_BACKGROUND] = vtemp;
					if (strcmp(ctemp, "toolbar_foreground") == 0)
						api->theme[TOOLBAR_FOREGROUND] = vtemp;
					if (strcmp(ctemp, "button_background") == 0)
						api->theme[BUTTON_BACKGROUND] = vtemp;
					if (strcmp(ctemp, "button_foreground") == 0)
						api->theme[BUTTON_FOREGROUND] = vtemp;
					if (strcmp(ctemp, "toolbar_relief") == 0)
						api->theme[TOOLBAR_RELIEF] = vtemp;
					if (strcmp(ctemp, "font") == 0)
						api->theme[FONT] = vtemp;
					if (strcmp(ctemp, "button_padding") == 0)
						api->theme[BUTTON_PADDING] = vtemp;
					if (strcmp(ctemp, "button_relief") == 0)
						api->theme[BUTTON_RELIEF] = vtemp;
					if (strcmp(ctemp, "border_width") == 0)
						api->theme[BORDER_WIDTH] = vtemp;
					if (strcmp(ctemp, "top_toolbar_width") == 0)
						api->theme[TOP_TOOLBAR_WIDTH] = vtemp;
					if (strcmp(ctemp, "top_toolbar_height") == 0)
						api->theme[TOP_TOOLBAR_HEIGHT] = vtemp;
					if (strcmp(ctemp, "bot_toolbar_width") == 0)
						api->theme[BOT_TOOLBAR_WIDTH] = vtemp;
					if (strcmp(ctemp, "bot_toolbar_height") == 0)
						api->theme[BOT_TOOLBAR_HEIGHT] = vtemp;
					if (strcmp(ctemp, "images_dir") == 0)
						api->theme[IMAGES_DIR] = vtemp;
					if (strcmp(ctemp, "icons_dir") == 0)
						api->theme[ICONS_DIR] = vtemp;
				}
			}

			fclose(f);
		}

		
		// Load store locations.

		for (count = 0; count < NR_STORE_LOCATIONS; count++)
			api->stores[count] = NULL;
		
		f = fopen("/usr/local/etc/store_locations", "r");

		if (f != NULL)
		{
			char ctemp[100], *vtemp;
			while (fgets(buffer, 1024, f) != NULL)
			{
				char* equal = strchr(buffer, '=');
				buffer[strlen(buffer) - 1] = '\0';

				if (equal != NULL)
				{
					int len = equal - buffer; 
					strncpy(ctemp, buffer, len);
					ctemp[len] = '\0';
					vtemp = strdup(equal+1);
		
					if (strcmp(ctemp, "storedir") == 0)
						api->stores[STOREDIR] = vtemp;
					if (strcmp(ctemp, "storedir1") == 0)
						api->stores[STOREDIR2] = vtemp;
					if (strcmp(ctemp, "storedir2") == 0)
						api->stores[STOREDIR3] = vtemp;
				}
			}

			fclose(f);
		}

		// Load lang constants.

		for (count = 0; count < NR_LANG_CONSTANTS; count++)
			api->lang[count] = NULL;
		
		f = fopen("/usr/local/etc/current_language", "r");

		if (f != NULL)
		{
			char ctemp[100];
			
			fscanf(f, "%s", ctemp);
			api->lang[LANGUAGE] = strdup(ctemp);

			fclose(f);
		}
		else
		{
			api->lang[LANGUAGE] = "en_US";
		}
	}

	return api;
}

		
int picoapi_get_ui_constant(const picoapi* api, ui_constants param)
{
	return api->ui[param];
}

const char* picoapi_get_theme_constant(const picoapi* api, theme_constants param)
{
	return api->theme[param];
}

const char* picoapi_get_store_location(const picoapi* api, store_locations param)
{
	return api->stores[param];
}

const char* picoapi_get_lang_constant(const picoapi* api, lang_constants param)
{
	return api->lang[param];
}

toolbar* toolbar_create(px_widget* parent, toolbar_type type, Bool retract)
{
	toolbar* bar; 
	picoapi* p = picoapi_get_picoapi();
	int tx, ty, twidth, theight;
	const char* cbgd;
	
	if (type == BOTTOM_TOOLBAR && parent->wtype != TOPLEVEL)
	{
		printf("A bottom bar's parent has to be a toplevel!\n");
		return NULL;
	}

	px_color bgd;
	px_display* display = get_display();
	bar = (toolbar*)malloc(sizeof(toolbar));
	bar->type = type;
	bar->retractable = retract;
	
	if (type == TOP_TOOLBAR)
	{
		const char* width = p->get_theme_constant(p, TOP_TOOLBAR_WIDTH);
		const char* height = p->get_theme_constant(p, TOP_TOOLBAR_HEIGHT);
		tx = 0;
		ty = 0;

		if (width != NULL)
			twidth = atoi(width);
		else
			twidth = 320;

		if (height != NULL)
			theight = atoi(height);
		else
			theight = 25;
	}
	else
	{
		const char* width = p->get_theme_constant(p, BOT_TOOLBAR_WIDTH);
		const char* height = p->get_theme_constant(p, BOT_TOOLBAR_HEIGHT);
		
		
		if (width != NULL)
			twidth = atoi(width);
		else
			twidth = 320;

		if (height != NULL)
			theight = atoi(height);
		else
			theight = 25;
		tx = 0;
		ty = parent->height - theight;
	}

	bar->mainframe = new_widget(FRAME, parent, tx, ty, twidth, theight, NULL);
	if (type == TOP_TOOLBAR)
	{
		bar->mainframe->redraw = top_toolbar_redraw;
		bar->mainframe->show = toolbar_show;
	}
	else
	{
		bar->mainframe->redraw = bottom_toolbar_redraw;
		bar->mainframe->show = bottom_toolbar_show;
		bar->mainframe->callbacks[CONFIGURE] = bottom_toolbar_configure;
	}

	
	
	bgd.type = SOLID;
	cbgd = p->get_theme_constant(p, TOOLBAR_BACKGROUND);

	if (cbgd != NULL)
		widget_xcolor_from_str(&(bgd.first_color), cbgd);
	else
		widget_xcolor_from_str(&(bgd.first_color), "white");
	bar->mainframe->set_background_color(bar->mainframe, &bgd);

	bar->mainframe->redraw(bar->mainframe);
	if (retract)
	{
		bar->old_client_message = parent->default_callbacks[CLIENT_MESSAGE];
		bar->old_callback_parameter = parent->callback_parameters[CLIENT_MESSAGE];
	
		parent->default_callbacks[CLIENT_MESSAGE] = toolbar_toggle;
		parent->callback_parameters[CLIENT_MESSAGE] = (void*)bar;
		bar->mainframe->hide(bar->mainframe);
	}
	else
	{
		bar->old_client_message = NULL;
		bar->old_callback_parameter = NULL;
		bar->mainframe->show(bar->mainframe);
	}

	bar->enabled = True;
		

	bar->disable = toolbar_disable;
	bar->enable = toolbar_enable;
	bar->destroy = toolbar_destroy;

	display->register_wm_protocol(display, "_AC_BUTTON_RETRACTBAR_REL");

	return bar;
}

void toolbar_show(px_widget* widget)
{
	widget->raise(widget);
	frame_show(widget);
}

void bottom_toolbar_show(px_widget* widget)
{
	picoapi* p = picoapi_get_picoapi();
	int ty;
	const char* height = p->get_theme_constant(p, BOT_TOOLBAR_HEIGHT);

	if (height != NULL)
		ty = widget->child_of->height - atoi(height);
	else
		ty = widget->child_of->height - 25;

	if (widget->y != ty)
	{
		widget->set_position(widget, widget->x, ty);
	}
	
	toolbar_show(widget);
}

void top_toolbar_redraw(px_widget* widget)
{
	GC gc, mask_gc;
	picoapi* p = picoapi_get_picoapi();
	int startx, starty, endx, endy;
	const char* height = p->get_theme_constant(p, TOP_TOOLBAR_HEIGHT);
	Display* display = display_get_Xdisplay();
	
	frame_redraw(widget);
	gc = XCreateGC(display, widget->backing_store.pxmp, 0, NULL);

	XSetForeground(display, gc, BlackPixel(display, DefaultScreen(display)));
	XSetLineAttributes(display, gc, 1, LineSolid, CapRound, JoinBevel);

	if (widget->backing_store.mask != None)
	{
		mask_gc = XCreateGC(display, widget->backing_store.mask, 0, NULL);

		XSetForeground(display, mask_gc, 1);
		XSetLineAttributes(display, mask_gc, 1, LineSolid, CapRound, JoinBevel);
	}

	startx = 0;

	if (height != NULL)
		starty = atoi(height) - 1;
	else
		starty = 24; // 25 (default) - 1

	endx = widget->width;
	
	endy = starty;

	XDrawLine(display, widget->backing_store.pxmp, gc, startx, starty, endx, endy);
	XFreeGC(display, gc);
	
	if (widget->backing_store.mask != None)
	{
		XDrawLine(display, widget->backing_store.pxmp, mask_gc, startx, starty, endx, endy);
		XFreeGC(display, gc);
	}
	XClearWindow(display, widget->win);
}

void bottom_toolbar_redraw(px_widget* widget)
{
	GC gc, mask_gc;
	picoapi* p = picoapi_get_picoapi();
	int startx, starty, endx, endy;
	Display* display = display_get_Xdisplay();
	
	frame_redraw(widget);
	gc = XCreateGC(display, widget->backing_store.pxmp, 0, NULL);

	XSetForeground(display, gc, BlackPixel(display, DefaultScreen(display)));
	XSetLineAttributes(display, gc, 1, LineSolid, CapRound, JoinBevel);

	if (widget->backing_store.mask != None)
	{
		mask_gc = XCreateGC(display, widget->backing_store.mask, 0, NULL);

		XSetForeground(display, mask_gc, 1);
		XSetLineAttributes(display, mask_gc, 1, LineSolid, CapRound, JoinBevel);
	}

	startx = 0;
	starty = 0;
	endx = widget->width;
	endy = starty;

	XDrawLine(display, widget->backing_store.pxmp, gc, startx, starty, endx, endy);
	XFreeGC(display, gc);
	
	if (widget->backing_store.mask != None)
	{
		XDrawLine(display, widget->backing_store.pxmp, mask_gc, startx, starty, endx, endy);
		XFreeGC(display, mask_gc);
	}
	XClearWindow(display, widget->win);
}

Bool bottom_toolbar_configure(px_widget* widget, px_event*event)
{
	widget->set_position(widget, 0, event->xev->xconfigure.height - widget->height);
	return True;
}
void toolbar_enable(toolbar* bar)
{
	bar->enabled = True;
}

void toolbar_disable(toolbar* bar)
{
	bar->enabled = False;
	bar->mainframe->hide(bar->mainframe);
}

	
Bool toolbar_toggle(px_widget* widget, px_event* event)
{
	toolbar* bar = (toolbar*)event->private_data;
	px_display* display = get_display();
	Bool ret= True;
	Atom retractable = display->get_atom(display, "_AC_BUTTON_RETRACTBAR_REL");
	Atom protocol_atom = display->get_atom(display, "WM_PROTOCOLS");

	if (bar->old_client_message != NULL)
	{
		event->private_data = bar->old_callback_parameter;
		ret = bar->old_client_message(widget, event);
		event->private_data = (void*)bar;
	}
	
	if (ret && event->xev->xclient.message_type == protocol_atom && bar->enabled && 
			event->xev->xclient.data.l[0] == retractable)
	{
		if (bar->mainframe->hidden)
		{
			bar->mainframe->show(bar->mainframe);
		}
		else
		{
			bar->mainframe->hide(bar->mainframe);
		}
	}

	return ret;
}

	
void toolbar_destroy(toolbar* bar)
{
//	bar->mainframe->destroy(bar->mainframe);
}


			
	
	
