/*  Gnometab -- a guitar tablature editor for GNOME
    Copyright (C) 2001  William L. Guelker

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <math.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <gnome.h>
#include "tab_canvas.h"
#include "interface.h"
#include "chord_builder.h"
#include "dialogs.h"
#include "tab_objects.h"
#include "chord_canvas.h"
#include "chord_lib.h"


static void 
destroy_chord_object(gpointer chord_object, gpointer user_data)
{
    GnomeCanvasItem *object;
    
    if (GNOME_IS_CANVAS_ITEM(chord_object))    {
        object = GNOME_CANVAS_ITEM(chord_object);
        gtk_object_destroy(GTK_OBJECT(object));
        
    }
}

static void 
count_chord_object(GtabChordLib *lib, GnomeCanvasItem *staff_obj)
{
    lib->obj_counter = g_list_prepend(lib->obj_counter, (gpointer ) staff_obj);
    
}

static gint
count_chords(GtabChordLib *lib)
{
    gint total = 0;
    gchar *active;
    xmlNodePtr ptr;
    
    for (ptr = lib->lib_doc->xmlRootNode->children; ptr != NULL; ptr = ptr->next)    {
        if (xmlIsBlankNode(ptr) == 1) continue;
            
        active = get_prop(ptr, "active");
        if (!active) total++;
        g_free(active);
    }
    
    return(total);
}

static void 
create_lib_chord_text(GnomeCanvasGroup* chord_group, double x, double y,
                                    double grid_x, double grid_y, gchar *text,
                                    GtabChordLib *lib)
{
    GnomeCanvasItem    *grid_item;
    PangoFontDescription *font_string;
    
    if (grid_x >= 84)    {
        font_string = pango_font_description_from_string(lib->parent->tab_font_small);
    
    }
    else    {
        font_string = pango_font_description_from_string(lib->parent->tab_font);
    }
    
    grid_item = gnome_canvas_item_new(chord_group, 
                                        gnome_canvas_text_get_type(),
                                        "text", text,
                                        "x", x + grid_x,
                                        "y", y + grid_y,
                                        "anchor", GTK_ANCHOR_NORTH_WEST,
                                        "font_desc", font_string,
                                        "fill_color", "firebrick4",
                                        NULL);
    pango_font_description_free(font_string);
    
}

static void 
create_lib_chord_bar(GnomeCanvasGroup* chord_group, double x, double y,
                                double grid_x, double grid_y, gint positions)
{
    GnomeCanvasItem    *new_bar;
    GnomeCanvasPoints  *points;
    double                 start_x;
    double                 start_y;
    double                 total_length;
    
    start_x = x + grid_x;
    start_y = y + grid_y - 17.0;
    total_length = 12*positions;
    
    points = gnome_canvas_points_new(6);

    points->coords[0] = start_x;
    points->coords[1] = start_y;
    points->coords[2] = start_x + (total_length/5);
    points->coords[3] = start_y - 4.0;
    points->coords[4] = start_x + 2*(total_length/5);
    points->coords[5] = start_y - 6.0;
    points->coords[6] = start_x + 3*(total_length/5);
    points->coords[7] = start_y - 6.0;
    points->coords[8] = start_x + 4*(total_length/5);
    points->coords[9] = start_y - 4.0;
    points->coords[10] = start_x + 5*(total_length/5);
    points->coords[11] = start_y;
    
    new_bar = gnome_canvas_item_new(chord_group,
                                    gnome_canvas_line_get_type(),
                                    "points", points,
                                    "fill_color", "firebrick4",
                                    "width_pixels", 1,
                                    "first_arrowhead", FALSE,
                                    "last_arrowhead", FALSE,
                                    "smooth", TRUE,
                                    "spline_steps", 8,    
                                    NULL);

    gnome_canvas_points_unref(points);
    
}

static void
create_lib_chord_name(GnomeCanvasGroup* chord_group, 
                        double x, double y, gchar *chrdname,
                        GtabChordLib *lib)
{
    GnomeCanvasItem *grid_item;
    PangoFontDescription *font_string;
    
    font_string = pango_font_description_from_string(lib->parent->tab_font);
    
    grid_item = gnome_canvas_item_new(chord_group,
                                    gnome_canvas_text_get_type(),
                                    "text", chrdname,
                                    "x", x + 43.0,
                                    "y", y + 12.0,
                                    "anchor", GTK_ANCHOR_SOUTH,
                                    "font_desc", font_string,
                                    "fill_color", "black",
                                    NULL);
    pango_font_description_free(font_string);
}



static GnomeCanvasGroup*
create_chord_grid_on_lib(GtabChordLib *lib, double start_x, double start_y)
{
    GnomeCanvasGroup   *lib_chord;
    GnomeCanvasItem    *grid;
    GnomeCanvasPoints  *points;
    double                 x = 0.0;
      double                 y = 0.0;
      gchar                 outline_color[12];

    lib_chord = GNOME_CANVAS_GROUP(gnome_canvas_item_new(lib->lib_group, 
                                        gnome_canvas_group_get_type(), 
                                        NULL));    
    
    for (x = start_x + 7.0; x <= start_x + 63.0; x = x + 14.0)    {
        
        for (y = start_y + 12.0; y <= start_y + 72.0; y = y + 12.0)    {
            
            if (y == start_y + 12.0)    {
                g_snprintf(outline_color, 11, "white");
            }
            else    {
                g_snprintf(outline_color, 11, "steel blue");
            }
            
            points = gnome_canvas_points_new(4);
            points->coords[0] = x;
            points->coords[1] = y;
            points->coords[2] = x + 14.0;
            points->coords[3] = y;
            points->coords[4] = x + 14.0;
            points->coords[5] = y + 12.0;
            points->coords[6] = x;
            points->coords[7] = y + 12.0;
            
            grid = gnome_canvas_item_new(lib_chord,
                                     gnome_canvas_polygon_get_type(),
                                     "points", points,
                                     "width_pixels", 1,
                                     "fill_color", "white",
                                     "outline_color", outline_color,
                                     NULL);
            
            gnome_canvas_points_unref(points);
            
        }
     }

      
    return lib_chord;
}

static gint 
chord_lib_event(GnomeCanvasItem *chord_object, GdkEvent *event, GtabChordLib *lib)
{
    xmlNodePtr    chord_node;
    
    switch (event->type)    {
        case GDK_BUTTON_PRESS:
            if (lib->parent->current_tool != TOOL_LIB_CHORD) prior_tool = lib->parent->current_tool;
        
            lib->parent->current_tool = TOOL_LIB_CHORD;
            
            chord_node = (xmlNodePtr ) g_object_get_data(G_OBJECT(chord_object), "node");
            /* error checking here */
            switch (event->button.button)    {
                case 1:
                    if (lib->highlights)    {
                        gtk_object_destroy(GTK_OBJECT(lib->highlights));
                        lib->highlights = NULL;
                    }
                    /*if (lib->selected_chord != NULL)    {
                        xmlFreeNode(lib->selected_chord);
                        lib->selected_chord = NULL;
                    }*/
                    lib->selected_chord = xmlCopyNode(chord_node, TRUE);
                    lib->selected_chord_item = chord_object;
                    
                    gnome_appbar_set_status(GNOME_APPBAR(lib->parent->appbar),
                                        "Current Tool: Library Chord");
                
                    lib->highlights = GNOME_CANVAS_GROUP
                                        (gnome_canvas_item_new(lib->lib_group,
                                                gnome_canvas_group_get_type(),
                                                NULL));
                    highlight_object(lib->selected_chord_item, lib->highlights);
                    // load_lib_chord(chord_node);
                    
                    break;
                case 2:
                    break;
                default:
                    if (lib->highlights)    {
                        gtk_object_destroy(GTK_OBJECT(lib->highlights));
                        lib->highlights = NULL;
                    }
                    
                    lib->selected_delete = chord_node;
                    lib->selected_chord_item = chord_object;
                    
                    lib->highlights = GNOME_CANVAS_GROUP
                                        (gnome_canvas_item_new(lib->lib_group,
                                                gnome_canvas_group_get_type(),
                                                NULL));
                    highlight_object(lib->selected_chord_item, lib->highlights);
                    
                    gtk_menu_popup(GTK_MENU(lib->popup->menu), 
                                    NULL, NULL, NULL, NULL, 1, 0);

                    break;
            }
        default:
            break;
    }
        
    
    return TRUE;
    
}

