/* --------------------------------------------------------------- *\

  file  : gkrellmimonc.c 
  author: m. gumz 
  mail  : gumz at cs.uni-magdeburg.de
  copyr : copyright (c) 2003 by m. gumz

  start : Mon 12 Mai 2003 07:35:16 CEST

  $Id: gkrellimonc.c,v 1.10 2003/05/17 18:07:56 bz-akira Exp $

\* --------------------------------------------------------------- */
/* --------------------------------------------------------------- *\
  
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public Licensse 
  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.

\* --------------------------------------------------------------- */
/* --------------------------------------------------------------- *\

  about : gkrellm-imonc plugin to monitor a fli4l-router

\* --------------------------------------------------------------- */

/* --------------------------------------------------------------- *\
    includes   
\* --------------------------------------------------------------- */

#if !defined(WIN32)
#include <gkrellm2/gkrellm.h>
#else
#include <src/gkrellm.h>
#include <src/win32-plugin.h>
#endif

//TODO fix execl for win32
#include <unistd.h>


#include "imonc.h"
#include "pixmaps.h"

/* --------------------------------------------------------------- *\
\* --------------------------------------------------------------- */

#define CONFIG_NAME             "gkrellm-imonc"
#define MONITOR_CONFIG_KEYWORD  "imonc"
#define IMONC_STYLE_NAME        "imonc"

#define	MIN_GRID_RES    2
#define	MAX_GRID_RES    50

#define LED_FRAMES 4

/* --------------------------------------------------------------- *\
    some typedefs 
\* --------------------------------------------------------------- */
enum
{
  SHOW_NONE=        0,
  SHOW_UPRATE=      1,
  SHOW_DOWNRATE=    2,
  SHOW_HOST=        4,
  SHOW_UPTIME=      8,
  SHOW_CHANNELTIME= 16,
  SHOW_ONLINETIME=  32,
  SHOW_CONTYPE=     64,

  SHOW_UPDOWN=    SHOW_UPRATE|SHOW_DOWNRATE,
  SHOW_HUD= SHOW_HOST|SHOW_UPDOWN,
  SHOW_UUD= SHOW_UPTIME|SHOW_UPDOWN,
  SHOW_CTUD= SHOW_CHANNELTIME|SHOW_UPDOWN,
  SHOW_OUD= SHOW_ONLINETIME|SHOW_UPDOWN,
  SHOW_ALL= SHOW_HOST|SHOW_UPDOWN|SHOW_CONTYPE,
};

typedef enum 
{
  FLI_ISDN= 1,
  FLI_PPPOE
} fliConType;

typedef struct 
{
  // informations
  char*         host;
  unsigned int  port;
  char*         pass;
  char*         adminpass;
  
  fliConType    contype;
  unsigned int  channel;
  unsigned int  circuit;

  char*         launch_command;

  // mostly internal, technical stuff
  int           fd;

  int           cpu_rate;
  int           up_rate;
  int           down_rate;
  int           uptime;
  int           channelstatus;

} fliChunk;

typedef struct
{
  GtkWidget *notebook;

  GtkWidget *option_frame;
  GtkWidget *option_pane;

  GtkWidget *leftlabel_frame;
  GtkWidget *host_label;
  GtkWidget *port_label;
  GtkWidget *pass_label;
  GtkWidget *adminpass_label;
  GtkWidget *launch_label;
  GtkWidget *contype_label;

  GtkWidget *rightentry_frame;
  GtkWidget *host_entry;
  GtkWidget *port_entry;
  GtkWidget *pass_entry;
  GtkWidget *adminpass_entry;
  GtkWidget *launch_entry;
  GtkWidget *contype_combo;
  GList     *contype_items;
  GtkWidget *contype_entry;

  GtkWidget *info_frame;
  GtkWidget *info_text;

  GtkWidget *about_frame;
  GtkWidget *about_text;

} guiChunk;

typedef struct
{
  GtkWidget*           vbox;
  GkrellmMonitor      *mon;
  GkrellmChart        *chart;
  GkrellmChartdata    *plugin_cd;
  GkrellmChartdata    *plugin_cd2;
  GkrellmChartconfig  *chart_config;

  GkrellmKrell        *cpukrell;
  GkrellmDecal        *online_led;
  GkrellmDecal        *connect_led;

  GkrellmPiximage     *led_piximage;
  GdkPixmap	          *led_pixmap;
  GdkBitmap	          *led_mask;

  GkrellmTicks        *pGK;
  
  int	                plugin_enable;
  int                 plugin_style_id;

} gkrChunk;

/* --------------------------------------------------------------- *\
   prototypes    
\* --------------------------------------------------------------- */
static void gkrellm_imonc_save_config(FILE* f);
static void gkrellm_imonc_load_config(char* config_line);
static void gkrellm_imonc_apply_config(void);

