/*******************************************************************
 *                  Light Weight Chord Library 1.0                 *
 *  CopyRight(C) Yoshihide Matsumoto IDEON WorkingGroup 2003,2004  *
 *      matsumoto333@yahoo.co.jp (http://www.matchan.mydns.jp)     *
 *                                                                 *
 * Implementation of chord (Distributed Hash Table)                *
 * This program is distributed under GPL                           *
 * Light Weight Chord Library comes with ABSOLUTELY NO WARRANTY.   *
 * This is free software, and you are welcome to redistribute it   *
 * under certain conditions; read `COPYING' for details.           *
 *******************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> //gethostbyname
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include "main.h"
#include "protocol.h"
#include "mchord.h"
#include "misc.h"
#include "app_list.h"


//構造体
typedef struct _App App;
struct _App
{
  GtkWidget *window;
  GtkWidget *clist;
  gint       selected_row;
  gint       selected_column;
  gchar     *selected_text;
};

#define MAX_BUFF 128

//global
MChord   *pMChord;
Protocol *pProtocol;
GtkWidget *pname;
GtkWidget *ptext;
GdkColor  color_blue;
GdkColor  color_green;
GtkWidget *clist;
GtkWidget *button_join_label;
APPLIST *pip_list;


void close_application (GtkWidget *widget, gpointer data ){

  
  pMChord->Quit();
  gtk_main_quit();
  
}




static void cb_selected (GtkWidget      *clist,
                         gint            row,
                         gint            column,
                         GdkEventButton *event,
                         App            *app);



int timeout_func(gpointer data){
  pMChord->TimerFunc();
  return TRUE;
}



void socket_func(gpointer data, gint sock, GdkInputCondition condition){


  pProtocol->RecvPacket((int)sock);


  return;
}


void recv_data(char *data){
  

  char buf1[MAX_BUFF];
  char buf2[MAX_BUFF];
  char *start;
  char *name;
  char *msg;

  start = strchr(data, '>');
  if(start != NULL){
    *start = '\0';
    name = &data[0];
    msg = &start[1];
    start = strchr(&start[1], '\n');
    if(start != NULL){
      *start = '\0';
    }
    
    
  }

  if(data != NULL){
    sprintf(&buf1[0], "%s\n", msg);//black
  }
  
  if(name != NULL){
    sprintf(&buf2[0], "%s>", name);//green
  }

  gtk_text_freeze(GTK_TEXT(ptext));
  gtk_text_insert (GTK_TEXT(ptext), NULL, &color_green, NULL,
		   &buf2[0], -1);
  gtk_text_insert (GTK_TEXT(ptext), NULL, NULL, NULL,
		   &buf1[0], -1);
  
  gtk_text_thaw(GTK_TEXT(ptext));
  
  
}


void file2gui(int McId, char *pCacheDir){

  FILE *fp;
  char buf[32];
  char file_name[50];
  char *start;
  char *clist_buf[2];

  sprintf(file_name,"./%s/%d", pCacheDir, McId);
  fp = fopen(file_name,"r");

  log(NOTICE, "file2gui %s\n", file_name);

  if(fp == NULL){
    fprintf(stderr, "main: cannot open file = %s\n",file_name);
    return;
  }

  //delete member list
  gtk_clist_clear(GTK_CLIST(clist));
  
  //open file
  while(fgets(buf,30,fp) != NULL){
    start = strchr(buf, ',');

    if(start != NULL){
      *start = '\0';
      clist_buf[0] = &buf[0];
      clist_buf[1] = &start[1];
      start = strchr(&start[1], '\n');
      if(start != NULL){
	*start = '\0';
      }
      gtk_clist_append(GTK_CLIST (clist), clist_buf);
    }
  }

  fclose(fp);
  
}


//TODO: change file2gui to iplist2gui
//unused
void iplist2gui(){

  char ipbuff[32];
  APPLIST *plist;  
  plist = pip_list;


  while(plist != NULL){
    ip_to_str(plist->ip, ipbuff);
    //fprintf(fp, "%s,%s:%d\n",plist->name, ipbuff, plist->port);
    plist = plist->next;
  }


}


void send_data(GtkWidget *widget, gpointer data){
  
  char buf1[MAX_BUFF];
  char buf2[MAX_BUFF];
  char buf3[MAX_BUFF*2];

  ADDRESS Address;
  char ipbuff[32];  
  APPLIST *plist;  
  plist = pip_list;

  GtkWidget *entry_msg;

  entry_msg = (GtkWidget *)data;
  



  sprintf(&buf1[0], "%s\n",gtk_entry_get_text(GTK_ENTRY(entry_msg)));//black
  sprintf(&buf2[0], "%s>",gtk_entry_get_text(GTK_ENTRY(pname)));//blue
  sprintf(&buf3[0], "%s%s",
	  &buf2[0], gtk_entry_get_text(GTK_ENTRY(entry_msg)));//send data
  gtk_text_freeze(GTK_TEXT(ptext));  
  gtk_text_insert (GTK_TEXT(ptext), NULL, &color_blue, NULL,
		   &buf2[0], -1);
  gtk_text_insert (GTK_TEXT(ptext), NULL, NULL, NULL,
		   &buf1[0], -1);
  
  gtk_text_thaw(GTK_TEXT(ptext));
  gtk_entry_set_text(GTK_ENTRY(entry_msg), "");
 
  while(plist != NULL){
    if(plist->ip != pMChord->GetIp() || plist->port != pMChord->GetPort()){
      log(NOTICE, "send message to %s:%d\n", plist->name, plist->port);
      ip_to_str(plist->ip, ipbuff);
      Address.Ip   = plist->ip;
      Address.Port = plist->port;
      pMChord->SendMessage(Address, &buf3[0]);
    }
    plist = plist->next;
  }
 
  
  
  
}

void send_login(GtkWidget *widget, gpointer data ){

  GtkWidget *room_msg;
  
  char buf_room[128];
  char buf_name[128];
  
  room_msg = (GtkWidget *) data;
  strncpy(buf_room, gtk_entry_get_text(GTK_ENTRY(room_msg)), 128);
  strncpy(buf_name, gtk_entry_get_text(GTK_ENTRY(pname)), 128);
  
  //SendLookup
  pMChord->SendLookupData(&buf_room[0]);
  
  //call back recv_lookup_response
  
}


void file2iplist(int McId){
  
  FILE *fp;
  char buf[32];
  char file_name[50];
  char *start;
  char *ip;
  int  port;
  char *name;
  
  sprintf(file_name,"./%s/%d", pMChord->GetCacheDir(), McId);
  fp = fopen(file_name,"r");

  if(fp == NULL){   
    fprintf(stderr, "main: cannot open file = %s\n",file_name);
    fp = fopen(file_name, "w");
    fclose(fp);
    return;
  }


  //open file
  while(fgets(buf, 30, fp) != NULL){

    start = strchr(buf, ',');

    if(start != NULL){
      *start = '\0';
      name = &buf[0];
      ip = &start[1];
      start = strchr(&start[1], '\n');
      if(start != NULL){
	*start = '\0';
      }
      start = strchr(ip,':');
      if(start != NULL){
	*start = '\0';
	port = atoi(&start[1]);
      }
      app_delete_key((APPLIST **)&pip_list, str_to_ip(ip), port);
      app_insert((APPLIST **)&pip_list, str_to_ip(ip), port, name);
      
    }
  }

  fclose(fp);


}


void iplist2file(int McId){

  FILE *fp;
  char file_name[50];
  char ipbuff[32];
  
  APPLIST *plist;  
  plist = pip_list;
  
  sprintf(file_name,"./%s/%d", pMChord->GetCacheDir(), McId);
  fp = fopen(file_name, "w");

  if(fp == NULL){   
    fprintf(stderr, "main: cannot open file = %s\n", file_name);
    fclose(fp);
    return;
  }
  
  while(plist != NULL){
    log(NOTICE, "iplist2file %s:%d\n", plist->name, plist->port);
    ip_to_str(plist->ip, ipbuff);
    fprintf(fp, "%s,%s:%d\n",plist->name, ipbuff, plist->port);
    plist = plist->next;
  }
  
  fclose(fp);
  
}


void recv_lookup_response(int McId){

  int key;

  //file to mem (app_insert)
  file2iplist(McId);
  
  log(NOTICE, "app_print\n");
  app_print((APPLIST **)&pip_list);

  //delete my name
  app_delete_key((APPLIST **)&pip_list, pMChord->GetIp(), pMChord->GetPort());
  log(NOTICE, "ip=%d, port = %d\n", 
	  pMChord->GetIp(), pMChord->GetPort());
  app_print((APPLIST **)&pip_list);
  log(NOTICE, "app_deleted\n\n");

  //add my name to MChord
  app_insert((APPLIST **)&pip_list, pMChord->GetIp(), pMChord->GetPort(),
	     gtk_entry_get_text(GTK_ENTRY(pname)));
  
  app_print((APPLIST **)&pip_list);
  
  
  //mem to file
  iplist2file(McId);
  
  //update GUI
  file2gui(McId, pMChord->GetCacheDir());  
  
  //SendInsert
  pMChord->SendInsert(McId);
  
  
}

void send_join(GtkWidget *widget, gpointer data ){

  GtkWidget *command_msg;
  char buf[128];
  char *buf_label;
  command_msg = (GtkWidget *) data;
  strncpy (buf, gtk_entry_get_text (GTK_ENTRY(command_msg)), 128);

  //Call Join
  gtk_label_get(GTK_LABEL(button_join_label), &buf_label);
  if(!strcmp(buf_label,"JOIN")){
    pMChord->Join(&buf[0]);
    gtk_label_set(GTK_LABEL(button_join_label), "LEAVE");
  }
}


void show_help (GtkWidget *widget, gpointer data ){

  GtkWidget *window;
  GtkWidget *box;
  GtkStyle  *style;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  GtkWidget *logo;
  GtkWidget *label;


  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_usize (window, 250, 350);
  gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);  
  gtk_window_set_title (GTK_WINDOW (window), "P2P CHAT WITH MCHORD");
  gtk_container_set_border_width (GTK_CONTAINER (window), 0);
  gtk_widget_show (window);

  //vbox
  box = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), box);
  gtk_widget_show (box);
  
  //ロゴ
  style = gtk_widget_get_style (window);
  pixmap = gdk_pixmap_create_from_xpm(window->window, &mask, 
					&style->bg[GTK_STATE_NORMAL],
					"p2pirc.xpm");
  logo = gtk_pixmap_new (pixmap, mask);
  gtk_box_pack_start (GTK_BOX(box), logo, FALSE, FALSE, 15);
  gtk_widget_show (logo);
  
  //ラベル
  label = gtk_label_new ("
 使用方法\n
 1. ネットワークに接続方法            
    Join IPに接続先アドレス:ポート番号
    「192.168.0.1:4649」    
    を入力しJOINボタンを押します      
 2. NAMEに自分の表示名を入力します
 3. ルームへの参加方法      
    ROOM NAMEにルーム名
   「ideon」   
    を入力しLOGINボタンを押します
    更新通知できないためLOGINボタンを連打します
");
  
  gtk_misc_set_alignment (GTK_MISC (label), 0,0);
  gtk_box_pack_start (GTK_BOX(box), label, FALSE, FALSE, 15);
  gtk_widget_show(label);

  
}

void Usage(){
  printf("mchord 1.0a  2004 .Feb\n");
  fprintf(stderr, "usage: ./matchan[-hcp]\n");
  fprintf(stderr, "  -h              - this message\n");
  fprintf(stderr, "  -c CacheDir     - cache directory\n");
  fprintf(stderr, "  -p PortNumber   - port number\n");
  fprintf(stderr, "  -l              - output logfile to stderr\n");
  fprintf(stderr, "\n");
  fprintf(stderr, "ex) ./mchord -p 5555\n");
  fprintf(stderr, "ex) ./mchord -p 5555 -c cache\n");
  
}

//FALSE=0
//TRUE=-1,1
int Options(int argc, char *argv[], int *port , char *cache_dir, int *log_flg){

  char c;

  while((c = getopt(argc, argv, "ht:i:c:p:o:w:l")) != -1){

    switch(c){
    case 'h': //help
      Usage();
      return(FALSE);
      break;

    case 'c':
      *cache_dir = '\0';
      strcpy(cache_dir, optarg);
      break;

    case 'p': //input iplist
      *port = atoi(optarg);
      break;
      
    case 'l':
      *log_flg = 1;
      break;

    default: //unknown option
      fprintf(stderr, "Error: Illegal Option '%c'!!\n", c);
      Usage();
      return(FALSE);
      break;
    }

  }


  //error
  if(*port < 0){
    fprintf(stderr, "Error: port number error !!\n");
    return FALSE;
  }


  return TRUE;

}


int main( int argc, char *argv[] )
{

  int sock;
  int port;
  int log_flg;
  char cache_dir[256];


  App app;
  GtkWidget *window;
  GtkWidget *box;

  GtkWidget *box_left;
  GtkWidget *table;
  GtkWidget *text;
  GdkColormap *cmap;

  GdkFont   *fixed_font;
  GtkWidget *box_left_bottom;

  GtkWidget *entry_msg;
  GtkWidget *button_send;

  GtkWidget *separator;

  GtkWidget *box_right;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
  GtkWidget *logo;
  GtkStyle  *style;
  GtkWidget *frame;
  GtkWidget *label_status;

  GtkWidget *table_join;
  GtkWidget *label_join;
  GtkWidget *entry_join;

  GtkWidget *button_join;

  GtkWidget *box_right_middle;
  GtkWidget *label_name;
  GtkWidget *entry_name; 


  GtkWidget *table_login;
  GtkWidget *label_login;
  GtkWidget *entry_login;
  GtkWidget *button_login;
  
  GtkWidget *scrolled_win;
  GtkWidget *vscrollbar;
  GtkWidget *button;  

  gtk_set_locale();


  cache_dir[0] = '\0';
  port = 0;
  log_flg = 0;

  //引数の解析
  //          in    in    out    out        out
  if((Options(argc, argv, &port, cache_dir, &log_flg)) == FALSE){
    return -1;
  }
  fprintf(stderr,"\n", cache_dir);
  //初期化  
  pMChord   = new MChord(port, cache_dir, log_flg);
  pProtocol = new Protocol();
  

  //gtk
  gtk_init (&argc, &argv);  
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_usize (window, 500, 500);
  gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);  
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
		      GTK_SIGNAL_FUNC(close_application),
		      NULL);
  gtk_window_set_title (GTK_WINDOW (window), "P2P CHAT WITH MCHORD");
  gtk_container_set_border_width (GTK_CONTAINER (window), 0);
  

  //メインのhbox横
  box = gtk_hbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), box);
  gtk_widget_show (box);
  
  //左フレームのvbox縦
  box_left = gtk_vbox_new (FALSE, 10);
  gtk_container_set_border_width (GTK_CONTAINER (box_left), 10);
  gtk_box_pack_start (GTK_BOX (box), box_left, TRUE, TRUE, 0);
  gtk_widget_show (box_left);
  
  //テキストのためのテーブル
  table = gtk_table_new (2, 2, FALSE);
  gtk_table_set_row_spacing (GTK_TABLE (table), 0, 0);
  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 0);
  gtk_box_pack_start (GTK_BOX (box_left), table, TRUE, TRUE, 0);
  gtk_widget_show (table);
  
  //テキストウィンドウ
  text = gtk_text_new (NULL, NULL);
  gtk_text_set_editable (GTK_TEXT(text), FALSE);
  gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
		    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL),
		    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
  gtk_widget_set_usize (text, 300, 250);
  gtk_widget_show (text);
  
  //global
  ptext = text;

  //テキストスクロールバー
  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
  gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
		    (GtkAttachOptions) (GTK_FILL), 
		    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
  gtk_widget_show (vscrollbar);
  
  // Get the system color map
  cmap = gdk_colormap_get_system();
  color_blue.red = 0;
  color_blue.green = 0;
  color_blue.blue = 0xffff;
  color_green.red = 0;
  color_green.green = 0xcfff;
  color_green.blue = 0;

  if (!gdk_color_alloc(cmap, &color_blue)) {
    g_error("couldn't allocate color");
  }

  if (!gdk_color_alloc(cmap, &color_green)) {
    g_error("couldn't allocate color");
  }

  //フォント
  //fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-140-*-*-*-*-*-*");
  
  gtk_widget_realize (text);
  
  //複数からのアップデートのためにfreezeする
  gtk_text_freeze (GTK_TEXT (text));
  
  // Insert some colored text
  //  gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
  //  		 "test ", -1);
  //  gtk_text_insert (GTK_TEXT (text), NULL, &color, NULL,
  //  		 "color ", -1);
  //  gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL,
  //  		 "text and different ", -1);
  //gtk_text_insert (GTK_TEXT (text), fixed_font, &text->style->black, NULL,
  //		 "fonts\n\n", -1);

  gtk_text_thaw(GTK_TEXT(text));

  //左下hbox
  box_left_bottom = gtk_hbox_new (FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (box_left_bottom), 0);
  gtk_box_pack_start (GTK_BOX (box_left), box_left_bottom, FALSE, FALSE, 0);
  gtk_widget_show (box_left_bottom);


  //テキスト
  entry_msg = gtk_entry_new_with_max_length(50);

  gtk_signal_connect(GTK_OBJECT(entry_msg), "activate",
		     GTK_SIGNAL_FUNC(send_data),entry_msg);
  gtk_entry_set_text(GTK_ENTRY(entry_msg),"");
  gtk_entry_set_editable(GTK_ENTRY(entry_msg),TRUE);
  gtk_box_pack_start(GTK_BOX(box_left_bottom),entry_msg,
		     TRUE,TRUE,0);
  gtk_widget_show(entry_msg);
  
  //sendボタン
  button_send = gtk_button_new_with_label ("Send!");
  gtk_signal_connect (GTK_OBJECT (button_send), "clicked",
		      GTK_SIGNAL_FUNC(send_data),
		      (gpointer)entry_msg);
  gtk_box_pack_start (GTK_BOX (box_left_bottom), button_send, FALSE, FALSE, 0);
  GTK_WIDGET_SET_FLAGS (button_send, GTK_CAN_DEFAULT);
  gtk_widget_grab_default (button_send);
  gtk_widget_show (button_send);

  //セパレータ
  separator = gtk_vseparator_new ();
  gtk_box_pack_start (GTK_BOX (box), separator, FALSE, TRUE, 0);
  gtk_widget_show (separator);


  //右フレーム
  box_right = gtk_vbox_new (FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (box_right), 10);
  gtk_widget_set_usize (box_right, 200,400);
  gtk_box_pack_start (GTK_BOX (box), box_right, FALSE, FALSE, 0);
  gtk_widget_show (box_right);

  //ロゴ
  style = gtk_widget_get_style (window);
  pixmap = gdk_pixmap_create_from_xpm(window->window, &mask, 
					&style->bg[GTK_STATE_NORMAL],
					"p2pirc.xpm");
  logo = gtk_pixmap_new (pixmap,mask);
  gtk_box_pack_start (GTK_BOX(box_right),logo,FALSE, FALSE, 0);
  gtk_widget_show (logo);

  //STATUSラベル
  label_status = gtk_label_new("STATUS : NONE");
  gtk_misc_set_alignment (GTK_MISC (label_status), 0,0);
  gtk_widget_show(label_status);


  //infoフレーム枠
  frame = gtk_frame_new ("info");
  gtk_container_set_border_width (GTK_CONTAINER (frame),0);
  gtk_box_pack_start (GTK_BOX (box_right), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);
  gtk_container_add (GTK_CONTAINER (frame),label_status);



  
  //右中hbox
  box_right_middle = gtk_hbox_new (FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (box_right), 10);
  gtk_box_pack_start (GTK_BOX (box_right), box_right_middle, FALSE, FALSE, 0);
  gtk_widget_show (box_right_middle);

  
  //ROOM ラベル
  label_name = gtk_label_new("Name");
  gtk_box_pack_start(GTK_BOX(box_right_middle),label_name,
		     TRUE,TRUE,0);
  gtk_widget_set_usize (label_name,60,10);
  gtk_widget_show(label_name);


  //ROOM テキスト
  entry_name = gtk_entry_new_with_max_length(20);
  gtk_entry_set_text(GTK_ENTRY(entry_name),"name");
  gtk_entry_set_editable(GTK_ENTRY(entry_name),TRUE);
  gtk_box_pack_start(GTK_BOX(box_right_middle),entry_name,
		     TRUE,TRUE,10);
  gtk_widget_show(entry_name);

  pname = entry_name;
  


  //右小テーブル
  table_join = gtk_table_new (4, 3, TRUE);
  gtk_box_pack_start (GTK_BOX (box_right), table_join, TRUE, TRUE, 0);
  gtk_widget_show (table_join);

  //JOINラベル
  label_join = gtk_label_new("MCHORD Join IP");
  gtk_table_attach_defaults (GTK_TABLE (table_join),label_join,0,2,0,1);
  gtk_widget_set_usize (label_join,100,38);
  gtk_misc_set_alignment (GTK_MISC (label_join), 0,1);
  gtk_widget_show(label_join);

  //テキスト
  entry_join = gtk_entry_new_with_max_length(20);
  gtk_entry_set_text(GTK_ENTRY(entry_join),"192.168.0.4:5555");
  gtk_entry_set_editable(GTK_ENTRY(entry_join),TRUE);
  gtk_table_attach_defaults (GTK_TABLE (table_join),entry_join,0,2,1,2);
  //  gtk_widget_set_usize (label_join,50,30);
  gtk_widget_show(entry_join);
  
  //JOINボタン
  button_join_label = gtk_label_new("JOIN");
  gtk_widget_show(button_join_label);

  button_join = gtk_button_new();
  gtk_container_add(GTK_CONTAINER(button_join),button_join_label);
  gtk_signal_connect (GTK_OBJECT (button_join), "clicked",
		      GTK_SIGNAL_FUNC(send_join),(gpointer)entry_join);
  gtk_table_attach_defaults (GTK_TABLE (table_join),button_join,2,3,1,2);

  GTK_WIDGET_SET_FLAGS (button_join, GTK_CAN_DEFAULT);
  gtk_widget_grab_default (button_join);  
  gtk_widget_show (button_join);


  //LOGINラベル
  label_login = gtk_label_new("ROOM name");
  gtk_table_attach_defaults (GTK_TABLE (table_join),label_login,0,2,2,3);
  //gtk_widget_set_usize (label_login,100,30);
  gtk_misc_set_alignment (GTK_MISC (label_login), 0, 1);
  gtk_widget_show(label_login);

  //テキスト
  entry_login = gtk_entry_new_with_max_length(20);
  gtk_entry_set_text(GTK_ENTRY(entry_login),"ideon");
  gtk_entry_set_editable(GTK_ENTRY(entry_login),TRUE);
  gtk_table_attach_defaults (GTK_TABLE (table_join),entry_login,0,2,3,4);
  //  gtk_widget_set_usize (label_login,50,30);
  gtk_widget_show(entry_login);
  
  //LOGINボタン
  button_login = gtk_button_new_with_label ("LOGIN");
  gtk_signal_connect (GTK_OBJECT (button_login), "clicked",
		      GTK_SIGNAL_FUNC(send_login),(gpointer)entry_login);
  gtk_table_attach_defaults (GTK_TABLE (table_join),button_login,2,3,3,4);
  GTK_WIDGET_SET_FLAGS (button_login, GTK_CAN_DEFAULT);
  gtk_widget_grab_default (button_login);
  gtk_widget_show (button_login);



  //scroll window
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, 
				  GTK_POLICY_AUTOMATIC);
  gtk_widget_set_usize (GTK_WIDGET (scrolled_win), 70, 250);
  gtk_box_pack_start (GTK_BOX (box_right), scrolled_win, TRUE, TRUE, 0);
  gtk_widget_show(scrolled_win);


  {

  gint i;
  gchar *titles[2] = { "NAME", "IP" };

  //    gchar *items[4][2] =
  //    {
  //      {"matsu", "192.168.0.X"},
  //      {"youki", "192.168.0.X"},
  //      {"y-doi", "192.168.0.X"},
  //      {"saito", "192.168.0.X"}
  //    };
  
  clist = gtk_clist_new_with_titles (2, titles);
  gtk_clist_set_column_width (GTK_CLIST (clist), 0, 60);
  gtk_signal_connect (GTK_OBJECT (clist), "select_row",
		      GTK_SIGNAL_FUNC (cb_selected), &app);
  //for (i = 0; i < 4; i++)
  //  gtk_clist_append (GTK_CLIST (clist), items[i]);
  
  gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
  
  app.clist = clist;
  app.selected_row = -1;
  gtk_widget_show(clist);
  
  
  }  
  

  //HELP button
  button = gtk_button_new_with_label ("HELP");
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC(show_help),
		      NULL);
  gtk_box_pack_start (GTK_BOX (box_right), button, FALSE, FALSE, 0);
  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
  gtk_widget_grab_default (button);
  gtk_widget_show (button);



  gtk_widget_show (window);

  //Initialize socket
  sock = pProtocol->SocketInit(pMChord->GetPort());

  //
  gdk_input_add(sock, GDK_INPUT_READ, socket_func, NULL);
  gtk_timeout_add(pMChord->GetTimer(), timeout_func, NULL);
  gtk_main();
  
  return(0);       
}




static void cb_selected (GtkWidget *clist, gint row, gint column,
			 GdkEventButton *event, App *app){
  //gchar *text;
  //gtk_clist_get_text (GTK_CLIST (clist), row, column, &text);
  //g_print ("%d:%d'%s'\n",row, column, text);
  //app->selected_row = row;

  return;

}