static void
render_each_chord(GtabChordLib *lib, xmlNodePtr chord_node, 
                    GnomeCanvasGroup* chord_group, 
                            double x, double y)
{
    xmlNodePtr                 ptr;
    gchar                    *char_x, *char_y, *char_text, *char_int;
    double                     grid_x, grid_y;
    double                     x1, y1, x2, y2;
    gchar                    *check_active;
    
    for (ptr = chord_node->children; ptr != NULL; ptr = ptr->next)    {
        
        if (xmlIsBlankNode(ptr) == 1) continue;
        check_active = get_prop(ptr, "active");
                    
        if (!check_active)    {
            
            if (g_ascii_strcasecmp(ptr->name, "chord_text") == 0)    {
                char_x = get_prop(ptr, "x_create");
                char_y = get_prop(ptr, "y_create");
                grid_x = atof(char_x);
                grid_y = atof(char_y) + 12.0;
                g_free(char_x);
                g_free(char_y);
                
                char_text = get_prop(ptr, "text");
                
                create_lib_chord_text(chord_group, x, y, grid_x, grid_y, 
                                            char_text, lib);
                g_free(char_text);
            }
            if (g_ascii_strcasecmp(ptr->name, "chord_bar") == 0)    {
                char_x = get_prop(ptr, "x_create");
                char_y = get_prop(ptr, "y_create");
                grid_x = atof(char_x);
                grid_y = atof(char_y) + 12.0; 
                g_free(char_x);
                g_free(char_y);
                
                char_int = get_prop(ptr, "positions");
                create_lib_chord_bar(chord_group, x, y, grid_x, grid_y, 
                                        atoi(char_int));
                g_free(char_int);
                
            }
            if (g_ascii_strcasecmp(ptr->name, "chord_name") == 0)    {
                char_text = get_prop(ptr, "name_text");
                create_lib_chord_name(chord_group, x, y, char_text, lib);
                g_free(char_text);
            }
        }
        g_free(check_active);
    }
    gnome_canvas_item_get_bounds(GNOME_CANVAS_ITEM(chord_group), 
                                            &x1, &y1, &x2, &y2);
    
    count_chord_object(lib, GNOME_CANVAS_ITEM(chord_group));
    
    xmlSetProp(chord_node, "x1", float_to_char(x1));
    xmlSetProp(chord_node, "y1", float_to_char(y1));
    xmlSetProp(chord_node, "x2", float_to_char(x2));
    xmlSetProp(chord_node, "y2", float_to_char(y2));
    
    g_signal_connect(GTK_OBJECT(chord_group), "event", 
                                    (GtkSignalFunc) chord_lib_event, lib);
    g_object_set_data(G_OBJECT(chord_group), "node", chord_node);
}

