/*
  gkrellhotbabe.c

  author: Rocco Stanzione

  last update: Fri Aug 8 2003

  purpose: silly cpu monitor for gkrellm

  changelog:
  0.1 - initial version adapted from Henryk Richter's gkrellflynn

*/
#ifndef WIN32

/* see makefile */
#ifdef GKRELLM2
#include <gkrellm2/gkrellm.h>
#else  /* GKRELLM2 */
#include <gkrellm/gkrellm.h>
#endif /* GKRELLM2 */

#else /* WIN32 */

#include <src/gkrellm.h>
#include <src/win32-plugin.h>

#endif /* WIN32 */


#include <stdlib.h>

#define HOTBABE_MAJOR_VERSION 0
#define HOTBABE_MINOR_VERSION 1

#include "hotbabe.picture_alpha_big.xpm"
#define STYLE_NAME "hot-babe"

#define HEIGHT		89
#define IMAGE_WIDTH	48
#define IMAGE_HEIGHT	79
#define IMAGE_COUNT	5

#define F_LOOKSTATES	1
#define F_EXTRASTATE1   1
#define F_EXTRASTATE2   1
/* 5 torture variants per state */
#define F_TORTURES	5

#define GRIN_TIME	0.05

#if GKRELLM_VERSION_MAJOR < 2
static Panel		*panel;
static Decal		*hotbabe = NULL;
#else
static GkrellmPanel	*panel;
static GkrellmDecal	*hotbabe = NULL;
static GkrellmMonitor	*monitor;
#endif

static gint		style_id;
static GdkPixmap	*hotbabe_image = NULL;
static GdkBitmap 	*hotbabe_mask = NULL;
float              dogrin = 0;

/* config stuff */
#define PLUGIN_CONFIG_KEYWORD "Hot-BabeA"
static GtkWidget *nice_checkbutton;
static int nice_checkdisable = 0;

void hotbabe_apply_config(void)
{
	nice_checkdisable = GTK_TOGGLE_BUTTON(nice_checkbutton)->active;
}

static void hotbabe_save_config(FILE *f)
{
	fprintf(f, "%s exclude_nice %d\n", PLUGIN_CONFIG_KEYWORD,nice_checkdisable);
}

static void hotbabe_load_config (gchar *arg)
{
    gchar config[64], item[256];
    gint n;

    n = sscanf(arg, "%s %[^\n]", config, item);
    if (n != 2)
        return;

        if (strcmp(config, "exclude_nice") == 0 )
		sscanf(item, "%d\n", &nice_checkdisable);
}

/* get current cpu usage */
int getcpu( void )
{
	float scale_factor = 1;
#if 0
        FILE * fin;
        char buffer[256];
        char tokens[4] = " \t\n";
#endif

        static long last_user = 0;
        static long last_nice = 0;
        static long last_sys = 0;
        static long last_idle = 0;

        long user=0, nice=0, sys=0, idle=0, total=0;
        long d_user, d_nice, d_sys, d_idle;
        float cpu_use;
        float percent;

	gkrellm_cpu_stats(0, &user, &nice, &sys, &idle);

#if 0
        if ( (fin = fopen("/proc/stat", "r")) == NULL ) {
                return(0);
        }

        while ( fgets(buffer, 256, fin) ) {
                if ( strstr(buffer,"cpu") != NULL ) {
                        strtok(buffer,tokens);
                        user = atol(strtok(NULL,tokens));
                        nice = atol(strtok(NULL,tokens));
                        sys =  atol(strtok(NULL,tokens));
                        idle = atol(strtok(NULL,tokens));

			break;
                }
        }

        fclose (fin);
#endif

        d_user = user - last_user;
        d_nice = nice - last_nice;
        d_sys  = sys  - last_sys;
        d_idle = idle - last_idle;

        last_user = user;
        last_nice = nice;
        last_sys  = sys;
        last_idle = idle;

        total = d_user + d_sys + d_nice + d_idle;
	if( nice_checkdisable == 1 )
		d_idle += d_nice;

        if ( total < 1 )
                total = 1.0;

        cpu_use = 1.0 - ( (float)  d_idle  / (float) total );
#if 0 
        printf("   CPU (/proc/stat): %5.2f  ", cpu_use);
        printf(" (jiffies: user:%ld nice:%ld system:%ld idle:%ld total:%ld)\n",
                        d_user, d_nice, d_sys, d_idle, total  );
#endif
        percent = cpu_use / scale_factor;
        if ( percent > .999999 )
                percent = .999999;

        return ( (int)(percent*100) );
}