static void gkrellm_imonc_update(void);
static void gkrellm_imonc_create(GtkWidget* vbox, int first_create);
static void gkrellm_imonc_create_optiontab(GtkWidget* main_widget);

static void gkrellm_imonc_load_extra_piximages(void);

static void gkrellm_imonc_draw_chart(void);

static int  gkrellm_imonc_chart_expose_event(GtkWidget* widget, GdkEventExpose* ev);
static void gkrellm_imonc_chart_click(GtkWidget* widget, GdkEventButton* event, gpointer data);
static int  gkrellm_imonc_panel_expose_event(GtkWidget* widget, GdkEventExpose* ev);
static void gkrellm_imonc_panel_click(GtkWidget* widget, GdkEventButton* event, gpointer data);


static void gkrellm_imonc_online_led_clickaction(GdkEventButton* ev);
static void gkrellm_imonc_connect_led_clickaction(GdkEventButton* ev);

/* --------------------------------------------------------------- *\
   globals 
\* --------------------------------------------------------------- */

static fliChunk     router;
static guiChunk     gui;
static gkrChunk     gkr;


static unsigned int show_state= SHOW_UPDOWN;

static char*        gkrellm_imonc_info_text[]=
{
  "<h>Setup Notes\n",
  "<h>Launch Command:\n",
  "Middle MouseClick on the Chart (and not the leds) will launch\n",
  "an external app, if one wants to.\n",
  "\n",
  "There are some variables one could use:\n",
  "\t%h - Hostname\n",
  "\t%p - Portnumber\n",
  "\t%P - Userpassword\n",
  "\n",
  "Example:\n",
  "\tgtk-imonc %h %p -> 'gtk-imonc fli4l 5000'\n",
  ""
};

static char*        gkrellm_imonc_about_text[]=
{
  "<h>Authors:\n",
  "\tcode, webpage and (c)opyrights \n",
  "\tall by m.gumz (aka akira aka bz-akira) 2003\n\n",
  "\tVersion: 0.2 \n",
  "\tCompiled: "__DATE__"\n",
  ""
};



/* --------------------------------------------------------------- *\
    plugin
\* --------------------------------------------------------------- */


static void gkrellm_imonc_online_led_clickaction(GdkEventButton* ev)
{
  switch ( ev->button )
  {

    case 1:
      break;

    case 2:
      {
        if ( router.fd > 0 )
        {
          int channel= router.contype == FLI_PPPOE ? -1 : router.channel;
          if ( imonc_is_admin_mode(router.fd) || imonc_admin_auth(router.fd, router.adminpass) )
          {
            if ( !imonc_get_channel_status(router.fd, channel) )
            {
              imonc_dial_channel(router.fd, channel);
            }
            else
            {
              imonc_hangup_channel(router.fd, channel);
            }
          }
          else
          {
            //TODO popup with error message
          }
        }
      }
      break;

    case 3:
      break;

  }; 

  return;
};

static void gkrellm_imonc_connect_led_clickaction(GdkEventButton* ev)
{
  switch ( ev->button )
  {

    case 1:
      break;

    case 2:
      {
        if ( router.fd == 0 && router.host && router.port > 0)
        {
          router.fd= service_connect(router.host, router.port);

          if ( router.fd > 0 )
          {
            if ( imonc_user_auth(router.fd, router.pass) )
            {

               if (imonc_is_pppoe_enabled(router.fd))
                 router.contype= FLI_PPPOE;
               else
                 router.contype= FLI_ISDN;
                
            }
            else
            {
              printf("wrong pass\n");
              service_disconnect(router.fd);
              router.fd= 0;
            }
          }
          else
          {
            printf("couldnt connect to %s:%d\n", router.host, router.port);
          }
        }
        else
        {
          service_disconnect(router.fd);
          router.fd= 0;
        }
        
      }
      break;

    case 3:
      break;

  }; 
  return;
};


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

static int gkrellm_imonc_panel_expose_event(GtkWidget* widget, GdkEventExpose* ev)
{
  GdkPixmap		*pixmap= gkr.chart->panel->pixmap;
  if (pixmap)
  {
    gdk_draw_drawable(widget->window, gkrellm_draw_GC(1), pixmap,
      ev->area.x, ev->area.y, ev->area.x, ev->area.y,
      ev->area.width, ev->area.height);
  }
	return FALSE;
}