static void
render_chords(GtabChordLib *lib)
{
    int                 num_chords;
    double                 row, column, size;
    xmlNodePtr             ptr;
    gchar                *active;
    GnomeCanvasGroup   *new_chord;
    GnomeCanvasItem    *background;
    GnomeCanvasPoints  *points;
    
    num_chords = count_chords(lib);
    
    size = ceil( num_chords > 0 ? num_chords : 1 )*100.0;
    
      gnome_canvas_set_scroll_region (GNOME_CANVAS 
                (lib->lib_canvas), 0, 0, 120, size);
    lib->lib_group = gnome_canvas_root(GNOME_CANVAS(lib->lib_canvas));
    
    points = gnome_canvas_points_new(4);
    points->coords[0] = 0.0;
    points->coords[1] = 0.0;
    points->coords[2] = 120.0;
    points->coords[3] = 0.0;
    points->coords[4] = 120.0;
    points->coords[5] = size;
    points->coords[6] = 0.0;
    points->coords[7] = size;
    
    background = gnome_canvas_item_new(lib->lib_group,
                                        gnome_canvas_polygon_get_type(),
                                        "points", points,
                                        "width_pixels", 1,
                                        "fill_color", "white",
                                        "outline_color", "black",
                                        NULL);
    
    gnome_canvas_points_unref(points);
    
    count_chord_object(lib, GNOME_CANVAS_ITEM(background));
    
    column = 15.0;
    row = 10.0;
    
    for (ptr = lib->lib_doc->xmlRootNode->children; ptr != NULL; ptr = ptr->next)    {
        if (xmlIsBlankNode(ptr) == 1) continue;
            
        active = get_prop(ptr, "active");
        if (!active)    {
            new_chord = create_chord_grid_on_lib(lib, column, row);
            render_each_chord(lib, ptr, new_chord, column, row);
            row = row + 100.0;
            
        }
        g_free(active);
        
        
        
    }
}

