#include <mac/All.h>
#include <mac/MACLib.h>
#include <mac/APEInfo.h>
#include <mac/APETag.h>
#include <mac/CharacterHelper.h>

#include <glib.h>
#include <gtk/gtk.h>
#include <wchar.h>

#include "common.h"

#define COMMON_TAG_COUNT 9

static gchar *common_tags[] = 
{
    _("ALBUM"),
    _("ARTIST"),
    _("COMMENT"),
    _("COMPOSER"),
    _("DATE"),
    _("GENRE"),
    _("PERFORMER"),
    _("TITLE"),
    _("TRACKNUMBER")
};

enum
{
    COL_NAME,
    COL_VALUE,
    N_COLS
};

typedef struct
{
    GtkWidget *window;
    GtkWidget *location;
    GtkWidget *techinfo;
    GtkWidget *metadata;

    IAPEDecompress *pAPEDecompress;
    gchar *current_filename;

} MAC_META_INFO;

typedef struct
{
    GtkWidget *tag_window;
    GtkWidget *field_name_widget;
    GtkWidget *field_value_widget;

    gboolean is_edit;
} MAC_META_TAG;
    
static MAC_META_INFO mac_info;
static MAC_META_TAG mac_tag;

#ifdef __cplusplus
extern "C"{
#endif

    /* callbacks of the whole APE info window */
    static void cb_info_box_close(GtkWidget *widget, gpointer data);
    static void cb_info_box_destroy(GtkWidget *widget, gpointer data);
    static gint cb_info_box_delete(GtkWidget *widget,
				   GdkEvent  *event,
				   gpointer   data );

    /* callbacks of the meta data related */
    static void cb_metadata_add(GtkWidget *widget, gpointer data);
    static void cb_metadata_edit(GtkWidget *widget, gpointer data);
    static void cb_metadata_remove(GtkWidget *widget, gpointer data);
    static void cb_metadata_update_file(GtkWidget *widget, gpointer data);

    /* callbacks of tag editing related */
    static void cb_tag_window_ok(GtkWidget *widget, gpointer data);
    static void cb_tag_window_cancel(GtkWidget *widget, gpointer data);
    static void cb_tag_window_destroy(GtkWidget *widget, gpointer data);
    static gint cb_tag_window_delete(GtkWidget *widget,
				     GdkEvent  *event,
				     gpointer   data );

    /* internal util functions */
    static void insert_metadata(GtkListStore* metadata, CAPETag *pAPETag);
    static void insert_techinfo(GtkListStore* techinfo, IAPEDecompress *pAPEDecompress);

    static void mac_tag_window_create();
    static void mac_info_box_create();

/**************************
 *   tag window related   *
 **************************/

void cb_tag_window_destroy(GtkWidget *widget, gpointer data)
{

    /* do some clean stuff of tag window */

    mac_tag.tag_window = NULL;
    mac_tag.field_name_widget = NULL;
    mac_tag.field_value_widget = NULL;
    mac_tag.is_edit = FALSE;
}

gint cb_tag_window_delete(GtkWidget *widget,
			GdkEvent  *event,
			gpointer   data )
{
    /* Don't destroy the window */

    gtk_widget_hide_all(mac_tag.tag_window);
    return TRUE;
}

void cb_tag_window_ok(GtkWidget *widget, gpointer data)
{
    const gchar *field_name;
    gchar *field_value;
    GtkEntry *entry; 
    GtkTextView *value_widget;
    GtkTextBuffer *value_buffer;
    GtkTextIter start_iter, end_iter;

    entry = GTK_ENTRY(GTK_BIN(mac_tag.field_name_widget)->child);
    field_name = gtk_entry_get_text(entry);

    value_widget = GTK_TEXT_VIEW(mac_tag.field_value_widget);
    value_buffer = gtk_text_view_get_buffer(value_widget);

    gtk_text_buffer_get_start_iter(value_buffer, &start_iter);
    gtk_text_buffer_get_end_iter(value_buffer, &end_iter);
    field_value = gtk_text_buffer_get_text(value_buffer, 
					   &start_iter, &end_iter, 
					   FALSE);

    if (mac_tag.is_edit)
    {
	/* Editing a tag */
	GtkTreeSelection *selection;
	GtkTreeIter iter;
	GtkTreeModel *model;

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mac_info.metadata));
	if (gtk_tree_selection_get_selected(selection, &model, &iter))
	{
	    gtk_list_store_set((GtkListStore *)model, &iter, 
			       COL_VALUE, field_value,
			       -1);
	}
    }
    else
    {
	/* Adding a tag */
	GtkListStore *list_store;
	GtkTreeIter iter;

	list_store = (GtkListStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(mac_info.metadata));
	gtk_list_store_append(list_store, &iter);
	gtk_list_store_set(list_store, &iter,
			   COL_NAME, field_name,
			   COL_VALUE, field_value, 
			   -1);
    }

    g_free(field_value);

    gtk_widget_hide_all(mac_tag.tag_window);
}