static void gkrellm_imonc_chart_click(GtkWidget* widget, GdkEventButton* event, gpointer data)
{

  // online_led handling
  if ( event->x >= gkr.online_led->x && 
       event->x < gkr.online_led->x+gkr.online_led->w &&
       event->y >= gkr.online_led->y && 
       event->y < gkr.online_led->y+gkr.online_led->h )
  {
    gkrellm_imonc_online_led_clickaction(event);
    return;
  }

  // connect led handling
  else if ( event->x >= gkr.connect_led->x && 
       event->x < gkr.connect_led->x+gkr.connect_led->w &&
       event->y >= gkr.connect_led->y && 
       event->y < gkr.connect_led->y+gkr.connect_led->h )
  {
    gkrellm_imonc_connect_led_clickaction(event);
    return;
  }

  else
  {
    
    switch ( event->button )
    {
      case 1:
        {
          switch (show_state)
          {
            case SHOW_NONE:
              show_state= SHOW_UPDOWN;
              break;

            case SHOW_UPDOWN:
              show_state= SHOW_HOST;
              break;

            case SHOW_HOST:
              show_state= SHOW_CHANNELTIME;
              break;

            case SHOW_CHANNELTIME:
              show_state= SHOW_ONLINETIME;
              break;

            case SHOW_ONLINETIME:
              show_state= SHOW_UPTIME;
              break;

            case SHOW_UPTIME:
              show_state= SHOW_HUD;
              break;

            case SHOW_HUD:
              show_state= SHOW_OUD;
              break;

            case SHOW_OUD:
              show_state= SHOW_CTUD;
              break;

            case SHOW_CTUD:
              show_state= SHOW_UUD;
              break;
              
            case SHOW_UUD:
              show_state= SHOW_NONE;
              break;

            default:
              show_state=SHOW_NONE;
              break;
          };
            
        }
        break;


      // middle mouse launches command
      case 2:
        {
          static char buf[256];
          int i, j, s;

          memset(buf, 0, 256);

          for ( s= strlen(router.launch_command), i= 0, j= 0; 
                i < s && j < 256; 
                i++ )
          {
            if ( router.launch_command[i] == '%' && i < s )
            {
              switch ( router.launch_command[i+1] )
              {
                case 'p':
                  printf("port");
                  {
                    static char p[6];
                    sprintf(p, "%d", router.port);
                    strcat(buf, p);
                  }
                  j= strlen(buf);
                  i++; 
                  break;

                case 'P':
                  printf("pass");
                  if ( router.pass && strlen(router.pass) > 0 )
                  {
                    strcat(buf, router.pass);
                    j= strlen(buf);
                  }
                  i++;
                  break;

                case 'h':
                  printf("host");
                  strcat(buf, router.host);
                  j= strlen(buf);
                  i++;
                  break;

              }; // switch
            }
            else
              buf[j++]= router.launch_command[i];
          }

          if ( strlen(buf) > 0 )
          {
            if ( !fork() )
            {
              execl("/bin/sh", "/bin/sh", "-c", buf, 0);
              exit(0); //exit child
            }
          }
        }

        break;
        

      case 3:
        gkrellm_chartconfig_window_create(gkr.chart);
        break;

    }; // switch

  }

  return;
}
static void gkrellm_imonc_panel_click(GtkWidget* widget, GdkEventButton* event, gpointer data)
{
  return;
}


static void gkrellm_imonc_draw_chart(void)
{
  static char buf[64]={ "\\f\\n\\n\\c" };
  
  if ( show_state & SHOW_HOST )
  {
    sprintf(&buf[8], "%s", router.host);
    gkrellm_draw_chart_text(gkr.chart, gkr.plugin_style_id, buf);
  }
  else if ( router.fd > 0 && show_state & SHOW_UPTIME )
  {
    imonchelp_get_uptime_string(router.uptime, &buf[8]);
    gkrellm_draw_chart_text(gkr.chart, gkr.plugin_style_id, buf);
  }
  else if ( router.fd > 0 && show_state & SHOW_CHANNELTIME )
  {
    static int channel;
    channel= ( router.contype == FLI_PPPOE ) ? -1 : router.channel;
    imonc_get_channel_time(router.fd, channel, &buf[8]);
    gkrellm_draw_chart_text(gkr.chart, gkr.plugin_style_id, buf);
  }
  else if ( router.fd > 0 && show_state & SHOW_ONLINETIME )
  {
    static int channel;
    channel= ( router.contype == FLI_PPPOE ) ? -1 : router.channel;
    imonc_get_channel_onlinetime(router.fd, channel, &buf[8]);
    gkrellm_draw_chart_text(gkr.chart, gkr.plugin_style_id, buf);
  }

  
  gkrellm_draw_chart_to_screen(gkr.chart);
  return;
}


