/** @file  evcfg.c
 *  @brief evidence setup tool
 *  generic client library in evclient.c
 */

#include "config.h"

#include <gtk/gtk.h>

#include <Ecore.h>
#include <Ecore_Ipc.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>



#include "evidence.h"
#include "errors.h"
#include "ipc.h"
#include "evclient.h"



#define OUT "< "
#define ERR "! "
#define IN  "> "

#define MI 4096



int debug=2;



typedef struct _col {
  GtkColorSelection *cs;
  char              *prop;
  GdkColor           colour;
  guint16            alpha;
} col;



/*****************************************************************************/



/**
 * callback: connected
 * @param data connstate variable
 * @param type event-type
 * @param event the event
 */
int ev_ipc_server_con(void *data,int type,void *event) {
  connstate                  *cs=(connstate *)data;
  *cs=ONLINE;
  E(1,"Connected to " ECORE_IPC_PIPE ".\n");
  return 1; }



/**
 * callback: disconnected
 * @param data connstate variable
 * @param type event-type
 * @param event the event
 */
int ev_ipc_server_dis(void *data,int type,void *event) {
  connstate                  *cs=(connstate *)data;
  *cs=OFFLINE;
  ecore_main_loop_quit();
  E(1,"Disconnected.\n");
  return 1; }



/**
 * callback: connected
 * @param data reserved
 * @param type event-type
 * @param event the event
 */
int ev_ipc_server_sent(void *data,int type,void *event) {
  Ecore_Ipc_Event_Server_Data *e=(Ecore_Ipc_Event_Server_Data *)event;
  E(2,"evidence sent: %2d.%02d  #%03d=>#%03d  \"%s\".%d\n",
    e->major,e->minor,0,0,(char *)e->data,e->size);
  if(e->data&&(e->size>0))
    printf(OUT "%s\n",(char *)e->data);
  else if(e->response<0)
    printf(OUT "error #%d\n",e->response);
  else if(!e->response)
    printf(OUT "OK\n");
  else
    printf(OUT "result: %d\n",e->response);
  ecore_main_loop_quit();
  return 1; }



/*****************************************************************************/
/* GTK callbacks */



/**
 * callback: dial was closed, end program
 * @param w the window that was closed
 * @param data reserved
 */
static void dial_colour_closed(GtkWidget *w,void *data) {
  gtk_main_quit(); }



/**
 * callback: colour was changed
 * @param widget the widget that received the event
 * @param c our colour struct
 */
static void dial_colour_activate(GtkWidget *widget,col *c) {
  char v[8];
  c->alpha=gtk_color_selection_get_current_alpha(c->cs);
  gtk_color_selection_get_current_color(c->cs,&c->colour);
  gtk_widget_modify_bg(widget,GTK_STATE_NORMAL,&c->colour);
  snprintf(v,8,"#%02x%02x%02x",(c->colour.red)>>8,(c->colour.blue)>>8,(c->colour.green)>>8);
  printf("%s=\"%s\"\n",c->prop,v); }



/**
 * open a GTK colour-selection dialog
 * @param prop the name of the evidence-property we want to change the colour for
 */
void dial_colour_open(char *prop) {
  GtkWidget         *dial_colour=gtk_color_selection_dialog_new(prop);
  GtkColorSelection *cs=GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dial_colour)->colorsel);
  gint               response;
  col                c;

  memset(&c,0,sizeof(col));
  c.cs=cs;
  c.prop=prop;

  gtk_color_selection_set_has_opacity_control(cs,TRUE);
  g_signal_connect(G_OBJECT(dial_colour),"destroy",G_CALLBACK(dial_colour_closed),(gpointer)NULL);
  g_signal_connect(G_OBJECT(cs),"color_changed",G_CALLBACK(dial_colour_activate),(gpointer)&c);

  response=gtk_dialog_run(GTK_DIALOG(dial_colour));
  if(response==GTK_RESPONSE_OK) {
    puts("OK");
//  gtk_color_selection_get_current_color(cs,&colour);
//  gtk_widget_modify_bg(dial_colour,GTK_STATE_NORMAL,&colour);
  }
  else if(response==GTK_RESPONSE_HELP)
    puts("HELP");
  else
    puts("CXL");

  gtk_widget_hide(dial_colour); }



/*****************************************************************************/



/**
 * evidence configuration tool (mainloop).
 * @param argc number of command-line arguments
 * @param argv command-line arguments
 */
int main(int argc,char **argv) {
  Ecore_Ipc_Server *server=NULL;
  int               ret=NOIR_SUCC,cc=0;
  connstate         cs=OFFLINE;
  char             *p,*f=NULL;
  char              buf[MI];
  gtk_init(&argc,&argv);


  puts("\nEXPERIMENTAL.  THIS DOES NOT DO ANYTHING USEFUL YET.\n");


//  marshal_gc_handle=timeout_add(GC_INTERVAL_MAIN,marshal_gc,(void *)sa);

  dial_colour_open("rubberboxbordercolour");

  gtk_main();

#if 0
  ecore_init();
  ecore_app_args_set(argc,(const char **)argv);
  ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,ev_ipc_sigexit,&cs);

reconnect:
  cc++;
  if((ret=ev_ipc_init(&server,&cs))!=NOIR_SUCC)
    E(0,"%sconnect to " ECORE_IPC_PIPE " failed: %d\n",(cc>1)?"re":"",ret);
  else {
    while(1) {
      p=NULL;
      ecore_main_loop_iterate();
      if(cs==OFFLINE) {
        ev_ipc_exit(&server);
        cs=ONLINE;
        goto reconnect; }

      printf(IN);
      if((f=p=fgets(buf,MI,stdin))) {
        char *q=strchr(p,'\n');
        if(q)
          *q='\0';
        if(!strcasecmp(p,"exit")||!strcasecmp(p,"quit")) {
          if(f)
            free(f);
          break; }

        if((ret<NOIR_SUCC)&&(ret!=NOIR_IGNORED))
          printf(ERR "error #%d: \"%s.\"\n",-ret,noir_error(ret));
        if(f)
          free(f); }
      else
        break; }}

  ev_ipc_exit(&server);
  ecore_shutdown();
#endif

  return ret; }



/*****************************************************************************/