static void update_plugin()
{
        static int image_number = 0;
	static int hotbabe_look = 0;
	int dir;
	int percent;

#if GKRELLM_VERSION_MAJOR < 2
	if( GK.second_tick )
#else
	if( gkrellm_ticks()->second_tick )
#endif
	{
	   if( dogrin > 0 )
	   {
		dogrin=dogrin-0.01;
		hotbabe_look = F_EXTRASTATE2;
	   }
	   else
	   {
		dir = (int)( (float)F_LOOKSTATES * (float)rand() / (RAND_MAX+1.0));
		switch( dir )
		{
			case 0:
				break;
			case 1: 
				hotbabe_look++;
				break;
			case 2: 
				hotbabe_look--;
				break;
			default:
				break;
		}
		if( hotbabe_look < 0 ) hotbabe_look = 0;
		if( hotbabe_look >= F_LOOKSTATES ) hotbabe_look = F_LOOKSTATES-1;
	   }
		percent = getcpu();

		image_number = hotbabe_look * F_TORTURES + (F_TORTURES * percent / 100);

	}


	/* draw determined frame */
	gkrellm_draw_decal_pixmap(panel, hotbabe, image_number);
#if GKRELLM_VERSION_MAJOR < 2
	gkrellm_draw_layers(panel);
#else
	gkrellm_draw_panel_layers(panel);
#endif
}

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

static gint panel_click_event(GtkWidget *widget, GdkEventExpose *ev)
{
	dogrin = GRIN_TIME;

    return FALSE;
}

static void load_images()
{
#if GKRELLM_VERSION_MAJOR < 2
	static GdkImlibImage  *image = NULL;

	gkrellm_load_image(NULL, hb_all_xpm, &image, NULL);
	gkrellm_render_to_pixmap(image, &hotbabe_image, &hotbabe_mask, 0, 0);
#else
	static GkrellmPiximage *image = NULL;
	gkrellm_load_piximage(NULL, hb_all_xpm, &image, NULL);
	gkrellm_scale_piximage_to_pixmap(image, &hotbabe_image, &hotbabe_mask, 0, 0);
#endif
}

static void create_plugin(GtkWidget *vbox, gint first_create)
{
#if GKRELLM_VERSION_MAJOR < 2
	Style		*style = NULL;
#else
	GkrellmStyle	*style = NULL;
#endif

	int            image_x_offset;
	int            image_y_offset;

	load_images();

	if (first_create)
		panel = gkrellm_panel_new0();
	else
		gkrellm_destroy_decal_list(panel);

	style = gkrellm_meter_style(style_id);

	image_x_offset = (gkrellm_chart_width() - IMAGE_WIDTH) / 2;
	image_y_offset = (HEIGHT - IMAGE_HEIGHT) / 2;

	hotbabe = gkrellm_create_decal_pixmap(panel, hotbabe_image, hotbabe_mask,
	                                    IMAGE_COUNT,
	                                    style, image_x_offset, image_y_offset);

	panel->textstyle = gkrellm_meter_textstyle(style_id);
	panel->label->h_panel = HEIGHT;

#if GKRELLM_VERSION_MAJOR < 2
	gkrellm_create_panel(vbox, panel, gkrellm_bg_meter_image(style_id));
	gkrellm_monitor_height_adjust(panel->h);
#else
	gkrellm_panel_configure(panel, "", style);
	gkrellm_panel_create(vbox, monitor, panel);
#endif
	
	if (first_create)
	{
		gtk_signal_connect(GTK_OBJECT(panel->drawing_area),
		                   "expose_event", (GtkSignalFunc) panel_expose_event,
		                   NULL);
		gtk_signal_connect(GTK_OBJECT(panel->drawing_area),
		                   "button_press_event", (GtkSignalFunc) panel_click_event,
		                   NULL);
	}

	gkrellm_draw_decal_pixmap(panel, hotbabe, 1 );

#if GKRELLM_VERSION_MAJOR < 2
	gkrellm_draw_layers(panel);
#else
	gkrellm_draw_panel_layers(panel);	
#endif
	
	
	
}

