/*
 * gkrellmapcupsd version 0.01
 * see COPYING for end-user agreement
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gkrellm2/gkrellm.h>
#include "gkrellmapcupsd.h"

#define	CONFIG_NAME	"gkrellmapcupsd"
#define	STYLE_NAME	"gkrellmapcupsd"

static GtkWidget        *kvbox;
static GkrellmMonitor	*monitor;
static GkrellmPanel	*panel;
static GkrellmPanel	*panel2;
static GkrellmPanel	*panel3;
static GkrellmPanel	*panel4;
static GkrellmDecal	*decal_text1, *decal_text4;
static GkrellmKrell     *krell2, *krell3;
//static gchar            *info,
static gchar *statsloc = "/var/log/apcupsd.status"; 
static gint	        style_id;
static GtkWidget        *voltage_button, *time_left_button, *charge_button, *load_button, *statsloc_text;
static gboolean         show_linev = 1, show_timel = 1, show_charge = 1, show_load = 1;
static time_t           tstatvar;

static void apply_plugin_config(void) {
        if (!show_linev && GTK_TOGGLE_BUTTON(voltage_button)->active)
                gkrellm_panel_show(panel);
        else if (show_linev && !GTK_TOGGLE_BUTTON(voltage_button)->active)
                gkrellm_panel_hide(panel);
	show_linev = GTK_TOGGLE_BUTTON(voltage_button)->active;
        
        if (!show_timel && GTK_TOGGLE_BUTTON(time_left_button)->active)
                gkrellm_panel_show(panel4);
        else if (show_timel && !GTK_TOGGLE_BUTTON(time_left_button)->active)
                gkrellm_panel_hide(panel4);
        show_timel = GTK_TOGGLE_BUTTON(time_left_button)->active;
        
        if (!show_charge && GTK_TOGGLE_BUTTON(charge_button)->active)
                gkrellm_panel_show(panel3);
        else if (show_charge && !GTK_TOGGLE_BUTTON(charge_button)->active)
                gkrellm_panel_hide(panel3);
	show_charge = GTK_TOGGLE_BUTTON(charge_button)->active;
        
        if (!show_load && GTK_TOGGLE_BUTTON(load_button)->active)
                gkrellm_panel_show(panel2);
        else if (show_load && !GTK_TOGGLE_BUTTON(load_button)->active)
                gkrellm_panel_hide(panel2);
	show_load = GTK_TOGGLE_BUTTON(load_button)->active;
        
        statsloc = (char*)gtk_entry_get_text(GTK_ENTRY(statsloc_text));
}

static void save_plugin_config(FILE *f) {
	//int		i;
	//char	str[MAX_STRING_LEN];
	fprintf(f, "%s show_line_voltage %d\n", CONFIG_NAME, show_linev);
	fprintf(f, "%s show_time_left %d\n", CONFIG_NAME, show_timel);
	fprintf(f, "%s show_charge %d\n", CONFIG_NAME, show_charge);
	fprintf(f, "%s show_load %d\n", CONFIG_NAME, show_load);
	fprintf(f, "%s status_path %s\n", CONFIG_NAME, statsloc);
}

static void load_plugin_config(gchar *config_line) {
	gchar	config_keyword[32], config_data[CFG_BUFSIZE];
	gint	n; //, i;
	//char	str[MAX_STRING_LEN];

	if ((n = sscanf(config_line, "%31s %[^\n]",
				config_keyword, config_data)) != 2)
		return;
	
	if ( !strcmp(config_keyword, "show_line_voltage") )
		sscanf(config_data, "%d", &show_linev);
	if ( !strcmp(config_keyword, "show_time_left") )
		sscanf(config_data, "%d", &show_timel);
	if ( !strcmp(config_keyword, "show_charge") )
		sscanf(config_data, "%d", &show_charge);
	if ( !strcmp(config_keyword, "show_load") )
                sscanf(config_data, "%d", &show_load);
        if ( !strcmp(config_keyword, "status_path") ) //TODO: malloc
		sscanf(config_data, "%s", statsloc);
}

void draw_panel(char *value, GkrellmPanel *ppanel, GkrellmDecal *dtext) {
	static gint	x_scroll, w;
        if (w == 0)
		w = gkrellm_chart_width();
        
        //if( !button1_down ) {
        //        if( x_scroll > 0 )
        //                x_scroll -= 1;
        //else
        //        x_scroll = w;
        
	x_scroll = (x_scroll + 1) % (2 * w);
//        dtext->x_off = (w - gdk_string_width(dtext->text_style.font, value)) / 2;
//        if (dtext->x_off < 0)
        dtext->x_off = 0;

        gkrellm_draw_decal_text(ppanel, dtext, value, w - x_scroll);
        gkrellm_draw_panel_layers(ppanel);
}

static gint ppanel_expose_event(GtkWidget *widget, GdkEventExpose *ev, GkrellmPanel *ppanel) {
	gdk_draw_pixmap(widget->window,
			widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
			ppanel->pixmap, ev->area.x, ev->area.y, ev->area.x, ev->area.y,
			ev->area.width, ev->area.height);
	return FALSE;
}

static gint panel_expose_event(GtkWidget *widget, GdkEventExpose *ev) {
        if (show_linev)
                return ppanel_expose_event(widget, ev, panel);
        return 0;
}

static gint panel2_expose_event(GtkWidget *widget, GdkEventExpose *ev) {
        if (show_load)
                return ppanel_expose_event(widget, ev, panel2);
        return 0;
}

static gint panel3_expose_event(GtkWidget *widget, GdkEventExpose *ev) {
        if (show_charge)
                return ppanel_expose_event(widget, ev, panel3);
        return 0;
}

static gint panel4_expose_event(GtkWidget *widget, GdkEventExpose *ev) {
        if (show_timel)
                return ppanel_expose_event(widget, ev, panel4);
        return 0;
}

static void update_plugin() {
	FILE *stats;
	char key[256], value[256];
        struct stat statvar;

	stat(statsloc, &statvar);

        // dont do it too much...
	if ((GK.timer_ticks % 10) != 0 ||
	    tstatvar == statvar.st_mtime)
		return;

	tstatvar = statvar.st_mtime;
	stats = fopen(statsloc, "r");
        
	while (!feof(stats)) {
	  fscanf(stats, "%s : %s\n", key, value);
	  if (strcmp(key, "LINEV") == 0 && show_linev) {
		sprintf(value, "%s Volts", value);
                draw_panel(value, panel, decal_text1);
          }
          else if (strcmp(key, "LOADPCT") == 0 && show_load) {
                gkrellm_update_krell(panel2, krell2, atoi(value));
                gkrellm_draw_panel_layers(panel2);
          }
          else if (strcmp(key, "BCHARGE") == 0 && show_charge) {
                gkrellm_update_krell(panel3, krell3, atoi(value));
                gkrellm_draw_panel_layers(panel3);
          }
          else if (strcmp(key, "TIMELEFT") == 0 && show_timel) {
		int totalmin;
		unsigned char hour, min;
                double sec;
                totalmin = atoi(value);
                hour = (unsigned char)floor(totalmin / 60);
                min = totalmin>59 ? (unsigned char)floor(totalmin % 60) : (unsigned char)totalmin;
                sec = (double)(strtod(value, NULL)-floor(strtod(value, NULL))) * 60.0;
                sprintf(value, "%.2d:%.2d:%.2d Left", hour, min, (unsigned char)sec);
                draw_panel(value, panel4, decal_text4);
	  }
	  else if (strcmp(key, "MODEL") == 0) {
	          //info = (char*)malloc(256);
		  //sprintf(info, ""); //%s", value);
	  }
	}

	fclose(stats);
}


static void
create_plugin(GtkWidget *vbox, gint first_create) {
	GkrellmStyle			*style;
	GkrellmTextstyle		*ts, *ts_alt;
	GkrellmPiximage *krell_image;

	if (first_create) {
		panel = gkrellm_panel_new0();
                panel2 = gkrellm_panel_new0();
                panel3 = gkrellm_panel_new0();
                panel4 = gkrellm_panel_new0();
        }

	style = gkrellm_meter_style(style_id);
        
	ts = gkrellm_meter_textstyle(style_id);
	ts_alt = gkrellm_meter_alt_textstyle(style_id);
	
        krell_image = gkrellm_krell_meter_piximage(style_id);
        
        decal_text1 = gkrellm_create_decal_text(panel, "apcupsd", ts, style, -1, -1, -1);
	krell2 = gkrellm_create_krell(panel2, krell_image, style);
        gkrellm_monotonic_krell_values(krell2, FALSE);
	gkrellm_set_krell_full_scale(krell2, 100, 1);
        gkrellm_set_krell_margins(panel2, krell2, 0, 0);
	krell3 = gkrellm_create_krell(panel3, krell_image, style);
        gkrellm_monotonic_krell_values(krell3, FALSE);
	gkrellm_set_krell_full_scale(krell3, 100, 1);
        gkrellm_set_krell_margins(panel3, krell3, 0, 0);
	decal_text4 = gkrellm_create_decal_text(panel4, "apcupsd", ts, style, -1, -1, -1);

	gkrellm_panel_configure(panel, NULL, style);
	gkrellm_panel_configure(panel2, "Load", style);
	gkrellm_panel_configure(panel3, "Charge", style);
	gkrellm_panel_configure(panel4, NULL, style);

        gkrellm_panel_create(vbox, monitor, panel);
        gkrellm_panel_create(vbox, monitor, panel4);
        gkrellm_panel_create(vbox, monitor, panel3);
        gkrellm_panel_create(vbox, monitor, panel2);

	if (first_create) {
	    g_signal_connect(G_OBJECT (panel->drawing_area), "expose_event", G_CALLBACK (panel_expose_event), NULL);
            if (!show_linev)
                gkrellm_panel_hide(panel);
	    g_signal_connect(G_OBJECT (panel2->drawing_area), "expose_event", G_CALLBACK (panel2_expose_event), NULL);
            if (!show_load)
                gkrellm_panel_hide(panel2);
	    g_signal_connect(G_OBJECT (panel3->drawing_area), "expose_event", G_CALLBACK (panel3_expose_event), NULL);
            if (!show_charge)
                gkrellm_panel_hide(panel3);
	    g_signal_connect(G_OBJECT (panel4->drawing_area), "expose_event", G_CALLBACK (panel4_expose_event), NULL);
            if (!show_timel)
                gkrellm_panel_hide(panel4);
        }
        
        kvbox = vbox;
}

static void create_plugin_tab(GtkWidget *tab_vbox)
{
	GtkWidget	*notebook;
	GtkWidget	*general_tab;
//	GtkWidget	*idle_tab;
	GtkWidget	*general_vbox;
//	GtkWidget	*sort_vbox;
//	GtkWidget	*idle_vbox;
//	GtkWidget	*color_hbox;
//	GtkWidget	*label;
//	GtkWidget	*choose_button;
//	GtkWidget	*info_tab;
//	GtkWidget	*info_text;
	GtkWidget	*about_tab;
	GtkWidget	*about_text;

//	gint		i;
	//char		str[MAX_STRING_LEN];

	notebook = gtk_notebook_new();
	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
	gtk_box_pack_start(GTK_BOX(tab_vbox), notebook, TRUE, TRUE, 0);

	/* -- General options tab -- */
	general_tab = gkrellm_gtk_framed_notebook_page(notebook, "General");
	general_vbox = gkrellm_gtk_framed_vbox(general_tab, "General options",
			4, FALSE, 0, 2);
	gkrellm_gtk_check_button(general_vbox, &voltage_button, show_linev,
			FALSE, 0, "Show Line Voltage");
	gkrellm_gtk_check_button(general_vbox, &time_left_button, show_timel,
			FALSE, 0, "Show Time Left");
	gkrellm_gtk_check_button(general_vbox, &charge_button, show_charge,
			FALSE, 0, "Show Battery Charge");
	gkrellm_gtk_check_button(general_vbox, &load_button, show_load,
			FALSE, 0, "Show Battery Load");

	statsloc_text = gtk_entry_new_with_max_length (100);
	gtk_entry_set_text (GTK_ENTRY(statsloc_text), statsloc);
	gtk_entry_set_editable (GTK_ENTRY(statsloc_text), TRUE);
		
	gtk_box_pack_end (GTK_BOX (general_vbox), statsloc_text, FALSE, FALSE, 0);
	
	/* -- Info tab */