void cb_tag_window_cancel(GtkWidget *widget, gpointer data)
{
    gtk_widget_hide_all(mac_tag.tag_window);
}

/**************************
 *    info box related    *
 **************************/

void cb_info_box_destroy(GtkWidget *widget, gpointer data)
{

    /* do some clean stuff of info box window */

    mac_info.window = NULL;
    mac_info.location = NULL;
    mac_info.techinfo = NULL;
    mac_info.metadata = NULL;

    g_free(mac_info.current_filename);
    mac_info.current_filename = NULL;
    if (mac_info.pAPEDecompress)
    {
	delete mac_info.pAPEDecompress;
    }
    mac_info.pAPEDecompress = NULL;
}

gint cb_info_box_delete(GtkWidget *widget,
			GdkEvent  *event,
			gpointer   data )
{

    gtk_widget_hide_all(mac_info.window);

    return TRUE;
}

void cb_info_box_close(GtkWidget *widget, gpointer data)
{
    gtk_widget_hide_all(mac_info.window);
}

/**************************
 *   meta data related    *
 **************************/

void cb_metadata_update_file(GtkWidget *widget, gpointer data)
{

    GtkTreeIter iter;
    GtkTreeModel *model;
    gboolean res;

    /* remove all tags, then add one by one */

    CAPETag *apeTag = (CAPETag *)mac_info.pAPEDecompress->GetInfo(APE_INFO_TAG);
    apeTag->ClearFields();

    model = gtk_tree_view_get_model(GTK_TREE_VIEW(mac_info.metadata));

    res = gtk_tree_model_get_iter_first(model, &iter);
    while (res)
    {
	gchar *name, *value;
	
	gtk_tree_model_get(model, &iter,
			   COL_NAME, &name,
			   COL_VALUE, &value,
			   -1);
	wchar_t *utf16_name = GetUTF16FromUTF8((const str_utf8 *)name);
	apeTag->SetFieldString(utf16_name, value, TRUE);

	g_free(name);
	g_free(value);

	res = gtk_tree_model_iter_next(model, &iter);
    }

    if (apeTag->Save() != ERROR_SUCCESS)
    {
	printf("error update files, error code = %d\n", res);
    }

}

void cb_metadata_add(GtkWidget *widget, gpointer data)
{

    GtkEntry *entry;
    GtkTextView *field_value;
    GtkTextBuffer *value_buffer;

    if (!mac_tag.tag_window)
    {
	mac_tag_window_create();
    }

    entry = GTK_ENTRY(GTK_BIN(mac_tag.field_name_widget)->child);
    field_value = GTK_TEXT_VIEW(mac_tag.field_value_widget);
    value_buffer = gtk_text_view_get_buffer(field_value);

    gtk_widget_set_sensitive(mac_tag.field_name_widget, TRUE);
    gtk_entry_set_text(entry, "");

    gtk_text_buffer_set_text(value_buffer, "", -1);
    mac_tag.is_edit = FALSE;

    gtk_window_set_title(GTK_WINDOW(mac_tag.tag_window), _("Adding a Tag"));
    gtk_widget_show_all(mac_tag.tag_window);

}