void 
load_lib_chord(GtabChordLib *lib, double x, double y)
{
    xmlNodePtr     ptr;
    gchar        *check_active;
    gchar        *char_x, *char_y, *char_text, *char_int;
    double         grid_x, grid_y;
    GtabChordBuilder     *gtab_dialog;
    GtabDoc             *current_doc;
    
    current_doc = (GtabDoc *)lib->parent->current_doc;
    
    gtab_dialog = create_chord_popup(current_doc);
    gtab_dialog->x = x;
    gtab_dialog->y = y;
    
    gtk_widget_show(gtab_dialog->dialog);
    create_grid(gtab_dialog);
    
    for (ptr = lib->selected_chord->children; ptr != NULL; ptr = ptr->next)    {
        if (xmlIsBlankNode(ptr) == 1) continue;
            
        check_active = get_prop(ptr, "active");
        if (!check_active)    {
            
            if (g_ascii_strcasecmp(ptr->name, "chord_text") == 0)    {
                char_x = get_prop(ptr, "x_create");
                char_y = get_prop(ptr, "y_create");
                grid_x = atof(char_x);
                grid_y = atof(char_y);
                g_free(char_x);
                g_free(char_y);
                
                char_text = get_prop(ptr, "text");
                
                create_chord_text(grid_x, grid_y, char_text, gtab_dialog);
                g_free(char_text);
            }
            if (g_ascii_strcasecmp(ptr->name, "chord_bar") == 0)    {
                char_x = get_prop(ptr, "x_create");
                char_y = get_prop(ptr, "y_create");
                grid_x = atof(char_x);
                grid_y = atof(char_y); 
                g_free(char_x);
                g_free(char_y);
                
                char_int = get_prop(ptr, "positions");
                create_chord_bar(grid_x, grid_y, atoi(char_int), gtab_dialog);
                g_free(char_int);
                
            }
            if (g_ascii_strcasecmp(ptr->name, "chord_name") == 0)    {
                char_text = get_prop(ptr, "name_text");
                gtk_entry_set_text(GTK_ENTRY(gtab_dialog->name), char_text);
                g_free(char_text);
            }
        }
        g_free(check_active);
    }
    xmlFreeNode(lib->selected_chord);
    
    lib->selected_chord = NULL;
    
    if (lib->highlights != NULL)    {
        gtk_object_destroy(GTK_OBJECT(lib->highlights));
        lib->highlights = NULL;
    }
    
}

static gchar* 
get_chord_name(xmlNodePtr chord_node)
{
    xmlNodePtr ptr;
    gchar *tmp_char = NULL;
    
    for (ptr = chord_node->children; ptr != NULL; ptr = ptr->next)    {
        
        if (xmlIsBlankNode(ptr) == 1) continue;
                            
        if (g_ascii_strcasecmp(ptr->name, "chord_name") == 0) {
            tmp_char = get_prop(ptr, "name_text");
        }
        
    }
    
    return (tmp_char);
}

/* Chord Lib Popup */

static void
on_chord_lib_popup_delete_activate     (GtkMenuItem     *menuitem,
                                        gpointer         *data)
{
    GtabChordLib *lib;
    
    lib = g_object_get_data(G_OBJECT(menuitem), GNOMEUIINFO_KEY_UIDATA);
    
    xmlSetProp(lib->selected_delete, "active", "false");
        
    if (lib->highlights)    {
        gtk_object_destroy(GTK_OBJECT(lib->highlights));
        lib->highlights = NULL;
    }
    
    if (lib->visible) {
        refresh_chord_canvas(lib);
    }
    
    lib->selected_delete = NULL;
    
    
    
}

static void
on_chord_lib_popup_deactivate            (GtkMenuShell    *menushell,
                                         GtabChordLib      *lib)
{
    if (lib->highlights) {
        gtk_object_destroy(GTK_OBJECT(lib->highlights));
        lib->highlights = NULL;
    }
    lib->parent->current_tool = prior_tool;
    lib->selected_chord_item = NULL;
    
}


static GtabChordLibPopup*
create_chord_lib_popup(GtabChordLib *lib)
{
    GtabChordLibPopup    *popup;
    GnomeUIInfo lib_right_click_popup_uiinfo[] =
    {
        {
            GNOME_APP_UI_ITEM, N_("_Delete"),
            N_("Delete chord from the library"),
            (gpointer) on_chord_lib_popup_delete_activate, lib, NULL,
            GNOME_APP_PIXMAP_STOCK, GTK_STOCK_CLOSE,
            0, (GdkModifierType) 0, NULL
        },
        GNOMEUIINFO_END
    };
        
    popup = g_new0(GtabChordLibPopup, 1);
    
    popup->menu = gtk_menu_new ();
  
    gnome_app_fill_menu(GTK_MENU_SHELL (popup->menu), lib_right_click_popup_uiinfo,
                       NULL, FALSE, 0);
    
    g_signal_connect (G_OBJECT(popup->menu), "deactivate",
                      G_CALLBACK(on_chord_lib_popup_deactivate),
                      lib);

    return popup;
}

