#include <pwd.h>
#include <grp.h>
#include <string.h>
#include "main_window.h"
#include "gtkclist.h"


void add1000_callback ();
void add10000_callback ();
void insert_at_5_callback ();
void remove_at_6_callback ();
void clear_list_callback ();
void select10_callback ();
void deselect10_callback ();


void insert_pixmap ();

/* menu structure for menu factory */
static GtkMenuEntry main_menu_items[] =
{
  { "<gcontrol>/File/Add 1000", NULL, add1000_callback, NULL },
  { "<gcontrol>/File/Add 10000", NULL, add10000_callback, NULL},
  { "<gcontrol>/File/Insert at Row 5", NULL, insert_at_5_callback, NULL},
  { "<gcontrol>/File/Remove at Row 6", NULL, remove_at_6_callback, NULL},
  { "<gcontrol>/File/Clear List", NULL, clear_list_callback, NULL},
  { "<gcontrol>/File/Select 10", NULL, select10_callback, NULL},
  { "<gcontrol>/File/Deselect 10", NULL, deselect10_callback, NULL},
  { "<gcontrol>/File/Update User List", NULL, update_user_page, NULL},
  { "<gcontrol>/File/Update Group List", NULL, update_group_page, NULL},
  { "<gcontrol>/File/Pixmap!", NULL, insert_pixmap, NULL},
  { "<gcontrol>/File/Quit", NULL, main_window_destroy_callback, NULL }
};
static int main_nmenu_items = sizeof (main_menu_items) 
     / sizeof (main_menu_items[0]);


MainWindow *mainW = NULL;
GtkWidget *select_item;


void
main_window_init ()
{
  GtkWidget        *vbox;
  GtkWidget        *label;
  GtkWidget        *notebook;
  GtkWidget        *scrolled;
  GtkWidget        *frame;
  GtkStyle         *style;

  int               i;
  char             *text[6];
  char              titles[6][100];

  if (mainW)
    return;

  mainW = g_malloc (sizeof (MainWindow));
  
  mainW->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (mainW->window), "delete_event",
		      (GtkSignalFunc) main_window_destroy_callback, 
		      &mainW->window);
  gtk_window_set_title (GTK_WINDOW (mainW->window), 
			"Debian/GNU Linux User Manager");
  gtk_container_border_width (GTK_CONTAINER (mainW->window), 0);
  
  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (mainW->window), vbox);
  gtk_widget_show (vbox);
		     
  mainW->factory = gtk_menu_factory_new (GTK_MENU_FACTORY_MENU_BAR);
  mainW->subfactories[0] = gtk_menu_factory_new (GTK_MENU_FACTORY_MENU_BAR);
  gtk_menu_factory_add_subfactory (mainW->factory, mainW->subfactories[0],
				   "<gcontrol>");
  gtk_menu_factory_add_entries (mainW->factory, main_menu_items, 
				main_nmenu_items);
  mainW->menubar = mainW->subfactories[0]->widget;
  gtk_box_pack_start (GTK_BOX (vbox), mainW->menubar, FALSE, TRUE, 0);
  gtk_widget_show (mainW->menubar);

  /*
   * create the Notebook
   */
  notebook = gtk_notebook_new ();
  gtk_container_border_width (GTK_CONTAINER (notebook), 5);
  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
  gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 5);


  label = gtk_label_new ("Users");
  frame = gtk_frame_new ("Users on Zen");
  gtk_container_border_width (GTK_CONTAINER (frame), 5);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
  gtk_widget_show (frame);


  /*
   * create the GtkCList
   */
  strcpy (titles[0], "User");
  strcpy (titles[1], "UID");
  strcpy (titles[2], "GID");
  strcpy (titles[3], "Name");
  strcpy (titles[4], "Home Directory");
  strcpy (titles[5], "Shell");

  for (i = 0; i < 6; i++)
    text[i] = titles[i];

  mainW->user_clist = gtk_clist_new (6, text);
  gtk_clist_set_selection_mode (GTK_CLIST (mainW->user_clist), 
				GTK_SELECTION_BROWSE);
  gtk_container_border_width (GTK_CONTAINER (mainW->user_clist), 10);
  gtk_container_add (GTK_CONTAINER (frame), mainW->user_clist);
  gtk_clist_set_policy (GTK_CLIST (mainW->user_clist), 
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_clist_set_column_width (GTK_CLIST (mainW->user_clist), 0, 100);
  gtk_clist_set_column_width (GTK_CLIST (mainW->user_clist), 1, 40);
  gtk_clist_set_column_justification (GTK_CLIST (mainW->user_clist), 1,
				      GTK_JUSTIFY_RIGHT);
  gtk_clist_set_column_width (GTK_CLIST (mainW->user_clist), 2, 40);
  gtk_clist_set_column_justification (GTK_CLIST (mainW->user_clist), 2,
				      GTK_JUSTIFY_RIGHT);
  gtk_clist_set_column_width (GTK_CLIST (mainW->user_clist), 3, 150);
  gtk_clist_set_column_width (GTK_CLIST (mainW->user_clist), 4, 100);
  gtk_clist_set_column_width (GTK_CLIST (mainW->user_clist), 5, 100);

  gtk_widget_show (mainW->user_clist);

  /*
   * create the group page
   */

  label = gtk_label_new ("Groups");
  frame = gtk_frame_new ("Groups on Zen");
  gtk_container_border_width (GTK_CONTAINER (frame), 5);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
  gtk_widget_show (frame);

  strcpy (titles[0], "Group");
  strcpy (titles[1], "GID");
  strcpy (titles[2], "Members");

  mainW->group_clist = gtk_clist_new (3, text);
  gtk_container_border_width (GTK_CONTAINER (mainW->group_clist), 10);
  gtk_container_add (GTK_CONTAINER (frame), mainW->group_clist);

  gtk_clist_set_row_height (GTK_CLIST (mainW->group_clist), 20);
 
  gtk_clist_set_column_width (GTK_CLIST (mainW->group_clist), 0, 100);
  gtk_clist_set_column_width (GTK_CLIST (mainW->group_clist), 1, 40);
  gtk_clist_set_column_width (GTK_CLIST (mainW->group_clist), 2, 200);

  gtk_clist_set_column_justification (GTK_CLIST (mainW->group_clist), 1,
				      GTK_JUSTIFY_RIGHT);

  gtk_widget_show (mainW->group_clist);

  style = gtk_widget_get_style (mainW->user_clist);
  mainW->pixmap = gdk_pixmap_create_from_xpm 
    (GTK_CLIST (mainW->user_clist)->clist_window, &mainW->mask,
     &style->white, "test.xpm");

  /*
   * show window/notebook
   */
  gtk_widget_show (notebook);
  gtk_widget_show (mainW->window);
}		    