void cb_metadata_edit(GtkWidget *widget, gpointer data)
{

    GtkEntry *entry; 
    GtkTextView *field_value;
    GtkTextBuffer *value_buffer;

    GtkTreeSelection *selection;
    GtkTreeIter iter;
    GtkTreeModel *model;

    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mac_info.metadata));
    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
    {
	return;
    }
    
    gchar *name;
    gchar *value;

    gtk_tree_model_get(model, &iter, 
		       COL_NAME, &name, 
		       COL_VALUE, &value,
		       -1);

    if (!mac_tag.tag_window)
    {
	mac_tag_window_create();
    }

    entry = GTK_ENTRY(GTK_BIN(mac_tag.field_name_widget)->child);
    field_value = GTK_TEXT_VIEW(mac_tag.field_value_widget);
    value_buffer = gtk_text_view_get_buffer(field_value);

    gtk_entry_set_text(entry, name);
    gtk_widget_set_sensitive(mac_tag.field_name_widget, FALSE);

    gtk_text_buffer_set_text(value_buffer, value, -1);

    g_free(name);
    g_free(value);

    mac_tag.is_edit = TRUE;

    gtk_window_set_title(GTK_WINDOW(mac_tag.tag_window), _("Editing a Tag"));
    gtk_widget_show_all(mac_tag.tag_window);

}

void cb_metadata_remove(GtkWidget *widget, gpointer data)
{
    GtkTreeSelection *selection;
    GtkTreeIter iter;
    GtkTreeModel *model;

    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mac_info.metadata));
    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
    {
	return;
    }
    
    gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
}

/***************************
 * internal util functions *
 ***************************/

void insert_metadata(GtkListStore* list_store, CAPETag *pAPETag)
{
    GtkTreeIter iter;

    if (!list_store || !pAPETag)
    {
	return;
    }

    gtk_list_store_clear(list_store);
    
    BOOL bHasID3Tag = pAPETag->GetHasID3Tag();
    BOOL bHasAPETag = pAPETag->GetHasAPETag();

    if (bHasID3Tag || bHasAPETag)
    {
	CAPETagField * pTagField;
	int index = 0;
	while ((pTagField = pAPETag->GetTagField(index)) != NULL)
	{
	    index ++;

	    const wchar_t *field_name;
	    char field_value[255];

	    gchar *name;

	    field_name = pTagField->GetFieldName();
	    name = (gchar *)GetUTF8FromUTF16(field_name);

	    memset(field_value, 0, 255);
	    int size = 255;
	    pAPETag->GetFieldString(field_name, (char *)field_value, &size, TRUE);

	    gtk_list_store_append(list_store, &iter);
	    gtk_list_store_set(list_store, &iter,
			       COL_NAME, name,
			       COL_VALUE, field_value,
			       -1);
	    
	    g_free(name);
	}
    }
}