/* public functions */

void
refresh_chord_canvas(GtabChordLib *lib)
{
    gint i;
    
    g_list_foreach(lib->obj_counter, destroy_chord_object, NULL);
    
    g_list_free(lib->obj_counter);
    lib->obj_counter = NULL;
    
    sort_lib(lib);
    
    render_chords(lib);
    
    if (lib->lib_doc) {
        i = xmlSaveFile(lib->filename, lib->lib_doc);
    }
}    

void
sort_lib(GtabChordLib *lib)
{
    xmlDocPtr     new_lib_doc;
    xmlNodePtr     sort1_node;
    xmlNodePtr     temp_node = NULL;
    xmlNodePtr     lowest_node = NULL;
    gchar        *check_active, *chord_name2, *chord_name;
    gint         total, i;
        
    new_lib_doc = xmlNewDoc("1.0");
    new_lib_doc->xmlRootNode = xmlNewDocNode(new_lib_doc, NULL, "chord_library", NULL);
    
    total = count_chords(lib);
    chord_name = g_strdup("~~~~");
    
    for (i = 0; i < total; i++) {
        sort1_node = lib->lib_doc->xmlRootNode->children;
        
        // pick out the lowest chord name
        
        while (sort1_node != NULL) {
            if (xmlIsBlankNode(sort1_node) == 1) {
                sort1_node = sort1_node->next;
                continue;
            }
            
            check_active = get_prop(sort1_node, "active");
            if (!check_active) {
                chord_name2 = get_chord_name(sort1_node);
                if (chord_name == NULL) {
                    chord_name = g_strdup("~~~~");
                }
                // fprintf(stderr, "name1: %s, name2: %s\n", chord_name, chord_name2);
                if (g_ascii_strcasecmp(chord_name, chord_name2) <= 0) {
                    sort1_node = sort1_node->next;
                }
                else {
                    
                    g_free(chord_name);    
                    
                    // temp_node = xmlCopyNode(sort1_node, TRUE);
                    chord_name = get_chord_name(sort1_node);
                    // get a placeholder so we can deactivate this one if it's
                    // the lowest.
                    lowest_node = sort1_node;
                    
                    // Back to the beginning
                    sort1_node = lib->lib_doc->xmlRootNode->children;
                }
                g_free(chord_name2);
            }
            else {
                sort1_node = sort1_node->next;
            }
            
            g_free(check_active);
        }

        // deactivate it and write it
        temp_node = xmlCopyNode(lowest_node, TRUE);
        xmlSetProp(lowest_node, "active", "false");
        temp_node = xmlAddChild(new_lib_doc->xmlRootNode, temp_node);
        
        g_free(chord_name);
        chord_name = NULL;
    }
    xmlFreeDoc(lib->lib_doc);        
    lib->lib_doc = new_lib_doc;
    
}