/*
 * update the user page of the main notebook
 */
void
update_user_page ()
{
  GdkColor red, green;
  GdkColormap *colormap;
  struct passwd  *pw;
  char            uid_s[50], 
                  gid_s[50];
  char           *text[6];
  char            titles[6][100];
  int             i;

  red.pixel = 0;
  red.red = 0xffff;
  red.green = 0;
  red.blue = 0;

  green.pixel = 0;
  green.red = 0;
  green.green = 0xffff;
  green.blue = 0;

  colormap = gdk_window_get_colormap 
    (GTK_CLIST (mainW->user_clist)->clist_window);

  gdk_color_alloc (colormap, &red);
  gdk_color_alloc (colormap, &green);

  for (i = 0; i < 6; i++)
    text[i] = titles[i];

  gtk_clist_freeze (GTK_CLIST (mainW->user_clist));
  gtk_clist_clear (GTK_CLIST (mainW->user_clist));

  while ((pw = getpwent ()))
    {
      sprintf (uid_s, "%d", pw->pw_uid);
      sprintf (gid_s, "%d", pw->pw_gid);

      text[0] = pw->pw_name;
      text[1] = uid_s;
      text[2] = gid_s;
      text[3] = pw->pw_gecos;
      text[4] = pw->pw_dir;
      text[5] = pw->pw_shell;

      gtk_clist_append (GTK_CLIST (mainW->user_clist), text);

      if (pw->pw_uid == 0)
	{
	gtk_clist_set_foreground (GTK_CLIST (mainW->user_clist), 
				  GTK_CLIST (mainW->user_clist)->rows-1, &red);
	}

      if (pw->pw_uid == 1)
	{
	gtk_clist_set_foreground (GTK_CLIST (mainW->user_clist), 
				  GTK_CLIST (mainW->user_clist)->rows-1, &green);
	}

      if (pw->pw_uid > 1 && pw->pw_uid <= 100)
	{
	gtk_clist_set_shift (GTK_CLIST (mainW->user_clist),
			     GTK_CLIST (mainW->user_clist)->rows-1,
			     0, 0, 15);
	}
    }
  endpwent ();

  gtk_clist_thaw (GTK_CLIST (mainW->user_clist));
}

