/*  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 <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
#include <gconf/gconf-client.h>

// useful constants

#define TOOL_POINTER        0
#define TOOL_NUM            1
#define TOOL_BEND           2
#define TOOL_BAR            3
#define TOOL_SLUR           4
#define TOOL_MEASURE        5
#define TOOL_LEGATO         6
#define TOOL_STRUM          7
#define TOOL_RHYTHM         8
#define TOOL_CHORD          9
#define TOOL_TIMESIG        10
#define TOOL_REPEAT_OPEN    11
#define TOOL_REPEAT_CLOSE   12
#define TOOL_COMMENT        13
#define TOOL_REST           14
#define TOOL_LIB_CHORD      15
#define TOOL_TEXT_ENTRY     16

#define SLUR_HAMMER         1
#define SLUR_PULLOFF        2
#define SLUR_SLIDE          3
#define SLUR_TRILL          4

// GConf stuff

#define GCONF_PATH                      "/apps/gnometab/general"
#define GCONF_CHORD_LIB                 "/apps/gnometab/general/chord_lib"
#define GCONF_CHORD_LIB_VISIBLE         "/apps/gnometab/general/chord_lib_is_visible"
#define GCONF_CHORDS_ABOVE_STAFF        "/apps/gnometab/general/chords_above_staff"
#define GCONF_TAB_FONT                  "/apps/gnometab/general/tab_font"
#define GCONF_TAB_FONT_LARGE            "/apps/gnometab/general/tab_font_large"
#define GCONF_TAB_FONT_SMALL            "/apps/gnometab/general/tab_font_small"
#define GCONF_TAB_FONT_TINY             "/apps/gnometab/general/tab_font_tiny"
#define GCONF_CHRD_BLDR_FONT            "/apps/gnometab/general/chrd_bldr_font"
#define GCONF_CHRD_BLDR_FONT_SMALL      "/apps/gnometab/general/chrd_bldr_font_small"
#define GCONF_WINDOWHEIGHT              "/apps/gnometab/layout/windowheight"
#define GCONF_WINDOWWIDTH               "/apps/gnometab/layout/windowwidth"
#define GCONF_ZOOMLEVEL                 "/apps/gnometab/layout/zoomlevel"
#define GCONF_HISTORY_N                 "/apps/gnometab/general/history/n"
#define GCONF_HISTORY_FILES             "/apps/gnometab/general/history/files"

typedef struct {
    gboolean active;
    gint value;
    gboolean dotted;
} Rhythm_element;
    
typedef struct {
    Rhythm_element pos1;
    Rhythm_element pos2;
    Rhythm_element pos3;
    Rhythm_element pos4;
}    Tab_Rhythm;

typedef struct _GtabApp         GtabApp;
    
struct _GtabApp {
    GtkWidget           *gnometab;
    GtkWidget           *toolbox;
    GtkWidget           *toolmenu;
    GtkWidget           *btn_ptr;
    GtkWidget           *btn_num;
    GtkWidget           *btn_bend;
    GtkWidget           *btn_bar;
    GtkWidget           *btn_slur;
    GtkWidget           *btn_measure;
    GtkWidget           *btn_legato;
    GtkWidget           *btn_strum;
    GtkWidget           *btn_rhythm;
    GtkWidget           *btn_rest;
    GtkWidget           *btn_timsig;
    GtkWidget           *btn_repeat_open;
    GtkWidget           *btn_repeat_close;
    GtkWidget           *btn_comment;
    GtkWidget           *btn_chord;
    GtkWidget           *btn_lib_chord;
    GtkWidget           *paned_window;
    GtkWidget           *appbar;
    gpointer            chord_lib;
    gpointer            current_doc;
    GList               *clipboard_objs;
    xmlDocPtr           clipboard_doc;
    gboolean            clipboard_multi;
    double              clipboard_multi_start_x;
    double              clipboard_multi_start_y;
    gint                current_tool;
    double              zoom_level;
    gchar               *tab_font;
    gchar               *tab_font_large;
    gchar               *tab_font_small;
    gchar               *tab_font_tiny;
    gchar               *chrd_bldr_font;
    gchar               *chrd_bldr_font_small;
    gint                history_n;
    GSList              *history_files;
};

typedef struct _GtabDocPopup    GtabDocPopup;
    
struct _GtabDocPopup {
    GtkWidget       *menu;
    double          x;
    double          y;
};

typedef struct _GtabDoc     GtabDoc;
    
struct _GtabDoc {
    GtabApp             *parent;
    xmlDocPtr           loaded_doc;
    xmlDocPtr           current_doc;
    GtkWidget           *scrolledwindow;
    GtabDocPopup        *popup;
    GnomeCanvas         *tab_canvas;
    GnomeCanvasGroup    *canvas_group;
    GnomeCanvasGroup    *staffs;
    GnomeCanvasGroup    *staff_objects[6];
    GnomeCanvasGroup    *properties;
    GnomeCanvasGroup    *highlights;
    GnomeCanvasItem     *background;
    GList               *obj_counter;
    xmlNodePtr          staff_nodes[6];
    xmlNodePtr          doc_props;
    gchar*              filename;
    gchar               current_page[3];
    gboolean            changed;
    gboolean            block_title_updates;
};

typedef struct _GtabChordLibPopup    GtabChordLibPopup;

struct _GtabChordLibPopup {
    GtkWidget           *menu;
    double              x;
    double              y;
};

typedef struct _GtabChordLib         GtabChordLib;
    
struct _GtabChordLib {
    GtabApp             *parent;
    xmlDocPtr           lib_doc;
    GtkWidget           *scrolledwindow;
    GtkWidget           *lib_canvas;
    GnomeCanvasGroup    *lib_group;
    GnomeCanvasGroup    *highlights;
    GList               *obj_counter;
    gchar               *filename;
    gboolean            visible;
    xmlNodePtr          selected_chord;
    GnomeCanvasItem     *selected_chord_item;
    xmlNodePtr          selected_delete;
    GtabChordLibPopup   *popup;
};

GnomeCanvasItem *cvs_num_entry;
gint current_staff;
gint popup_holder_x2;
gint popup_holder_y2;
gint prior_tool;
gint current_chord_tool;
gint staff_select;
gboolean num_entry_bool;
gboolean chords_above_staff;
gchar return_val[12];

void 
create_staff(GtabDoc *tab_doc);

gint
staff_event(GnomeCanvasItem *staff, GdkEventButton *event, GtabDoc *tab_doc);

gint 
staff_object_event(GnomeCanvasItem *staff_object, 
                    GdkEvent *event, GtabDoc *tab_doc);

void
load_tab_file(GtabDoc *tab_doc);

void
refresh_canvas(GtabDoc *tab_doc, gboolean newfile);

void
find_staff(double y);

void
init_current_doc(GtabDoc *tab_doc);

gchar*
int_to_char(gint x);

gchar* 
float_to_char(double x);

void
set_pagenum(GtabDoc *tab_doc, gint pagenum);

void
render_objects(GtabDoc *tab_doc, xmlNodePtr node);

void
render_current_page(GtabDoc *tab_doc, GtkProgressBar *progress);

gint
count_page_objects(xmlNodePtr page_node);

void 
file_pre_load(GtabDoc *tab_doc);

void
set_title(GtabDoc *tab_doc);

gint
save_tab_file(GtabDoc *tab_doc);

void 
sync_loaded_doc(GtabDoc *tab_doc);

void
init_loaded_doc(GtabDoc *tab_doc);

void
switch_page(GtabDoc *tab_doc, GtkProgressBar *progress, gboolean up);

void
highlight_object(GnomeCanvasItem *object, GnomeCanvasGroup *group);

gint
background_event(GnomeCanvasItem *background, GdkEvent *event, GtabDoc *tab_doc);

void 
bulk_select(GtabDoc *tab_doc, GnomeCanvasItem *select_rec);

double
clipboard_multi_find_y_offset(gint staff_num);

gint
find_object_staff(xmlNodePtr obj_node);

gchar*
get_prop(xmlNodePtr node, const char* prop_name);

void
destroy_tab_object_and_node_with_cut(gpointer tab_object, gpointer tab_doc);

void
destroy_tab_object_and_node(gpointer tab_object, gpointer tab_doc);

void
load_chord_lib (GtabApp *app, gchar *filename, gboolean visible);

void 
refresh_fonts(GtabApp *app);

void 
take_care_of_business(GtabApp *app);