void insert_techinfo(GtkListStore* list_store, IAPEDecompress *pAPEDecompress)
{
    GtkTreeIter iter;
    gchar *name, *value;

    if (!list_store || !pAPEDecompress)
    {
	return;
    }

    gtk_list_store_clear(list_store);

    /* APE Version */
    name = _("Version");
    value = g_strdup_printf("%.2f", (float)pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION) / float(1000));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Compression Level */
    name = _("Compression Level");
    switch (pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL))
    {
    case COMPRESSION_LEVEL_FAST:
	value = _("Fast");
	break;
    case COMPRESSION_LEVEL_NORMAL:
	value = _("Normal");
	break;
    case COMPRESSION_LEVEL_HIGH:
	value = _("High");
	break;
    case COMPRESSION_LEVEL_EXTRA_HIGH:
	value = _("Extra High");
	break;
    case COMPRESSION_LEVEL_INSANE:
	value = _("Insane");
	break;
    }
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);

    /* Format Flags */
    name = _("Flags");
    value = g_strdup_printf("%d", pAPEDecompress->GetInfo(APE_INFO_FORMAT_FLAGS));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Sample Rate */
    name = _("Sample Rate");
    value = g_strdup_printf("%d", pAPEDecompress->GetInfo(APE_INFO_SAMPLE_RATE));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Bits Per Sample */
    name = _("Bits Per Sample");
    value = g_strdup_printf("%d", pAPEDecompress->GetInfo(APE_INFO_BITS_PER_SAMPLE));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Channels */
    name = _("Channels");
    value = g_strdup_printf("%d", pAPEDecompress->GetInfo(APE_INFO_CHANNELS));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Actrual File if the file is APL */
    char *ext = strrchr(mac_info.current_filename, '.');
    if(ext)
    {
	if (!strcasecmp(ext, ".apl"))
	{
	    name = _("Actrual File");
	    CIO *pIO = (CIO *)pAPEDecompress->GetInfo(APE_INFO_IO_SOURCE);
	    if (pIO)
	    {
		wchar_t nameBuf[255];
		memset(nameBuf, 0, 255 * sizeof(wchar_t));
		pIO->GetName(nameBuf);
		gchar *actrual_name = (gchar *)GetUTF8FromUTF16(nameBuf);
		gchar *basename = g_strdup(g_basename(name));
		value = basename;
		gtk_list_store_append(list_store, &iter);
		gtk_list_store_set(list_store, &iter,
				   COL_NAME, name,
				   COL_VALUE, value,
				   -1);
		g_free(actrual_name);
		g_free(basename);
	    }
	}
    }
    
    /* Total File Size */
    name = _("File Size");
    value = g_strdup_printf("%d bytes", pAPEDecompress->GetInfo(APE_INFO_APE_TOTAL_BYTES));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Length (Time) */
    name = _("Length");
    unsigned int length = pAPEDecompress->GetInfo(APE_DECOMPRESS_LENGTH_MS);
    int min, sec, ms;
    ms = length % 1000;
    sec = length / 1000;
    min = sec / 60;
    sec = sec % 60;
    value = g_strdup_printf("%d:%d.%d ", min, sec, ms);
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

    /* Average Bitrate */
    name = _("Bitrate");
    value = g_strdup_printf("%d", pAPEDecompress->GetInfo(APE_DECOMPRESS_AVERAGE_BITRATE));
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       COL_NAME, name,
		       COL_VALUE, value,
		       -1);
    g_free(value);

}


void mac_tag_window_create()
{
    GtkWidget *tag_window;
    GtkWidget *vbox, *hbox;
    GtkWidget *field_name_label;
    GtkWidget *field_value_label;
    GtkWidget *field_name;
    GtkWidget *field_value;
    GtkWidget *button_ok, *button_cancel;

    gint i = 0;

    tag_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(GTK_OBJECT(tag_window), "destroy",
		     GTK_SIGNAL_FUNC(cb_tag_window_destroy), NULL);

    g_signal_connect(GTK_OBJECT (tag_window), "delete_event",
		     GTK_SIGNAL_FUNC (cb_tag_window_delete), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(tag_window), 10);
    gtk_window_set_modal(GTK_WINDOW(tag_window), TRUE);
    gtk_widget_set_size_request(tag_window, 250, 300);

    vbox = gtk_vbox_new(FALSE, 5);

    gtk_container_add(GTK_CONTAINER(tag_window), vbox);

    field_name_label = gtk_label_new(_("Field Name:"));
    gtk_misc_set_alignment(GTK_MISC(field_name_label), 0, 0);
    field_value_label = gtk_label_new(_("Field Value:"));
    gtk_misc_set_alignment(GTK_MISC(field_value_label), 0, 0);

    field_name = gtk_combo_box_entry_new_text();
    for (i = 0; i < COMMON_TAG_COUNT; i ++)
    {
	gtk_combo_box_append_text(GTK_COMBO_BOX(field_name), common_tags[i]);
    }

    field_value = gtk_text_view_new();
    gtk_text_view_set_editable(GTK_TEXT_VIEW(field_value), TRUE);

    hbox = gtk_hbutton_box_new();
    gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
    gtk_box_set_spacing(GTK_BOX(hbox), 5);

    button_ok = gtk_button_new_with_label("OK");
    g_signal_connect(GTK_OBJECT(button_ok), "clicked",
		     GTK_SIGNAL_FUNC(cb_tag_window_ok),
		     NULL);
    button_cancel = gtk_button_new_with_label("Cancel");
    g_signal_connect(GTK_OBJECT(button_cancel), "clicked",
		     GTK_SIGNAL_FUNC(cb_tag_window_cancel),
		     NULL);

    gtk_box_pack_start(GTK_BOX(hbox), button_ok,
		       TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), button_cancel,
		       TRUE, TRUE, 0);

    gtk_box_pack_start(GTK_BOX(vbox), field_name_label,
		       FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), field_name,
		       FALSE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), field_value_label,
		       FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), field_value,
		       TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), hbox,
		       FALSE, TRUE, 0);

    mac_tag.tag_window = tag_window;
    mac_tag.field_name_widget = field_name;
    mac_tag.field_value_widget = field_value;

}

