#ifndef SCREEM_PAGE_H
#define SCREEM_PAGE_H

#include <glib-object.h>
#include <gtksourceview/gtksourcebuffer.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtktreemodel.h>

#include <libxml/tree.h>

#include "screem-dtd.h"

#define SCREEM_TYPE_PAGE            (screem_page_get_type ())
#define SCREEM_PAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCREEM_TYPE_PAGE, ScreemPage))
#define SCREEM_PAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SCREEM_TYPE_PAGE, ScreemPageClass))
#define SCREEM_IS_PAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCREEM_TYPE_PAGE))

typedef struct ScreemPagePrivate ScreemPagePrivate;

#define BOOKMARK_MARKER "Screem::bookmark"
#define SCREEM_INVALID_MARKUP_TAG "Screem::invalid_markup"

typedef struct ScreemPageBookMark {
	gint line_number;
	GString *name;
	gpointer iter;
	GtkSourceMarker *marker;
} ScreemPageBookMark;

typedef enum {
	SCREEM_PAGE_MODEL_NAME,
	SCREEM_PAGE_MODEL_TEXT,
	SCREEM_PAGE_MODEL_START,
	SCREEM_PAGE_MODEL_END,
	SCREEM_PAGE_MODEL_VALID,
	SCREEM_PAGE_MODEL_ICON,
	SCREEM_PAGE_MODEL_NODE,
	SCREEM_PAGE_MODEL_MAX
} ScreemPageModelCols;


typedef struct  {
	GtkSourceBuffer parent;

	ScreemPagePrivate *private;
} ScreemPage;

typedef struct {
        GtkSourceBufferClass parent_class;

	/* emited just before the page is saved, this enables
	 * listeners to modify the page before it is actually
	 * saved, to update the last modified time for example */
	void (*saving)( ScreemPage *page );
	
	/* emited when the page is saved, this is so we can update
		other pages if this is a template etc. */
	void (*saved)( ScreemPage *page );

	/* emitted from the ScreemPageModel when it begins
	 * building */
	void (*building)( ScreemPage *page );
	/* emitted from the ScreemPageModel when it is finished
	 * building */
	void (*built)( ScreemPage *page );
	
} ScreemPageClass;

ScreemPage *screem_page_new( GObject *application );
GType screem_page_get_type( void );

gboolean screem_page_is_loaded( ScreemPage *page );

gboolean screem_page_is_open( ScreemPage *page );
void screem_page_set_open( ScreemPage *page, gboolean opened );

void screem_page_set_lang( ScreemPage *page );

void screem_page_set_pathname( ScreemPage *page, const gchar *path );
const gchar *screem_page_get_pathname( ScreemPage *page );

gchar *screem_page_get_short_name( ScreemPage *page );
gchar *screem_page_get_title_name( ScreemPage *page );

void screem_page_set_mime_type( ScreemPage *page, const gchar *mime_type );
const gchar *screem_page_get_mime_type( ScreemPage *page );

gchar *screem_page_get_charset( ScreemPage *page );

void screem_page_set_data( ScreemPage *page, const gchar *data );
gchar *screem_page_get_data( ScreemPage *page );

void screem_page_set_changed( ScreemPage *page, gboolean flag );
gboolean screem_page_get_changed( ScreemPage *page );

gboolean screem_page_load( ScreemPage *page, GError **error );
gboolean screem_page_revert( ScreemPage *page, GError **error  );
gboolean screem_page_save( ScreemPage *page, GError **error );
void screem_page_unload( ScreemPage *page );
glong screem_page_get_seconds_since_last_save_or_load( ScreemPage *page );

gboolean screem_page_is_file_page( const gchar *path );
gboolean screem_page_is_mime_type_page( const gchar *mime_type );

gboolean screem_page_get_modified( ScreemPage *page );

/* needed for row activate callback on bookmarks dialog */
GtkListStore *screem_page_get_bookmark_model( ScreemPage *page );

void screem_page_add_bookmark( ScreemPage *page, gint line, const gchar *name );
void screem_page_remove_bookmark( ScreemPage *page, const gchar *name );
gint screem_page_get_bookmark( ScreemPage *page, const gchar *name );

gboolean screem_page_is_feature( ScreemPage *page, const gchar *feature );
gboolean screem_page_is_dynamic( ScreemPage *page );
gboolean screem_page_is_markup( ScreemPage *page );

gchar *screem_page_template_path( ScreemPage *page );
gboolean screem_page_is_template( ScreemPage *page, 
		const gchar *base,
		gchar **tag, gchar **path, GSList **blocks );

GtkTreeModel *screem_page_get_model( ScreemPage *page );
void screem_page_build_model( ScreemPage *page );
void screem_page_ensure_model_built( ScreemPage *page );
gboolean screem_page_select_context( ScreemPage *page,
				  guint pos,
				  guint *start, guint *end,
				  gboolean select_text );
gboolean screem_page_select_parent_context( ScreemPage *page,
		guint pos,
		guint *start, guint *end,
		gboolean select_text );
gboolean screem_page_select_content( ScreemPage *page,
				  guint pos,
				  guint *start, guint *end,
				  gboolean select_text );
gchar *screem_page_query_context( ScreemPage *page,
		guint pos, gboolean query_text,
		gboolean build, 
		guint *depth, guint *start, guint *end,
		xmlNodePtr *node );

ScreemDTD *screem_page_get_dtd( ScreemPage *page );

gboolean screem_page_is_xml( ScreemPage *page );

#endif
