/* (C) Copyright 1999 Patrick Lambert <drow@wildstar.net>
 *
 * This program is free software. You can use, copy and modify it under
 * the terms of the GPL. See the file COPYING for the full GPL license.
*/

#include "gtk-shell.h"

#define VERSION "gtk-shell 1.03"

void print_out(char *string)
{
 /* prints the string */
 if(output==NULL) fprintf(stdout, "%s", string);
 else fputs(string, output);
 /* optional end of line char */
 if(output==NULL && append) fprintf(stdout, "\n");
 if(output!=NULL && append) fputs("\n", output);
}

void print_err(char *string)
{
 if(output==NULL) fprintf(stderr, "gtk-shell: %s", string);
 else fputs(string, output);
}  

void help()
{
 print_out("gtk-shell (C) 1999 Patrick Lambert <drow@darkelf.net> under GPL\n");
 print_out("This program will use the GTK library (www.gtk.org) to ask for user input, and can be used in scripts or called from other programs.\n\n");
 print_out("Command line options:\n");
 print_out("--help, -h               This help text\n");
 print_out("--version, -v            Show gtk-shell's version\n");
 print_out("--output <file>, -o      Set the output file, default is stdout\n");
 print_out("--title <title>, -t      Set the window title\n");
 print_out("--label <label>, -l      Show a label to the user\n");
 print_out("--file-selection, -fs    Display a file selection box\n");
 print_out("--size <x> <y>, -s       Set the size of the window\n");
 print_out("--position <x> <y>, -p   Set the position of the window on the screen\n");
 print_out("--query, -q              Display a query box\n");
 print_out("--query-value, -qv       Set a value in the query box\n");
 print_out("--append-eol, -eol       Appends an EOL char at output time\n");
 print_out("--exit-code <str>, -ec   String to display if user press Cancel\n");
 print_out("--view-file <file>, -vf  View a file in a text box\n");
 print_out("--edit-file <file>, -ef  Edit a file in a text box\n");
 print_out("--button <str>, -b       Add a button to quit\n");
 print_out("--choice <c1> <c2>.., -c Display a choice box with the specified choices\n");
 print_out("\nExample: gtk-shell -l \"Pick a choice\" -c 1 2 3 4 -b Ok -eol\n");
 print_out("Example: xv -quit -root `gtk-shell -t \"Which image?\" -fs`\n");
 exit(0);
}

void CB_exit(GtkWidget *widget, GtkWidget *entry)
{
 if(combo) print_out(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(cb)->entry)));
 else print_out(exit_code);
 gtk_widget_destroy(window);
 gtk_main_quit();   
 exit(0);
}

void CB_query_ok(GtkWidget *widget, GtkWidget *entry)
{
 print_out(gtk_entry_get_text(GTK_ENTRY(entry_box)));
 gtk_widget_destroy(window);
 gtk_main_quit();
 exit(0);
}

void CB_save(GtkWidget *widget, gpointer data)
{
 char *alltext = gtk_editable_get_chars(GTK_EDITABLE (text), 0, gtk_text_get_length(GTK_TEXT(text)));
 fd=fopen(filename,"w");
 fputs((char*)alltext,fd);
 if(fd!=NULL) fclose(fd);
 g_free(alltext);
 exit(0);
}

void CB_fs_ok(GtkWidget *widget, GtkFileSelection *fs)
{
 print_out(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
 gtk_widget_destroy(window);
 gtk_main_quit();
 exit(0);
}

void fs()
{
 window = gtk_file_selection_new(title);
 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
  GTK_SIGNAL_FUNC(CB_exit), &window);
 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button),
  "clicked", GTK_SIGNAL_FUNC(CB_fs_ok), window);
 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->cancel_button),
  "clicked", GTK_SIGNAL_FUNC(CB_exit), &window);
}

void make_main_win()
{
 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
  GTK_SIGNAL_FUNC(CB_exit), &window);
 gtk_container_border_width(GTK_CONTAINER(window), 5);

 vbox = gtk_vbox_new (FALSE, 0);
 gtk_container_add (GTK_CONTAINER (window), vbox);
 gtk_widget_show (vbox);
}