/*	info_tab = gkrellm_gtk_framed_notebook_page(notebook, "Info");
	info_text = gkrellm_gtk_scrolled_text_view(info_tab, NULL,
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	for (i = 0; i < sizeof(plugin_info_text)/sizeof(gchar *); ++i)
		gkrellm_gtk_text_view_append(info_text, plugin_info_text[i]); *

	/* -- About tab */
	about_tab = gtk_label_new( "About" );
	about_text = gtk_label_new( "APCUPSD Status Monitor" );
	gtk_notebook_append_page( GTK_NOTEBOOK(notebook), about_text, about_tab );
}

static GkrellmMonitor	plugin_mon = {
	CONFIG_NAME,		/* Name, for config tab.    */
	0,			/* Id,  0 if a plugin       */
	create_plugin,		/* The create function      */
	update_plugin,		/* The update function      */
	create_plugin_tab, 	/* The config tab create function   */
	apply_plugin_config,/* Apply the config function        */

	save_plugin_config, /* Save user config   */
	load_plugin_config, /* Load user config   */
	NULL,			/* config keyword			*/

	NULL,			/* Undefined 2	*/
	NULL,			/* Undefined 1	*/
	NULL,			/* private		*/

	MON_MAIL,	/* Insert plugin before this monitor			*/

	NULL,			/* Handle if a plugin, filled in by GKrellM     */
	NULL			/* path if a plugin, filled in by GKrellM       */
};


GkrellmMonitor *
gkrellm_init_plugin() {
	style_id = gkrellm_add_meter_style(&plugin_mon, STYLE_NAME);
	monitor = &plugin_mon;
	return &plugin_mon;
}