gboolean
load_chord_lib_file(GtabChordLib* lib, gchar* filename)
{
    /* returns TRUE if everything seems ok, FALSE otherwise */
    GConfClient    *client;
    GtkWidget        *btn_lib_chord;
    gint             test;
    gboolean         file_exists = FALSE;
    gchar            *lib_file;
    
    btn_lib_chord = lib->parent->btn_lib_chord;
    client = gconf_client_get_default();
    
    if (lib->lib_doc) xmlFreeDoc(lib->lib_doc);
        
    if (filename == NULL) {
        
        
        lib_file = gconf_client_get_string(client, GCONF_CHORD_LIB, NULL);
        if (g_strcasecmp(lib_file, "NONE") == 0) {
            if (filename != NULL) {
                test = new_chord_lib_file(lib, filename);
            }
            else {
                /* looks like this is a first run */
                /* We'll let the error message below tell the user what to do. */
            }
            
        }
        else {
            file_exists = g_file_test(lib_file,
                                G_FILE_TEST_EXISTS && G_FILE_TEST_IS_REGULAR);
            
            if (!file_exists) {
                gtab_warn(lib->parent, 
                    "Your default chord library cannot be found!\nYou should select another, or create a new one.");
                g_free(lib_file);
                return FALSE;
            }
            
        }
    }
    else {
        lib_file = g_strdup(filename);
        g_free(filename);
        file_exists = g_file_test(lib_file,
                            G_FILE_TEST_EXISTS && G_FILE_TEST_IS_REGULAR);
        if (!file_exists) {
            gtab_warn(lib->parent, "The requested chord library file cannot be found!");
            g_free(lib_file);
            return FALSE;
        } 
    }
    
    
    
    lib->lib_doc = xmlParseFile(lib_file);
    if (lib->lib_doc) {
        if (lib->visible) {
                
            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (btn_lib_chord), lib->visible);
            refresh_chord_canvas(lib);
        }
        else {
            sort_lib(lib);
        }
        gtk_widget_set_sensitive(btn_lib_chord, TRUE);
        gconf_client_set_string(client, GCONF_CHORD_LIB, lib_file, NULL);
        lib->filename = g_strdup(lib_file);
        g_free(lib_file);
        return TRUE;
    } 
    else {
        gtab_warn(lib->parent, "Failed to load chord library!\nIf you have never run Gnometab before, you should create a chord library.\nTry Edit->Preferences.");
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (btn_lib_chord), FALSE);
        gtk_widget_set_sensitive(btn_lib_chord, FALSE);
        g_free(lib_file);
        return FALSE;
    }
}

gint
new_chord_lib_file(GtabChordLib *lib, gchar *filename)
{    
    gboolean file_exists;
    gint test;
    
    file_exists = g_file_test(filename,    G_FILE_TEST_EXISTS);
    
    if (!file_exists) {
             
        lib->lib_doc = xmlNewDoc("1.0");
        lib->lib_doc->xmlRootNode = xmlNewDocNode(lib->lib_doc, NULL, "chord_library", NULL);
        test = xmlSaveFile(filename, lib->lib_doc);

        if (test) {
            lib->filename = g_strdup(filename);
            return TRUE;
        }
        else {
            gtab_warn(lib->parent, "Error creating chord library file!");
            xmlFreeDoc(lib->lib_doc);
            return FALSE;
        }
    }
    else {
        gtab_warn(lib->parent, "File already exists!");
        return FALSE;
    }
        
}

void
render_chord_lib_in_pane (GtabApp *app)
{
    gint    win_width, win_height;
    GtabChordLib     *lib;
    
    lib = (GtabChordLib *)app->chord_lib;
    
    lib->scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
    
    gtk_widget_show (lib->scrolledwindow);
    gtk_paned_pack2(GTK_PANED(app->paned_window), lib->scrolledwindow, TRUE, TRUE);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(lib->scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    gtk_window_get_size(GTK_WINDOW(app->gnometab), &win_width, &win_height);
    
    gtk_paned_set_position(GTK_PANED(app->paned_window), (win_width - 150));
    gtk_widget_push_colormap (gdk_rgb_get_colormap ());
    lib->lib_canvas = gnome_canvas_new ();
    gtk_widget_pop_colormap ();
    gtk_widget_show (GTK_WIDGET(lib->lib_canvas));
    gtk_container_add (GTK_CONTAINER (lib->scrolledwindow), GTK_WIDGET(lib->lib_canvas));
    lib->visible = TRUE;
    render_chords(lib);
}


GtabChordLib*
create_chord_lib(GtabApp *app) 
{
    GtabChordLib     *new_lib;

    new_lib = g_new0(GtabChordLib, 1);
    new_lib->visible = FALSE;
    new_lib->lib_doc = NULL;
    new_lib->selected_chord = NULL;
    /* this may be trouble... */
    new_lib->popup = create_chord_lib_popup(new_lib);
    
    new_lib->parent = app;
    
    return new_lib;
}

void
free_chord_lib(GtabChordLib *lib)
{
    if (lib->lib_doc) xmlFreeDoc(lib->lib_doc);
    if (lib->scrolledwindow) {    
        if (GTK_IS_WIDGET(lib->scrolledwindow)) {
            gtk_widget_destroy(lib->scrolledwindow);
        }
    }
    if (lib->obj_counter) {
        g_list_free(lib->obj_counter);
        lib->obj_counter = NULL;
    }
    if (lib->filename) g_free(lib->filename);
    lib->selected_chord = NULL;
    lib->selected_chord_item = NULL;
    if (GTK_IS_WIDGET(lib->popup->menu)) {
        gtk_widget_destroy(lib->popup->menu);
    }
    g_free(lib->popup);
    g_free(lib);
    
}
    