static void gkrellm_imonc_update(void)
{
	if (gkr.pGK && gkr.pGK->second_tick)
	{
    static char buf[64];
    static char buf2[64];
        
    if ( router.fd > 0 )
    {
		  /* Make up some data to store on the chart.
		  */

    
      imonc_get_channel_rate(router.fd, 
          ( router.contype == FLI_PPPOE ? -1 : router.channel ), 
          &router.down_rate, 
          &router.up_rate);
      
      gkrellm_store_chartdata(gkr.chart, 0, router.down_rate, router.up_rate);
		  gkrellm_draw_chartdata(gkr.chart);

      //TODO right justify .. etc
      if ( show_state & SHOW_DOWNRATE )
      {
        sprintf(buf2, "%s", imonchelp_get_bytes_string(router.down_rate,buf));
		    gkrellm_draw_chart_label(gkr.chart, 
            gkrellm_chart_textstyle(gkr.plugin_style_id), gkr.chart->x+gkr.chart->w - 20, 8, buf2);
        memset(buf2, 0, 64);
      }
      
      if ( show_state & SHOW_UPRATE )
      {
        sprintf(buf2, "%s", imonchelp_get_bytes_string(router.up_rate, buf));
        gkrellm_draw_chart_label(gkr.chart, 
            gkrellm_chart_textstyle(gkr.plugin_style_id), gkr.chart->x+gkr.chart->w - 20, 34, buf2);
        memset(buf2, 0, 64);
      }
	    if ( show_state & SHOW_CONTYPE )
      {
        gkrellm_draw_chart_label(gkr.chart, 
            gkrellm_chart_textstyle(gkr.plugin_style_id), gkr.chart->x+gkr.chart->w - 20, 18, (( router.contype == FLI_PPPOE ) ? "pppoe" : "isdn"));
      }

      router.cpu_rate=        imonc_get_cpuload(router.fd);
      router.uptime=          imonc_get_uptime(router.fd);
      router.channelstatus=   imonc_get_channel_status(router.fd, ( router.contype == FLI_PPPOE ? -1 : router.channel ));

    }
    else
    {
      router.down_rate= 0;
      router.up_rate= 0;
      router.cpu_rate= 0;
      router.uptime= 0;
      router.channelstatus= 0;
    }
    
		/* If you don't have a separate draw chart function, then put
		|  here gkrellm_draw_chartdata() and gkrellm_draw_chart_to_screen().
		*/

    gkrellm_update_krell(gkr.chart->panel, gkr.cpukrell, (gulong)router.cpu_rate);
		gkrellm_draw_panel_layers(gkr.chart->panel);
    gkrellm_draw_decal_pixmap(NULL, gkr.online_led, router.channelstatus);
    gkrellm_draw_decal_on_chart(gkr.chart, gkr.online_led, gkr.chart->x+2, gkr.chart->y+2);
    gkrellm_draw_decal_pixmap(NULL, gkr.connect_led, ( router.fd > 0 ? 1 : 0) );
    gkrellm_draw_decal_on_chart(gkr.chart, gkr.connect_led, gkr.chart->x+2, gkr.chart->y + gkr.chart->h - gkr.connect_led->h - 2);

		gkrellm_imonc_draw_chart();
  }

  return;
}