static void hotbabe_create_plugin_tab(GtkWidget *tab_vbox)
{
	GtkWidget           *tabs;
	GtkWidget		*vbox,*vbox1;
        GtkWidget       *frame;

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

	/* Config */
	{
#if GKRELLM_VERSION_MAJOR < 2
	 vbox = gkrellm_create_tab(tabs, _("Config"));
#else
	 vbox = gkrellm_gtk_framed_notebook_page(tabs, _("Config"));
#endif

	 frame = gtk_frame_new(_("CPU time Calculations"));
         gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5);
         vbox1 = gtk_vbox_new (FALSE, 2);
         gtk_container_add(GTK_CONTAINER(frame), vbox1);
#if GKRELLM_VERSION_MAJOR < 2
         gkrellm_check_button(vbox1, &nice_checkbutton, nice_checkdisable, FALSE, 0,
                              "Exclude Nice time from calculations");
#else
	{
	 gchar *label = _("Exclude Nice time from calculations");
         gkrellm_gtk_check_button_connected(vbox1, &nice_checkbutton, nice_checkdisable, FALSE, 0,0,
		hotbabe_apply_config, 
		NULL, 
		label);
	}
#endif
	}

	/* ABOUT */
        {
            gchar *plugin_about_text;
            GtkWidget *label, *text;

            plugin_about_text = g_strdup_printf(
                "GKrellHotBabe %d.%d\n"
                "GKrellM Load Meter Plugin\n\n"
                "(C) 2003 Rocco Stanzione\n"
                "<grasshopper@linuxkungfu.org>\n\n"
                "Released under the GNU General Public License",
                HOTBABE_MAJOR_VERSION, HOTBABE_MINOR_VERSION);

            text = gtk_label_new(plugin_about_text);
            label = gtk_label_new("About");
            gtk_notebook_append_page(GTK_NOTEBOOK(tabs),text,label);
            g_free(plugin_about_text);
        }

}

#if GKRELLM_VERSION_MAJOR < 2
 static Monitor  plugin_mon  =
#else
 static GkrellmMonitor  plugin_mon  =
#endif
         {
         "HotBabe",                 /* Name, for config tab.        */
         0,                         /* Id,  0 if a plugin           */
         create_plugin,             /* The create_plugin() function */
         update_plugin,             /* The update_plugin() function */
         hotbabe_create_plugin_tab, /* The create_plugin_tab() config function */
         hotbabe_apply_config,      /* The apply_plugin_config() function      */

         hotbabe_save_config,       /* The save_plugin_config() function  */
         hotbabe_load_config,       /* The load_plugin_config() function  */
         PLUGIN_CONFIG_KEYWORD,                /* config keyword                     */

         NULL,           /* Undefined 2  */
         NULL,           /* Undefined 1  */
         NULL,           /* Undefined 0  */

         MON_INSERT_AFTER|MON_CLOCK, /* Insert plugin before this monitor.       */
         NULL,           /* Handle if a plugin, filled in by GKrellM */
         NULL            /* path if a plugin, filled in by GKrellM   */
         };

#if GKRELLM_VERSION_MAJOR < 2
Monitor * init_plugin(void)
#else
#ifdef WIN32
__declspec(dllexport) GkrellmMonitor *
gkrellm_init_plugin(win32_plugin_callbacks* calls)
#else
GkrellmMonitor *
gkrellm_init_plugin()
#endif
#endif
{
#if GKRELLM_VERSION_MAJOR < 2
	style_id = gkrellm_add_meter_style(&plugin_mon, STYLE_NAME);
#else
#if defined(WIN32)
	callbacks = calls;
	pwin32GK = calls->GK;
#endif
	style_id = gkrellm_add_meter_style(&plugin_mon, STYLE_NAME);
	monitor = &plugin_mon;
#endif 
	return &plugin_mon;
}

