#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include <glib/gprintf.h>
#include "callbacks.h"
#include "interface.h"
#include "support.h"
#include "../include/globals.h"
#include "../include/pdictype.h"
#include "../include/endictype.h"
#include "../include/data.h"

int bitcount(gchar c)
{
	if(!(c&0x80))return 0;
	if(!(c&0x40))return 1;
	if(!(c&0x20))return 2;
	if(!(c&0x10))return 3;
	if(!(c&0x08))return 4;
	if(!(c&0x04))return 5;
	if(!(c&0x02))return 6;
	if(!(c&0x01))return 7;
	return 8;
}

//////////////////////////////////////////////////////////////////
//テキストビューへのメッセージの書き込み
void
settreeview(GtkWidget *widget,gchar *word,gchar *message)
{
	GtkTreeView *tview;
	GtkListStore *model;
	GtkTreeIter iter;
	
	//TreeModelを探す
	tview=GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(widget),"dicview"));
	model=GTK_LIST_STORE(gtk_tree_view_get_model(tview));

	//最終位置を取得
	gtk_list_store_append(GTK_LIST_STORE (model), &iter);
	//書き込み
	gtk_list_store_set (GTK_LIST_STORE (model),
									&iter, 0, word, 1 ,message, -1);
}
//////////////////////////////////////////////////////////////////
//テキストビューへのメッセージの書き込み
void
cleartreeview(GtkWidget *widget)
{
	GtkTreeView *tview;
	GtkTreeViewColumn *column;
	GtkListStore *model;
	
	//メモ帳探す
	tview=GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(widget),"dicview"));
	model=GTK_LIST_STORE(gtk_tree_view_get_model(tview));
	gtk_list_store_clear(model);

	column=gtk_tree_view_get_column(tview,1);
	gtk_tree_view_column_set_expand(column,TRUE);
	gtk_tree_view_column_set_fixed_width(column,2);
}
//////////////////////////////////////////////////////////////////
//検索ボタンの押下
void
on_btnsearch_clicked                   (GtkButton       *button,
                                        gpointer         user_data)
{
	const gchar *keyword;
	gint16 kbit,eixbit;
	gchar *k_sjis=NULL;
	guint32 count=1;
	GtkWidget *widget;
	GList *dl=NULL,*find=NULL,*fp;
	findword *fw;
	enindex *eix=NULL;

	//テキストエントリーを探す
	widget=lookup_widget(GTK_WIDGET(button),"edkeyword");
	keyword=gtk_entry_get_text(GTK_ENTRY(widget));
	kbit=bitcount(keyword[0]);
	if(kbit){
		k_sjis=g_convert(keyword,strlen(keyword),"shift_jis","utf-8",
										NULL,NULL,NULL);
	}

	if(!strlen(keyword))
		return;

	//インデックスから単語を検索する
	dl=g_list_first(indList);

	//前半スキップ
	while(dl){
		eix=dl->data;
		eixbit=bitcount(eix->word[0]);

		//キーワードがasciiの時
		if(kbit==0){
			//debug
			if(eixbit==0 && strcmp(keyword,eix->word)<=0){
				break;
			}else{
			}
		}
		else{
			if(strcmp(k_sjis,eix->word)<=0){
				break;
			}
		}
		dl=g_list_next(dl);
	}

	if(k_sjis)g_free(k_sjis);

	//dl が NULL なら最後のリスト
	if(dl==NULL)
		dl=g_list_last(indList);
	else
		dl=g_list_previous(dl);

	//画面の消去
	cleartreeview(GTK_WIDGET(button));

	do{
		eix=dl->data;

		//マッチする単語を検索
		find=pdicDataRead(eix->h,eix->fp,eix->pos,find,(gchar*)keyword);

		//マッチするものがなければ脱出
		if(!find) break;

		//表示
		fp=g_list_first(find);
		while(fp){
			fw=(findword*)fp->data;
			settreeview(GTK_WIDGET(button),fw->key,fw->direct);
			g_free(fw->key);
			g_free(fw->direct);
			fp=g_list_next(fp);
			count++;
		}
		g_list_free(find);
		find=NULL;fp=NULL;
		dl=g_list_next(dl);
	}while(dl);
}
//////////////////////////////////////////////////////////////////
//現在選択中の辞書のデータ構造体を返す
diclistitem *nowdiclistitem(void)
{
	GList *lp;
	diclistitem *item;

	lp=g_list_first(dicList);
	while(lp){
		item=(diclistitem*)(lp->data);
		if(item->h){
			return item;
		}
		lp=g_list_next(lp);
	}
	return NULL;
}
//////////////////////////////////////////////////////////////////
//辞書の変更
void
on_cmbdiclist_changed                  (GtkComboBox     *combobox,
                                        gpointer         user_data)
{
	gint entry;
	GtkComboBoxEntry *cmbdiclist;
	GList *lp;
	diclistitem *item;

	if(!dicloadflag) return;

	//どの辞書が選ばれたか調べる
	cmbdiclist= GTK_COMBO_BOX_ENTRY(combobox);
	entry=gtk_combo_box_get_active(combobox);

	//現在読み込まれている辞書のメモリ解放
	lp=g_list_first(dicList);
	while(lp){
		item=(diclistitem*)(lp->data);
		if(item->h){
			fclose(item->fp);
			ClearDictionary(&(item->h));
			item->h=NULL;
		}
		lp=g_list_next(lp);
	}
	
	//辞書をロード
	lp=g_list_nth(dicList,entry);
	item=(diclistitem*)(lp->data);

	item->h=g_new(newdic3,1);
	LoadDictionary(item->path,item->h,&(item->fp));
}
//////////////////////////////////////////////////////////////////
//キー入力
gboolean
on_edkeyword_key_press_event           (GtkWidget       *widget,
                                        GdkEventKey     *event,
                                        gpointer         user_data)
{
	gchar *keyword=NULL;
	GtkEntry *keyent; 
	
	
	if(event->keyval==GDK_Return){
		//ボタン押下イベントをコール
		on_btnsearch_clicked(
			GTK_BUTTON(lookup_widget(GTK_WIDGET(widget),"btnsearch")),
			NULL);
	}
	else if(event->keyval==GDK_Tab){
		//補完処理
		
		//文字の取得
		keyent=GTK_ENTRY(lookup_widget(GTK_WIDGET(widget),"edkeyword"));
		keyword=(gchar*)gtk_entry_get_text(keyent);

	}
	return FALSE;
}
//////////////////////////////////////////////////////////////////
//アプリケーションの終了
void
on_dickeyword_destroy                  (GtkObject       *object,
                                        gpointer         user_data)
{
	gtk_main_quit();
}
//////////////////////////////////////////////////////////////////
//情報ダイアログの表示
void
on_btnInfo_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkWidget *wig;
	gchar *str=NULL,*str2;
	diclistitem *item;
	newdic3 *nd3;

	//情報ウィンドウの生成
	dicinfo = create_dicinfodialog ();

	//登録辞書数ラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbEntryDics"));
	str=g_strdup_printf("%d",g_list_length(dicList));
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);
	//設定ファイルパスラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbShareEndicrc"));
	str=g_strdup_printf("%s/endicrc",PACKAGE_DATA_DIR);
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);
	//個人ファイルパスラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbPersonalEndicrc"));
	str=g_strdup_printf("%s/.endicrc",g_getenv("HOME"));
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);

	//インデックスラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbNowDicIndexCount"));
	//インデックス数を文字列に変換
	str=g_strdup_printf("%d",g_list_length(indList));
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);

	//現在の辞書情報を取得
	item=nowdiclistitem();
	//バージョンラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbNowDicVersion"));
	//バージョン番号を文字列に変換
	nd3=item->h;
	str=g_strdup_printf("%d.%d",(nd3->version>>8),(nd3->version&0xff));
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);
	//語彙数ラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbWordCount"));
	str=g_strdup_printf("%ld",nd3->nword);
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);
	//見出語の登録順ラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbDicOrder"));
	switch(nd3->dicorder){
		case 0: str=g_strdup("コード順");break;
		case 1: str=g_strdup("大小文字同順");break;
		case 2: str=g_strdup("辞書順");break;
		case 3: str=g_strdup("逆順");break;
		default: str=g_strdup("");
	}
	str2=g_convert(str,strlen(str),"utf-8","euc-jp",NULL,NULL,NULL);
	gtk_label_set_text(GTK_LABEL(wig),str2);
	g_free(str);
	g_free(str2);
	//属性ラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbDicTypes"));
	str=g_strnfill(256,0);
	if(nd3->dictype & 0x01) g_strlcat(str," AR圧縮",255);
	if(nd3->dictype & 0x02) g_strlcat(str," 多言語",255);
	if(nd3->dictype & 0x04) g_strlcat(str," 暗号化",255);
	if(nd3->dictype & 0x08) g_strlcat(str," ツリー",255);
	if(str[0]==0)g_strlcat(str,"なし",255);
	str2=g_convert(str,strlen(str),"utf-8","euc-jp",NULL,NULL,NULL);
	gtk_label_set_text(GTK_LABEL(wig),str2);
	g_free(str);
	g_free(str2);
	//更新回数ラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbUpdateCount"));
	str=g_strdup_printf("%d",nd3->update_count);
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);
	//更新回数ラベルの検索
	wig=GTK_WIDGET(lookup_widget(GTK_WIDGET(dicinfo),"LbExtheader"));
	str=g_strdup_printf("%d",nd3->extheader);
	gtk_label_set_text(GTK_LABEL(wig),str);
	g_free(str);

	gtk_widget_show (dicinfo);
	
}
//////////////////////////////////////////////////////////////////
//
void
on_btnClose_clicked                    (GtkButton       *button,
                                        gpointer         user_data)
{
	gtk_widget_destroy(dicinfo);
}