static void gkrellm_imonc_create(GtkWidget* vbox, int first_create)
{

	GkrellmStyle	*style;
  GkrellmChart	*cp;
	GkrellmPanel	*p;


  gkrellm_imonc_load_extra_piximages();
  
	if (first_create) 
  {
	    
/* --------------------------------------------------------------- *\
     check connection     
\* --------------------------------------------------------------- */
    if ( router.host && router.port > 0 )
    {
      router.fd= service_connect(router.host, router.port);

      if ( router.fd > 0 )
      {
        if ( imonc_user_auth(router.fd, router.pass) )
        {

           if (imonc_is_pppoe_enabled(router.fd))
             router.contype= FLI_PPPOE;
           else
             router.contype= FLI_ISDN;
            
        }
        else
        {
          printf("wrong pass\n");
          service_disconnect(router.fd);
          router.fd= 0;
        }
      }
      else
      {
        printf("couldnt connect to %s:%d\n", router.host, router.port);
      }
    }
    
    gkr.vbox= gtk_vbox_new(FALSE, 0);
		gtk_container_add(GTK_CONTAINER(vbox),gkr.vbox);
		gtk_widget_show(gkr.vbox);

    gkr.chart= gkrellm_chart_new0();
    gkr.chart->panel= gkrellm_panel_new0();
  }

  cp= gkr.chart;
  p= gkr.chart->panel;
  style= gkrellm_panel_style(gkr.plugin_style_id);
  
  // cpu load meter
  gkr.cpukrell= gkrellm_create_krell(p,
				gkrellm_krell_panel_piximage(gkr.plugin_style_id), 
        style);
  
	gkrellm_monotonic_krell_values(gkr.cpukrell, FALSE);
	gkrellm_set_krell_full_scale(gkr.cpukrell, 100, 1);
  gkrellm_update_krell(p, gkr.cpukrell, (gulong)0);


  // the chart
	gkrellm_set_chart_height_default(cp, 40);
	gkrellm_chart_create(gkr.vbox, gkr.mon, cp, &gkr.chart_config);
	
  gkr.plugin_cd=  gkrellm_add_default_chartdata(cp, "Download Rate");
	gkr.plugin_cd2= gkrellm_add_default_chartdata(cp, "Upload Rate");

	gkrellm_monotonic_chartdata(gkr.plugin_cd, FALSE);
	gkrellm_monotonic_chartdata(gkr.plugin_cd2, FALSE);
	
  gkrellm_set_chartdata_draw_style_default(gkr.plugin_cd, CHARTDATA_LINE);
	gkrellm_set_chartdata_flags(gkr.plugin_cd, CHARTDATA_ALLOW_HIDE);
	gkrellm_set_chartdata_draw_style_default(gkr.plugin_cd2, CHARTDATA_LINE);
	gkrellm_set_chartdata_flags(gkr.plugin_cd2, CHARTDATA_ALLOW_HIDE);

	gkrellm_set_draw_chart_function(cp, gkrellm_imonc_draw_chart, NULL); 

  // leds
  if ( gkr.online_led )
    gkrellm_destroy_decal(gkr.online_led);
  
   gkr.online_led= gkrellm_create_decal_pixmap(
      NULL, gkr.led_pixmap, gkr.led_mask, LED_FRAMES, style, 0, 0);
  
   if ( gkr.connect_led )
     gkrellm_destroy_decal(gkr.connect_led);
  
   gkr.connect_led= gkrellm_create_decal_pixmap(
      NULL, gkr.led_pixmap, gkr.led_mask, LED_FRAMES, style, 0, 0);

  
  gkrellm_panel_configure(p, NULL, style);
	gkrellm_panel_create(gkr.vbox, gkr.mon, p);
	
  gkrellm_alloc_chartdata(cp);


	if (first_create)
  {
		g_signal_connect(G_OBJECT(cp->drawing_area),
				"expose_event", G_CALLBACK(gkrellm_imonc_chart_expose_event), NULL);
    g_signal_connect(G_OBJECT(p->drawing_area),
				"expose_event", G_CALLBACK(gkrellm_imonc_panel_expose_event), NULL);

		g_signal_connect(G_OBJECT(cp->drawing_area),
				"button_press_event", G_CALLBACK(gkrellm_imonc_chart_click), NULL);
    g_signal_connect(G_OBJECT(p->drawing_area),
				"button_press_event", G_CALLBACK(gkrellm_imonc_panel_click), NULL);

  }
	else
  {
		gkrellm_imonc_draw_chart();
  }


  return;
}



  /* Save any configuration data we have in config lines in the format:
  |  MONITOR_CONFIG_KEYWORD  config_keyword  data
  */
static void gkrellm_imonc_save_config(FILE* f)
{
	fprintf(f, "%s enable %d\n", MONITOR_CONFIG_KEYWORD, gkr.plugin_enable);

  if ( router.host )
    fprintf(f, "%s host %s\n", MONITOR_CONFIG_KEYWORD, router.host);
  
  fprintf(f, "%s port %d\n", MONITOR_CONFIG_KEYWORD, router.port);
  
  if ( router.pass )
    fprintf(f, "%s pass %s\n", MONITOR_CONFIG_KEYWORD, router.pass);
  if ( router.adminpass )
    fprintf(f, "%s adminpass %s\n", MONITOR_CONFIG_KEYWORD, router.adminpass);

  if ( router.launch_command )
    fprintf(f, "%s launch_command %s\n", MONITOR_CONFIG_KEYWORD, router.launch_command);
  
  fprintf(f, "%s circuit %d\n", MONITOR_CONFIG_KEYWORD, router.circuit);
  fprintf(f, "%s channel %d\n", MONITOR_CONFIG_KEYWORD, router.channel);
  fprintf(f, "%s showstate %d\n", MONITOR_CONFIG_KEYWORD, show_state);

	/* Save any chart config changes the user has made.
	*/
	gkrellm_save_chartconfig(f, gkr.chart_config, MONITOR_CONFIG_KEYWORD, NULL);

  return;
}

  /* When GKrellM is started up, load_plugin_config() is called if any
  |  config lines for this plugin are found.  The lines must have been
  |  saved by save_plugin_config().  gkrellm_load_chartconfig() must
  |  have the address of a ChartConfig struct pointer.  At this point, the
  |  pointer is almost always NULL and the function will allocate a
  |  ChartConfig struct and update the pointer.  The struct will be
  |  initialized with values from the config line.
  */