void mac_info_box_create()
{

    GtkWidget *window = NULL;
    GtkWidget *location = NULL;
    GtkWidget *metadata = NULL;
    GtkWidget *techinfo = NULL;

    GtkWidget *location_frame, *metadata_frame, *techinfo_frame;
    GtkWidget *vbox, *hbox;
    GtkWidget *bottom_hbox;
    GtkWidget *close_button, *update_button;

    GtkWidget *meta_vbox;

    GtkWidget *buttons_hbox;
    GtkWidget *meta_add, *meta_remove, *meta_edit;

    GtkListStore *store;
    GtkTreeViewColumn *column;
    GtkCellRenderer *renderer;
	
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//	gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
    g_signal_connect(GTK_OBJECT(window), "destroy",
		     GTK_SIGNAL_FUNC(cb_info_box_destroy), NULL);

    g_signal_connect(GTK_OBJECT (window), "delete_event",
		     GTK_SIGNAL_FUNC (cb_info_box_delete), NULL);

    gtk_container_set_border_width(GTK_CONTAINER(window), 10);

    location_frame = gtk_frame_new(_("Location"));
    metadata_frame = gtk_frame_new(_("Metadata"));
    techinfo_frame = gtk_frame_new(_("Technical info"));

    vbox = gtk_vbox_new(FALSE, 5);
    hbox = gtk_hbox_new(FALSE, 5);

    bottom_hbox = gtk_hbutton_box_new();
    gtk_button_box_set_layout(GTK_BUTTON_BOX(bottom_hbox), GTK_BUTTONBOX_END);
    gtk_box_set_spacing(GTK_BOX(bottom_hbox), 5);

    gtk_container_add(GTK_CONTAINER(window), vbox);

    gtk_box_pack_start(GTK_BOX(vbox), location_frame, 
		       FALSE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), hbox,
		       TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), bottom_hbox,
		       FALSE, TRUE, 0);

    gtk_box_pack_start(GTK_BOX(hbox), metadata_frame,
		       TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), techinfo_frame,
		       FALSE, FALSE, 0);

    update_button = gtk_button_new_with_label(_("Update File"));
    gtk_box_pack_start(GTK_BOX(bottom_hbox), update_button,
		       TRUE, TRUE, 0);

    g_signal_connect(GTK_OBJECT(update_button), "clicked",
		     GTK_SIGNAL_FUNC(cb_metadata_update_file),
		     NULL);

    close_button = gtk_button_new_with_label(_("Close"));
    g_signal_connect(GTK_OBJECT(close_button), "clicked",
		     GTK_SIGNAL_FUNC(cb_info_box_close), 
		     NULL);
    gtk_box_pack_end(GTK_BOX(bottom_hbox), close_button,
		     TRUE, TRUE, 0);


    location = gtk_entry_new();
    gtk_container_add(GTK_CONTAINER(location_frame), location);
    gtk_editable_set_editable(GTK_EDITABLE(location), FALSE);

    meta_vbox = gtk_vbox_new(FALSE, 0);

    buttons_hbox = gtk_hbutton_box_new();
    gtk_button_box_set_layout(GTK_BUTTON_BOX(buttons_hbox), GTK_BUTTONBOX_END);
    gtk_box_set_spacing(GTK_BOX(buttons_hbox), 5);

    meta_add = gtk_button_new_with_label(_("Add"));
    g_signal_connect(GTK_OBJECT(meta_add), "clicked",
		     GTK_SIGNAL_FUNC(cb_metadata_add),
		     NULL);
    meta_remove = gtk_button_new_with_label(_("Remove"));
    g_signal_connect(GTK_OBJECT(meta_remove), "clicked",
		     GTK_SIGNAL_FUNC(cb_metadata_remove),
		     NULL);
    meta_edit = gtk_button_new_with_label(_("Edit"));
    g_signal_connect(GTK_OBJECT(meta_edit), "clicked",
		     GTK_SIGNAL_FUNC(cb_metadata_edit),
		     NULL);

    gtk_box_pack_start(GTK_BOX(buttons_hbox), meta_add, TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(buttons_hbox), meta_edit, TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(buttons_hbox), meta_remove, TRUE, TRUE, 0);


    gtk_box_pack_start(GTK_BOX(meta_vbox), buttons_hbox, FALSE, TRUE, 0);

    store = gtk_list_store_new(N_COLS, G_TYPE_STRING, G_TYPE_STRING);
    metadata = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    g_object_unref(store);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(
	_("Name"), renderer, "text", COL_NAME, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(metadata), column);
    gtk_tree_view_column_set_resizable(column, TRUE);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(
	_("Value"), renderer, "text", COL_VALUE, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(metadata), column);
    gtk_tree_view_column_set_resizable(column, TRUE);

    gtk_tree_view_columns_autosize(GTK_TREE_VIEW(metadata));

    gtk_box_pack_start(GTK_BOX(meta_vbox), metadata, TRUE, TRUE, 0);

    gtk_container_add(GTK_CONTAINER(metadata_frame), meta_vbox);


    store = gtk_list_store_new(N_COLS, G_TYPE_STRING, G_TYPE_STRING);
    techinfo = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    g_object_unref(store);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(
	_("Name"), renderer, "text", COL_NAME, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(techinfo), column);
    gtk_tree_view_column_set_resizable(column, TRUE);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(
	_("Value"), renderer, "text", COL_VALUE, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(techinfo), column);
    gtk_tree_view_column_set_resizable(column, TRUE);
    gtk_tree_view_columns_autosize(GTK_TREE_VIEW(techinfo));

    gtk_container_add(GTK_CONTAINER(techinfo_frame), techinfo);

    mac_info.window = window;
    mac_info.location = location;
    mac_info.techinfo = techinfo;
    mac_info.metadata = metadata;

}

