/*  Application main window
 *
 *  Demonstrates a typical application window, with menubar, toolbar, statusbar.
 */

#include "demowindow.h"
#include <inti/gtk/scrolledwindow.h>
#include <inti/gtk/accelgroup.h>
#include <inti/gtk/itemfactory.h>
#include <inti/gtk/iconfactory.h>
#include <inti/gtk/table.h>
#include <inti/gtk/menubar.h>
#include <inti/gtk/stock.h>
#include <inti/gtk/toolbar.h>
#include <inti/gtk/textview.h>
#include <inti/gtk/statusbar.h>
#include <inti/gtk/dialog.h>
#include <inti/gtk/messagedialog.h>
#include <inti/gdk-pixbuf/pixbuf.h>
#include <gtk/gtkstock.h>

using namespace Inti;

class AppWindow : public Gtk::Window
{
	static Pointer<Gtk::IconFactory> icon_factory;
	Pointer<Gtk::ItemFactory> item_factory;

	Gtk::Statusbar *statusbar;
	Gtk::TextBuffer *buffer;

	void update_statusbar();
	void mark_set(const GtkTextIter*, GtkTextMark*);

public:
	AppWindow();
	~AppWindow();

	static void register_stock_icons();

	void menu_item_selected(const char *parent, const char *item);

	void on_file_new();
	void on_file_open();
	void on_file_save();
	void on_file_save_as();
	void on_file_quit();

	void on_color_red();
	void on_color_green();
	void on_color_blue();

	void on_shape_square();
	void on_shape_rectangle();
	void on_shape_oval();

	void on_help_about();

	void on_tool_item();

	DECLARE_ITEM_FACTORY_MAP(AppWindow)
};
//!

Pointer<Gtk::IconFactory> AppWindow::icon_factory;

AppWindow::AppWindow()
{
	set_title("Application Window");
	set_default_size(200, 200);
	Gtk::Table *table = new Gtk::Table(1, 4);
	add(*table);

	// Register our stock items
	register_stock_icons();

	// Create the menubar
	Pointer<Gtk::AccelGroup> accel_group = new Gtk::AccelGroup;
	add_accel_group(accel_group);
 	item_factory = new Gtk::ItemFactory(GTK_TYPE_MENU_BAR, "<main>", accel_group);

	// Create menu items
	item_factory->create_items(*this);
	Gtk::MenuBar *menu = item_factory->menu_bar();
	table->attach(*menu, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0);

	// Create the toolbar
	Gtk::Toolbar *toolbar = new Gtk::Toolbar;
	toolbar->append_stock(GTK_STOCK_OPEN, slot(this, &AppWindow::on_tool_item), "This is a demo button with an 'open' icon");
	toolbar->append_stock(GTK_STOCK_QUIT, slot(this, &AppWindow::on_tool_item), "This is a demo button with an 'quit' icon");
	toolbar->append_space();                 
	toolbar->append_stock("demo-gtk-logo", slot(this, &AppWindow::on_tool_item), "This is a demo button with an 'gtk' icon");
	table->attach(*toolbar, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0);
	
	// Create document
	Gtk::ScrolledWindow *scrolled_window = new Gtk::ScrolledWindow;
	scrolled_window->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	scrolled_window->set_shadow_type(Gtk::SHADOW_IN);
	table->attach(*scrolled_window, 0, 1, 2, 3);
	Gtk::TextView *contents = new Gtk::TextView;
	scrolled_window->add(*contents); 

	// Create statusbar
	statusbar = new Gtk::Statusbar;
	table->attach(*statusbar, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, 0);
	
	// Show text widget info in the statusbar
	buffer = contents->get_buffer();
	buffer->sig_changed().connect(slot(this, &AppWindow::update_statusbar));
	buffer->sig_mark_set().connect(slot(this, &AppWindow::mark_set));
	update_statusbar();

	show_all();
}

AppWindow::~AppWindow()
{
}

void
AppWindow::menu_item_selected(const char *parent, const char *item)
{
	Gtk::MessageDialog *dialog = new Gtk::MessageDialog(Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, this);
	dialog->set_message("You selected or toggled the \"%s\" menu item: \"%s\"", parent, item);
	if (dialog->run())
		dialog->dispose();
}

void
AppWindow::update_statusbar()
{
	statusbar->pop(); // clears any previous message
	int count = buffer->get_char_count();
	Gtk::TextIter iter = buffer->get_iter_at_mark(*buffer->get_insert());
	int row = iter.get_line();
	int col = iter.get_line_offset();
	String msg;
	msg.format("Cursor at row %d column %d - %d chars in document", row, col, count);
	statusbar->push(msg);
}

void
AppWindow::mark_set(const GtkTextIter*, GtkTextMark*)
{
	update_statusbar();
}