static void gkrellm_imonc_load_config(char* config_line)
{
	static char config_keyword[32];
  static char config_data[CFG_BUFSIZE];
	static int	n;

	if ((n = sscanf(config_line, "%31s %[^\n]",
				config_keyword, config_data)) != 2)
		return;
  
	if (!strcmp(config_keyword, "enable"))
		sscanf(config_data, "%d", &gkr.plugin_enable);
  else if (!strcmp(config_keyword, "host"))
  {
    static char buf[64];
    sscanf(config_data, "%s", buf);
    router.host= g_strdup(buf);
  }
  else if (!strcmp(config_keyword, "port"))
    sscanf(config_data, "%d", &router.port);
  else if (!strcmp(config_keyword, "pass"))
  {
    static char buf[64];
    sscanf(config_data, "%s", buf);
    if ( strlen(buf) )
      router.pass= g_strdup(buf);

  }
  else if (!strcmp(config_keyword, "launch_command"))
  {
    if ( router.launch_command )
      g_free(router.launch_command);
    router.launch_command= g_strdup(config_data);
  }
  else if (!strcmp(config_keyword, "adminpass"))
  { 
    static char buf[64];
    sscanf(config_data, "%s", buf);
    router.adminpass= g_strdup(buf);
  }
  else if (!strcmp(config_keyword, "circuit"))
    sscanf(config_data, "%d", &router.circuit);
  else if (!strcmp(config_keyword, "channel"))
    sscanf(config_data, "%d", &router.channel);
  else if (!strcmp(config_keyword, "showstate"))
    sscanf(config_data, "%d", &show_state);
	else if (!strcmp(config_keyword, "chart_config"))
		gkrellm_load_chartconfig(&gkr.chart_config, config_data, 2);

  return;
}

static void gkrellm_imonc_load_extra_piximages(void)
{
	int			  w, h;

	/* Check for theme_dir/net/decal_net_leds.png. */
	gkrellm_load_piximage("decal_net_leds", decal_net_leds_xpm,
			&gkr.led_piximage,  "net");

	w = gdk_pixbuf_get_width(gkr.led_piximage->pixbuf);
	w *= gkrellm_get_theme_scale();

	h = gdk_pixbuf_get_height(gkr.led_piximage->pixbuf);
	h *= gkrellm_get_theme_scale();

	gkrellm_scale_piximage_to_pixmap(gkr.led_piximage,
				&gkr.led_pixmap, 
        &gkr.led_mask, 
        w, h );
  
  return;
}


/* --------------------------------------------------------------- *\
     gui 
\* --------------------------------------------------------------- */


static void gkrellm_imonc_apply_config(void)
{
  {
    const char*   host=     gtk_entry_get_text(GTK_ENTRY(gui.host_entry));
    const char*   pass=     gtk_entry_get_text(GTK_ENTRY(gui.pass_entry));
    const char*   adminpass=gtk_entry_get_text(GTK_ENTRY(gui.adminpass_entry));
    int           port=     atoi(gtk_entry_get_text(GTK_ENTRY(gui.port_entry)));
    int           fd= 0;
    
    if ( host && port > 0 )
    {
      fd= service_connect((char*)host,port);
      if ( fd > 0 )
      {
        if ( imonc_user_auth(fd, pass) )
        {
          if ( fd != router.fd )
            service_disconnect(router.fd);
          
          g_free(router.pass);
          g_free(router.host);
          g_free(router.adminpass);
          router.pass= g_strdup(pass);
          router.adminpass= g_strdup(adminpass);
          router.host= g_strdup(host);
          router.port= port;
          router.fd= fd;

          router.contype= ( imonc_is_pppoe_enabled(fd) ) ? FLI_PPPOE : FLI_PPPOE;

          printf("gkrellm-imonc: apply_config -> ok\n");
        }
        else
        {
          service_disconnect(fd);
          printf("gkrellm-imonc: apply_config -> wrong pass\n");
        }
         
      }
      else
      {
        printf("gkrellm-imonc: apply_config -> couldnt connect to host %s:%d.\n", host,port);
      }
    }
    else
    {
      printf("gkrellm-imonc: apply_config -> no host and / or port set.\n");
    }
  }
  
  // check launch - command
  {
    const char* launch_command= gtk_entry_get_text(GTK_ENTRY(gui.launch_entry));

    g_free(router.launch_command);
    router.launch_command= g_strdup(launch_command);
  }

  return;
}