void
update_group_page ()
{
  struct group  *gr;
  char            gid_s[50];
  char           *text[3];
  char            titles[3][100];
  char            members[4096];
  int             i, row;
  
  for (i = 0; i < 3; i++)
    text[i] = titles[i];

  gtk_clist_freeze (GTK_CLIST (mainW->group_clist));
  gtk_clist_clear (GTK_CLIST (mainW->group_clist));

  while ((gr = getgrent ()))
    {
      sprintf (gid_s, "%d", gr->gr_gid);

      strcpy (members, "");
      i = 0;
      while (gr->gr_mem[i])
	{
	  strcat (members, gr->gr_mem[i]);
	  
	  if (gr->gr_mem[++i])
	    strcat (members, ", ");
	}

      text[0] = NULL;
      text[1] = gid_s;
      text[2] = members;

      row = gtk_clist_append (GTK_CLIST (mainW->group_clist), text);
      gtk_clist_set_pixtext (GTK_CLIST (mainW->group_clist), row, 0, 
			     gr->gr_name, 5, mainW->pixmap, mainW->mask);
    }
  endgrent ();

  gtk_clist_thaw (GTK_CLIST (mainW->group_clist));
}

void
main_window_destroy_callback ()
{
  gtk_exit (0);
}

void
insert_pixmap ()
{
  gtk_clist_set_row_height (GTK_CLIST (mainW->user_clist), 20);

  gtk_clist_set_pixtext (GTK_CLIST (mainW->user_clist),
			 4, 0, "Hello", 5, mainW->pixmap, mainW->mask);


  gtk_clist_set_pixmap (GTK_CLIST (mainW->user_clist),
			10, 3, mainW->pixmap, mainW->mask);
  gtk_clist_set_shift (GTK_CLIST (mainW->user_clist),
		       10, 3, 0, 15);



  gtk_clist_set_text(GTK_CLIST (mainW->user_clist),
		     0, 0, "Joe Root!!!");
}

void
add1000_callback ()
{
  int i;
  char *text[6];
  char  titles[6][100];

  for (i = 0; i < 6; i++)
    {
      text[i] = titles[i];
      sprintf (titles[i], "Column %d", i+1);
    } 

  gtk_clist_freeze (GTK_CLIST (mainW->user_clist));

  for (i = 0 ; i <= 1000 ; i++ )
    {
      sprintf (titles[0], "Row %d", i+1);
      gtk_clist_append (GTK_CLIST (mainW->user_clist), text);
    }
  
  gtk_clist_thaw (GTK_CLIST (mainW->user_clist));
}

void
add10000_callback ()
{
  int i;
  char *text[6];
  char  titles[6][100];

  for (i = 0; i < 6; i++)
    {
      text[i] = titles[i];
      sprintf (titles[i], "Column %d", i+1);
    } 

  gtk_clist_freeze (GTK_CLIST (mainW->user_clist));

  for (i = 0 ; i <= 10000 ; i++ )
    {
      sprintf (titles[0], "Row %d", i+1);
      gtk_clist_append (GTK_CLIST (mainW->user_clist), text);
    }
  
  gtk_clist_thaw (GTK_CLIST (mainW->user_clist));
}

void
insert_at_5_callback ()
{
  int i;
  char *text[6];
  char  titles[6][100];

  for (i = 0; i < 6; i++)
    {
      text[i] = titles[i];
      sprintf (titles[i], "Column %d", i+1);
    } 

  gtk_clist_insert (GTK_CLIST (mainW->user_clist), 5, text);
}

void
remove_at_6_callback ()
{
  gtk_clist_remove (GTK_CLIST (mainW->user_clist), 6);
}

void
clear_list_callback ()
{
  gtk_clist_clear (GTK_CLIST (mainW->user_clist));
}

void 
select10_callback ()
{
   gtk_clist_select_row (GTK_CLIST (mainW->user_clist), 10, -1);
   gtk_clist_moveto (GTK_CLIST (mainW->user_clist),
		     10, 5, 0.5, 0.0);
}

void 
deselect10_callback ()
{
  gtk_clist_unselect_row (GTK_CLIST (mainW->user_clist), 10, -1);
}