void
AppWindow::register_stock_icons()
{
	// Register our custom toolbar icons, so they can be themed.
	Gtk::Stock::add("demo-gtk-logo", "_GTK!");

	// Add our custom icon factory to the list of defaults
	icon_factory = new Gtk::IconFactory;
	icon_factory->add_default();

	// DemoWindow::find_file() looks in the the current directory first, then looks in the location where the file is installed.
	Pointer<Gdk::Pixbuf> pixbuf;
	String filename = DemoWindow::find_file("gtk-logo-rgb.gif");
	if (!filename.null())
	pixbuf = new Gdk::Pixbuf(filename);

	// Register icon to accompany stock item
	if (pixbuf)
	{
		Pointer<Gdk::Pixbuf> transparent = pixbuf->add_alpha(true, 0xff, 0xff, 0xff);
		Pointer<Gtk::IconSet> icon_set = new Gtk::IconSet(*transparent);
		icon_factory->add("demo-gtk-logo", *icon_set);
	}
	else
		g_warning ("failed to load GTK logo for toolbar");
}

void
AppWindow::on_file_new()
{
	menu_item_selected("File", "New");
}

void
AppWindow::on_file_open()
{
	menu_item_selected("File", "Open");
}

void
AppWindow::on_file_save()
{
	menu_item_selected("File", "Save");
}

void
AppWindow::on_file_save_as()
{
	menu_item_selected("File", "Save As");
}

void
AppWindow::on_file_quit()
{
	menu_item_selected("File", "Quit");
}

void
AppWindow::on_color_red()
{
	menu_item_selected("Color", "Red");
}

void
AppWindow::on_color_green()
{
	menu_item_selected("Color", "Green");
}

void
AppWindow::on_color_blue()
{
	menu_item_selected("Color", "Blue");
}

void
AppWindow::on_shape_square()
{
	menu_item_selected("Shape", "Square");
}

void
AppWindow::on_shape_rectangle()
{
	menu_item_selected("Shape", "Rectangle");
}

void
AppWindow::on_shape_oval()
{
	menu_item_selected("Shape", "Oval");
}

void
AppWindow::on_help_about()
{
	menu_item_selected("Help", "About");
}

void
AppWindow::on_tool_item()
{
	Gtk::MessageDialog *dialog = new Gtk::MessageDialog(Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, this);
	dialog->set_message("You selected a toolbar button");
	if (dialog->run())
		dialog->dispose();
}

BEGIN_ITEM_FACTORY_MAP(AppWindow)
	IFM_BRANCH("/_File"),
	IFM_STOCK_ITEM("/File/_New", "<Ctl>N", on_file_new, GTK_STOCK_NEW),
	IFM_STOCK_ITEM("/File/_Open", "<Ctl>0", on_file_open, GTK_STOCK_OPEN),
	IFM_STOCK_ITEM("/File/_Save", "<Ctl>S", on_file_save, GTK_STOCK_SAVE),
	IFM_STOCK_ITEM("/File/Save As", 0, on_file_save_as, GTK_STOCK_SAVE),
	IFM_SEPARATOR("/File/Separator"),
	IFM_STOCK_ITEM("/File/Quit", "<Ctl>Q", on_file_quit, GTK_STOCK_QUIT),
	
	IFM_BRANCH("/_Preferences"),
	IFM_BRANCH("/_Preferences/_Color"),
	IFM_RADIO_ITEM("/_Preferences/Color/_Red", 0, on_color_red),
	IFM_RADIO_ITEM_LINK("/_Preferences/Color/_Green", on_color_green, "/Preferences/Color/Red"),
	IFM_RADIO_ITEM_LINK("/_Preferences/Color/_Blue", on_color_blue, "/Preferences/Color/Red"),

	IFM_BRANCH("/_Preferences/_Shape"),
	IFM_RADIO_ITEM("/_Preferences/Shape/_Square", 0, on_shape_square),
	IFM_RADIO_ITEM_LINK("/_Preferences/Shape/_Rectangle", on_shape_rectangle, "/Preferences/Shape/Square"),
	IFM_RADIO_ITEM_LINK("/_Preferences/Shape/_Oval", on_shape_oval, "/Preferences/Shape/Rectangle"),

	// If you wanted this to be right justified you would use IFM_LAST_BRANCH, not IFM_BRANCH.
	IFM_BRANCH("/_Help"),
	IFM_ITEM("/Help/_About", 0, on_help_about),
END_ITEM_FACTORY_MAP

Gtk::Window*
do_appwindow()
{
	static Gtk::Window *window = 0;

	if (!window)
		window = new AppWindow;
	else
	{
		window->dispose();
		window = 0;
	}
	return window;
}