void mac_file_info_box(char *filename)
{
    char *title;

    int nRetVal;
    wchar_t *pUTF16Name;

    if (!mac_info.window)
    {
	mac_info_box_create();
    }
    
    if (mac_info.current_filename)
    {
	g_free(mac_info.current_filename);
    }
    mac_info.current_filename = (gchar *)GetUTF8FromANSI(filename);
    
    title = g_strdup_printf(_("File Info - %s"), g_basename(mac_info.current_filename));
    gtk_window_set_title(GTK_WINDOW(mac_info.window), title);
    g_free(title);
    
    gtk_entry_set_text(GTK_ENTRY(mac_info.location), mac_info.current_filename);

    if (mac_info.pAPEDecompress)
    {
	delete mac_info.pAPEDecompress;
    }

    pUTF16Name = GetUTF16FromANSI(filename);
    mac_info.pAPEDecompress = CreateIAPEDecompress(pUTF16Name, &nRetVal);

    if (mac_info.pAPEDecompress == NULL || nRetVal != ERROR_SUCCESS)
    {
	printf("Oops, something is wrong with the file, error_code = %d\n", nRetVal);
	return;
    }

    CAPETag *apeTag = (CAPETag *)mac_info.pAPEDecompress->GetInfo(APE_INFO_TAG);
    GtkListStore *list_store;

    list_store = (GtkListStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(mac_info.metadata));
    insert_metadata(list_store, apeTag);
    list_store = (GtkListStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(mac_info.techinfo));
    insert_techinfo(list_store, mac_info.pAPEDecompress);

    gtk_widget_show_all(mac_info.window);
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
	printf("usage: fileinfo filename\n");
	return 0;
    }
    gtk_set_locale();
    gtk_init(&argc, &argv);

    mac_file_info_box(argv[1]);

    gtk_main();
    
    return 0;
}

#ifdef __cplusplus
}
#endif