static void gkrellm_imonc_create_optiontab(GtkWidget* main_widget)
{
  static char buf[64];
  static int  i;
  memset(buf,0,64);

/* --------------------------------------------------------------- *\
    gui for options 
\* --------------------------------------------------------------- */
  
  gui.notebook = gtk_notebook_new ();
  gtk_widget_show (gui.notebook);
  gtk_container_add (GTK_CONTAINER (main_widget), gui.notebook);

  gui.option_frame = gkrellm_gtk_framed_notebook_page(gui.notebook, _("Options"));
  
  gui.option_pane = gtk_hpaned_new ();
  gtk_widget_show (gui.option_pane);
  gtk_container_add (GTK_CONTAINER (gui.option_frame), gui.option_pane);
  gtk_container_set_border_width (GTK_CONTAINER (gui.option_pane), 2);
  gtk_paned_set_position (GTK_PANED (gui.option_pane), 70);

/* --------------------------------------------------------------- *\
    option frame 
\* --------------------------------------------------------------- */

  gui.leftlabel_frame = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (gui.leftlabel_frame);
  gtk_paned_pack1 (GTK_PANED (gui.option_pane), gui.leftlabel_frame, FALSE, TRUE);

  gui.host_label = gtk_label_new (_("host"));
  gtk_widget_show (gui.host_label);
  gtk_box_pack_start (GTK_BOX (gui.leftlabel_frame), gui.host_label, TRUE, TRUE, 0);
  gtk_label_set_justify (GTK_LABEL (gui.host_label), GTK_JUSTIFY_RIGHT);

  gui.port_label = gtk_label_new (_("port"));
  gtk_widget_show (gui.port_label);
  gtk_box_pack_start (GTK_BOX (gui.leftlabel_frame), gui.port_label, TRUE, TRUE, 0);
  gtk_label_set_justify (GTK_LABEL (gui.port_label), GTK_JUSTIFY_RIGHT);

  gui.pass_label = gtk_label_new (_("pass"));
  gtk_widget_show (gui.pass_label);
  gtk_box_pack_start (GTK_BOX (gui.leftlabel_frame), gui.pass_label, TRUE, TRUE, 0);
  gtk_label_set_justify (GTK_LABEL (gui.pass_label), GTK_JUSTIFY_RIGHT);
  
  gui.adminpass_label = gtk_label_new (_("adminpass"));
  gtk_widget_show (gui.adminpass_label);
  gtk_box_pack_start (GTK_BOX (gui.leftlabel_frame), gui.adminpass_label, TRUE, TRUE, 0);
  gtk_label_set_justify (GTK_LABEL (gui.adminpass_label), GTK_JUSTIFY_RIGHT);

  /*
  gui.contype_label = gtk_label_new (_("contype"));
  gtk_widget_show (gui.contype_label);
  gtk_box_pack_start (GTK_BOX (gui.leftlabel_frame), gui.contype_label, TRUE, TRUE, 0);
  gtk_label_set_justify (GTK_LABEL (gui.contype_label), GTK_JUSTIFY_RIGHT);
*/

  gui.launch_label= gtk_label_new(_("lauch_command"));
  gtk_widget_show(gui.launch_label);
  gtk_box_pack_start(GTK_BOX (gui.leftlabel_frame), gui.launch_label, TRUE, TRUE, 0);
  
  gui.rightentry_frame = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (gui.rightentry_frame);
  gtk_paned_pack2 (GTK_PANED (gui.option_pane), gui.rightentry_frame, TRUE, TRUE);

  gui.host_entry = gtk_entry_new ();
  gtk_widget_show (gui.host_entry);
  gtk_box_pack_start (GTK_BOX (gui.rightentry_frame), gui.host_entry, TRUE, TRUE, 0);
  gtk_entry_set_text (GTK_ENTRY (gui.host_entry), _(router.host));

  gui.port_entry = gtk_entry_new ();
  gtk_widget_show (gui.port_entry);
  gtk_box_pack_start (GTK_BOX (gui.rightentry_frame), gui.port_entry, TRUE, TRUE, 0);
  sprintf(buf, "%d", router.port);
  gtk_entry_set_text (GTK_ENTRY (gui.port_entry), buf);

  gui.pass_entry = gtk_entry_new ();
  gtk_widget_show (gui.pass_entry);
  gtk_box_pack_start (GTK_BOX (gui.rightentry_frame), gui.pass_entry, TRUE, TRUE, 0);
  gtk_entry_set_visibility (GTK_ENTRY (gui.pass_entry), FALSE);
  if ( router.pass )
    gtk_entry_set_text (GTK_ENTRY (gui.pass_entry), router.pass);

  gui.adminpass_entry = gtk_entry_new ();
  gtk_widget_show (gui.adminpass_entry);
  gtk_box_pack_start (GTK_BOX (gui.rightentry_frame), gui.adminpass_entry, TRUE, TRUE, 0);
  gtk_entry_set_visibility (GTK_ENTRY (gui.adminpass_entry), FALSE);
  if ( router.adminpass )
    gtk_entry_set_text (GTK_ENTRY (gui.adminpass_entry), router.adminpass);

  /* connection type .. disabled for the moment */
  /*
  gui.contype_combo = gtk_combo_new ();
  g_object_set_data (G_OBJECT (GTK_COMBO (gui.contype_combo)->popwin),
                     "GladeParentKey", gui.contype_combo);
  gtk_widget_show (gui.contype_combo);
  gtk_container_add (GTK_CONTAINER (gui.rightentry_frame), gui.contype_combo);
  gtk_combo_set_value_in_list (GTK_COMBO (gui.contype_combo), TRUE, TRUE);
  gui.contype_items = g_list_append (gui.contype_items, (gpointer) _("pppoe"));
  gui.contype_items = g_list_append (gui.contype_items, (gpointer) _("isdn"));
  gtk_combo_set_popdown_strings (GTK_COMBO (gui.contype_combo), gui.contype_items);
  g_list_free (gui.contype_items);
  gui.contype_items= NULL;

  gui.contype_entry = GTK_COMBO (gui.contype_combo)->entry;
  gtk_widget_show (gui.contype_combo);
  switch( router.contype )
  {
    case FLI_PPPOE:
      gtk_entry_set_text (GTK_ENTRY (gui.contype_entry), _("pppoe"));
      break;

    case FLI_ISDN:
      gtk_entry_set_text(GTK_ENTRY(gui.contype_entry), _("isdn"));
      break;
  };

  */
  
  gui.launch_entry = gtk_entry_new ();
  gtk_widget_show (gui.launch_entry);
  gtk_box_pack_start (GTK_BOX (gui.rightentry_frame), gui.launch_entry, TRUE, TRUE, 0);
  gtk_entry_set_text(GTK_ENTRY (gui.launch_entry), router.launch_command);
  
/* --------------------------------------------------------------- *\
    info box    
\* --------------------------------------------------------------- */
  gui.info_frame = gkrellm_gtk_framed_notebook_page(gui.notebook, _("Info"));
  gui.info_text = gkrellm_gtk_scrolled_text_view(gui.info_frame, NULL,
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_widget_show(gui.info_text);
	for (i = 0; i < sizeof(gkrellm_imonc_info_text)/sizeof(char*); ++i)
		gkrellm_gtk_text_view_append(gui.info_text, gkrellm_imonc_info_text[i]);

/* --------------------------------------------------------------- *\
    about box 
\* --------------------------------------------------------------- */
  gui.about_frame = gkrellm_gtk_framed_notebook_page(gui.notebook, _("About"));
  gui.about_text = gkrellm_gtk_scrolled_text_view(gui.about_frame, NULL,
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_widget_show(gui.about_text);
	for (i = 0; 
      i < sizeof(gkrellm_imonc_about_text)/sizeof(char*); ++i)
		gkrellm_gtk_text_view_append(gui.about_text, gkrellm_imonc_about_text[i]);

  return;
}

static GkrellmMonitor  gkrellm_imonc_monitor=
{
	CONFIG_NAME,                    /* Name, for config tab.        */
	0,                              /* Id,  0 if a plugin           */
	gkrellm_imonc_create,           /* The create_plugin() function */
	gkrellm_imonc_update,           /* The update_plugin() function */
	gkrellm_imonc_create_optiontab, /* The create_plugin_tab() config function */
	gkrellm_imonc_apply_config,     /* The apply_plugin_config() function      */

	gkrellm_imonc_save_config,      /* The save_plugin_config() function  */
	gkrellm_imonc_load_config,      /* The load_plugin_config() function  */
	MONITOR_CONFIG_KEYWORD,         /* 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   */
	};

#if defined(WIN32)
__declspec(dllexport) GkrellmMonitor* gkrellm_init_plugin(win32_plugin_callbacks* calls)
#else
GkrellmMonitor* gkrellm_init_plugin(void)
#endif
{
  memset(&gkr, 0, sizeof(gkr));
  memset(&gui, 0, sizeof(gui));
  memset(&router, 0, sizeof(router));
  
  /* set defaults */ 
  router.host= g_strdup("fli4l");
  router.port= 5000;
  router.circuit= 1;
  router.channel= 1;
  router.launch_command= g_strdup("gtk-imonc %h %p");

	gkr.pGK= gkrellm_ticks();
	gkr.plugin_style_id= gkrellm_add_chart_style(&gkrellm_imonc_monitor, 
      IMONC_STYLE_NAME);
	gkr.mon= &gkrellm_imonc_monitor;

	return &gkrellm_imonc_monitor;
}