int main(int argc, char *argv[])
{
 output = NULL;
 size = FALSE; pos = FALSE, append = FALSE, combo = FALSE;
 strcpy(title,"gtk-shell");
 gtk_init(&argc, &argv);
 make_main_win();
 if(argc==1) help();
 for(i=1;i<argc;i++)
 {
  /* end of command line */
  if(argv[i]==NULL) break;
  /* arg too big to fit in vars */
  if(strlen(argv[i])>500)
  {
   print_err("Argument overflow\n");
   exit(1);
  }
  else if(!strcasecmp(argv[i],"--version") || !strcasecmp(argv[i],"-v"))
  {
   print_out(VERSION);
   print_out("\n");
   exit(0);
  }
  else if(!strcasecmp(argv[i],"--append-eol") || !strcasecmp(argv[i],"-eol"))
  {
   append = TRUE;
  }
  else if(!strcasecmp(argv[i],"--exit-code") || !strcasecmp(argv[i],"-ec"))
  {
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No exit code specified\n");
    exit(1);
   }
   strncpy(exit_code, argv[i], 500);
  }
  else if(!strcasecmp(argv[i],"--output") || !strcasecmp(argv[i],"-o"))
  {
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No output file specified\n");
    exit(1);
   }
   output = fopen(argv[i], "a");
   if(output==NULL)
   {
    print_err("Can't open output file\n");
    exit(1);
   }
  }
  else if(!strcasecmp(argv[i],"--query-value") || !strcasecmp(argv[i],"-qv"))
  {
   if(entry_box==NULL)
   {
    print_err("You must specify an entry box first (--query)\n");
    exit(1);
   }
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No default entry specified\n");
    exit(1);
   }
   gtk_entry_set_text(GTK_ENTRY(entry_box), argv[i]);
  }
  else if(!strcasecmp(argv[i],"--title") || !strcasecmp(argv[i],"-t"))
  {
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No title specified\n");
    exit(1);
   }
   strncpy(title, argv[i], 512);
   gtk_window_set_title(GTK_WINDOW(window), title);
  }
  else if(!strcasecmp(argv[i],"--file-selection") || !strcasecmp(argv[i],"-fs"))
  {
   size = TRUE;
   fs();
  }
  else if(!strcasecmp(argv[i],"--view-file") || !strcasecmp(argv[i],"-vf")
       || !strcasecmp(argv[i],"--edit-file") || !strcasecmp(argv[i],"-ef"))
  {
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No file name specified\n");
    exit(1);
   }
   table = gtk_table_new(2, 2, FALSE);
   gtk_table_set_row_spacing(GTK_TABLE(table), 0, 2);
   gtk_table_set_col_spacing(GTK_TABLE(table), 0, 2);
   gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
   gtk_widget_show(table);

   text = gtk_text_new(NULL, NULL);
   gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
   gtk_text_set_editable (GTK_TEXT (text), TRUE);
   gtk_table_attach_defaults(GTK_TABLE(table), text, 0, 1, 0, 1);
   gtk_widget_show(text);

   vscrollbar = gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
   gtk_table_attach(GTK_TABLE(table), vscrollbar, 1, 2, 0, 1,
   GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
   gtk_widget_show(vscrollbar);
   gtk_text_freeze(GTK_TEXT(text));
   gtk_widget_realize(text);

   fd = fopen(argv[i], "r");
   if(fd==NULL)
   {
    print_err("Can't open file\n");
    exit(1);
   }
   while(fgets(temp, 500, fd)!=NULL)
   gtk_text_insert(GTK_TEXT(text), NULL, &text->style->black, NULL, temp, -1); 
   fclose(fd);
   gtk_text_thaw(GTK_TEXT(text));
   if(!size)
   {
    size = TRUE;
    gtk_widget_set_usize(GTK_WIDGET(window), 450, 200);
   }
   if(!strcasecmp(argv[i-1],"--edit-file") || !strcasecmp(argv[i-1],"-ef"))
   {
    strncpy(filename, argv[i], 500);
    button = gtk_button_new_with_label("Save");
    gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
    GTK_SIGNAL_FUNC(CB_save), GTK_OBJECT (window));
    gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
    gtk_widget_show(button);
   }
  }
  else if(!strcasecmp(argv[i],"--help") || !strcasecmp(argv[i],"-h"))
  {
   help();
  }
  else if(!strcasecmp(argv[i],"--size") || !strcasecmp(argv[i],"-s"))
  {
   if(argv[i+1]==NULL || argv[i+2]==NULL || atoi(argv[i+1])<1 || atoi(argv[i+2])<1)
   {
    print_err("Invalid size\n");
    exit(1);
   }
   gtk_widget_set_usize(GTK_WIDGET(window), atoi(argv[i+1]), atoi(argv[i+2]));
   i = i + 2;
   size = TRUE;
  }
  else if(!strcasecmp(argv[i],"--button") || !strcasecmp(argv[i],"-b"))
  {
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No label specified\n");
    exit(1);
   }
   button = gtk_button_new_with_label(argv[i]);
   gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
   GTK_SIGNAL_FUNC(CB_exit), GTK_OBJECT (window));
   gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
   gtk_widget_show(button);
  }
  else if(!strcasecmp(argv[i],"--query") || !strcasecmp(argv[i],"-q"))
  {
   entry_box = gtk_entry_new();
   gtk_editable_select_region(GTK_EDITABLE(entry_box), 0, -1);
   gtk_box_pack_start(GTK_BOX(vbox), entry_box, TRUE, TRUE, 0);
   gtk_widget_show(entry_box);

   hbox = gtk_hbutton_box_new();
   gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
   gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 5);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
   gtk_widget_show (hbox);

   button = gtk_button_new_with_label("OK");
   gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
   GTK_SIGNAL_FUNC(CB_query_ok), GTK_OBJECT (window));
   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
   gtk_widget_show(button);

   button = gtk_button_new_with_label("Cancel");
   gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
   GTK_SIGNAL_FUNC(CB_exit), GTK_OBJECT (window));
   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
   gtk_widget_show(button);
  }
  else if(!strcasecmp(argv[i],"--position") || !strcasecmp(argv[i],"-p"))
  {
   if(argv[i+1]==NULL || argv[i+2]==NULL || atoi(argv[i+1])<0 || atoi(argv[i+2])<0)
   {
    print_err("Invalid position\n");
    exit(1);
   }
   gtk_widget_set_uposition(GTK_WIDGET(window), atoi(argv[i+1]), atoi(argv[i+2]));
   i = i + 2;
   pos = TRUE;
  }
  else if(!strcasecmp(argv[i],"--choice") || !strcasecmp(argv[i],"-c"))
  {
   cbitems = NULL;
   i++;
   for(i=i; argv[i]!=NULL && *argv[i]!='-'; i++)
   {
    cbitems = g_list_append(cbitems, argv[i]);
   }
   i--;
   cb = gtk_combo_new ();
   gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
   gtk_box_pack_start (GTK_BOX (vbox), cb, TRUE, TRUE, 0);
   gtk_widget_show (cb);
   combo = TRUE;
  }
  else if(!strcasecmp(argv[i],"--label") || !strcasecmp(argv[i],"-l"))
  {
   i++;
   if(argv[i]==NULL || *argv[i]=='-')
   {
    print_err("No label specified\n");
    exit(1);
   }
   label = gtk_label_new(argv[i]);
   gtk_box_pack_start(GTK_BOX (vbox), label, TRUE, TRUE, 0);
   gtk_widget_show(label);    
  }
  else
  {
   sprintf(temp, "Unknown command: %s\n", argv[i]);
   print_err(temp);
  }
 }
 if(!size) gtk_widget_set_usize(GTK_WIDGET(window), 300, 100);
 if(!pos) gtk_widget_set_uposition(GTK_WIDGET(window), 100, 100);
 gtk_widget_show(window);
 gtk_main();
 exit(0);
}
