// 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. 

// Copyright 2003 Liam Girdwood  

#include "config.h"
#include "nova_app.hh"
#include "vsky_druid.hh"
#include "todo_dialog.hh"
#include "import.hh"
#include "astro_object.hh"
#include "library.hh"
#include "file.hh"
#include <gconfmm/init.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/fileselection.h>
#include <iostream>
#include <string>
#include <vector>

#define GCONF_NOVA_DIR	"/apps/nova"
#define GCONF_SIZE_DIR	"/apps/nova/size"
#define GCONF_VSKY_DIR	"/apps/nova/vsky"

#define GCONF_SIZE_WIDTH	"/apps/nova/size/width"
#define GCONF_SIZE_HEIGHT	"/apps/nova/size/height"
#define GCONF_VSKY_LAST		"/apps/nova/vsky/vsky"

namespace GUI
{

/*! \fn NovaApp::NovaApp ()
* \todo attach resize signal handler
*
* Nova application constructor.
* Sets up app properties and loads last session.
*/
NovaApp::NovaApp (): Gtk::Window(Gtk::WINDOW_TOPLEVEL)
{  	
	// set up app properties
	set_border_width(2);
	set_modal(false);
	property_window_position().set_value(Gtk::WIN_POS_NONE);
	set_resizable(true);
	
	// retreive last session
	if (!load_session()) 
		std::cerr << "could not load last session " << std::endl;

	// install app features
	install_appbar();
	install_about();
	install_menus();
	install_toolbar();
	install_contents();
	install_logo();
	add(m_app);
	show_all();
	// default signal handlers
	// need a resize
}

/*! \fn NovaApp::~NovaApp ()
* \todo save any unsaved data
*
* Nova destructor. Quit Nova, but save session 
* and check for modified data first.
*/
NovaApp::~NovaApp ()
{
	// save session
	m_width = get_width();
	m_height = get_height();
	
	if(!save_session())
		std::cerr << "could not save last session" << std::endl;
	delete m_about;
	
	// is there any unsaved data
}

/*! \fn bool NovaApp::load_session()
*
* Load GConf session information
*/
bool NovaApp::load_session()
{
	Gnome::Conf::init();

	m_str_main_dir = GCONF_NOVA_DIR;
	m_str_size_dir = GCONF_SIZE_DIR;
	m_str_vsky_dir = GCONF_VSKY_DIR;
	
	// retreive last session
	m_ref_client = Gnome::Conf::Client::get_default_client();
	if (m_ref_client) {
		if (m_ref_client->dir_exists(m_str_main_dir)) {
			try {
				// get app window size
				m_width = m_ref_client->get_int(GCONF_SIZE_WIDTH);
				m_height = m_ref_client->get_int(GCONF_SIZE_HEIGHT);
				set_size_request (m_width, m_height);
				
			} catch(const Glib::Error& ex) {
    			std::cerr << "error loading session info: " << ex.what() << std::endl;
			}
			// get last sky view
			return true;
		} else {
			try {
				// run for the first time, so:-
				// set app defaults and create session dirs
				maximize();
				m_width = 800;
				m_height = 600;
				
				m_ref_client->add_dir(m_str_main_dir);
				m_ref_client->add_dir(m_str_size_dir);
				m_ref_client->add_dir(m_str_vsky_dir);
				
				m_ref_client->set(GCONF_SIZE_WIDTH,  m_width);
				m_ref_client->set(GCONF_SIZE_HEIGHT, m_height);
				m_ref_client->set(GCONF_VSKY_LAST, 0);
			} catch(const Glib::Error& ex) {
    			std::cerr << "error creating session info: " << ex.what() << std::endl;
			}
		}
	}
	return false;
}

/*! \fn bool NovaApp::save_session()
*
* Save GConf session data
*/
bool NovaApp::save_session()
{
	m_ref_client = Gnome::Conf::Client::get_default_client();
	if (m_ref_client)
	{
		if (m_ref_client->dir_exists(m_str_main_dir)) {
			try {
				// save size
				m_ref_client->set(GCONF_SIZE_WIDTH,  m_width);
				m_ref_client->set(GCONF_SIZE_HEIGHT, m_height);
				
				// save last sky
				
				return true;
			} 
			catch(const Glib::Error& ex) {
    			std::cerr << "error saving session info: " << ex.what() << std::endl;
			}
		}
	}
	return false;
}

/*! \fn void NovaApp::get_pixmap_file (std::string file, std::string path)
*
* Get pixmap filenames.
*/
void NovaApp::get_pixmap_file (std::string file, std::string path)
{
	path = NOVA_PIXMAP_DIR;
	path += file;
}

/*! \fn void NovaApp::install_logo ()
* \todo broken
*
* Display the nova logo when there are no files open
*/
void NovaApp::install_logo ()
{
	std::string path;
	
	get_pixmap_file ("/nova_logo.png", path);
	Gtk::Image logo(path);
	m_nova_book.append_page (logo, "test");
	m_nova_book.set_current_page(0);
}

/*! \fn void NovaApp::install_contents ()
* 
* Add the MDI view to the Nova app.
*/
void NovaApp::install_contents ()
{
	m_nova_book.set_show_border(true);
	m_nova_book.set_show_tabs(false);
	m_nova_book.set_border_width(3);
	
	m_app.pack_start(m_nova_book, Gtk::PACK_EXPAND_WIDGET, 0);
}

/*! \fn void NovaApp::install_appbar ()
*
* Install the Nova appbar
*/
void NovaApp::install_appbar ()
{	
}

/*! \fn void NovaApp::install_about ()
* \todo fix logo
* 
* Create and install the Nova about box.
*/
void NovaApp::install_about ()
{
	const char * const nova_authors[] = {
		"Liam Girdwood", 
		"Juan Carlos Remis", 
		"Fausto Manenti", 
		0
	};
	
	const char * const nova_documenters[] = {
		"I think we need some of this.", 
		0
	};
	
	Glib::ustring nova_translator = "Babelfish ??? Only Joking";
	//Glib::RefPtr<Gdk::Pixbuf> nova_logo = Gdk::Pixbuf::create_from_file("nova_logo.png");
	
	m_about = new Gnome::UI::About(PACKAGE, VERSION, "Copyright 2003\n",
		 nova_authors, nova_documenters, "Developer Version !", nova_translator);//, nova_logo));
}

/*! \fn void NovaApp::install_toolbar ()
* 
* Install Nova toolbar
*/
void NovaApp::install_toolbar ()
{
	// use the helpers
	using namespace Gtk::Toolbar_Helpers;
	
	// toolbar images
	Gtk::Image * image_zoom_in = Gtk::manage (new Gtk::Image (Gtk::Stock::ZOOM_IN, Gtk::IconSize(2)));
	Gtk::Image * image_zoom_out = Gtk::manage (new Gtk::Image (Gtk::Stock::ZOOM_OUT, Gtk::IconSize(2)));
	Gtk::Image * image_proj = Gtk::manage (new Gtk::Image (Gtk::Stock::CONVERT, Gtk::IconSize(2)));

	// create toolbar items
	ButtonElem * m_tb_zoom_in = new ButtonElem(*image_zoom_in, slot (*this, &NovaApp::on_zoom_in_button_clicked),"Zoom In", "");
	ButtonElem * m_tb_zoom_out = new ButtonElem(*image_zoom_out, slot (*this, &NovaApp::on_zoom_out_button_clicked),"Zoom Out", "");
	ButtonElem * m_tb_proj = new ButtonElem(*image_proj, slot (*this, &NovaApp::on_change_proj),"Change Sky Projection", "");
	
	//m_toolbar.append_item ("", "Zoom In", "", *image_zoom_in, slot (*this, &NovaApp::on_zoom_in_button_clicked));
	// build toolbar
	m_toolbar.tools().push_back (*m_tb_zoom_in);
	m_toolbar.tools().push_back (*m_tb_zoom_out);
	m_toolbar.tools().push_back (*m_tb_proj);
	m_toolbar.tools().push_back (Space());
	
	m_toolbar.set_toolbar_style(Gtk::TOOLBAR_ICONS);
	m_app.pack_start(m_toolbar, Gtk::PACK_SHRINK, 0);
}


/*! \fn void NovaApp::create_menu_file ()
*
* Create an install the file menu
*/
void NovaApp::create_menu_file ()
{
	// activate the helpers for easy menu setup.
	using namespace Gtk::Menu_Helpers;
	
	Gtk::Menu * file_new_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_file_new = file_new_menu->items();
	Gtk::Menu *file_menu = Gtk::manage (new Gtk::Menu());
	MenuList & list_file = file_menu->items();

	// file new
	MenuElem new_vsky("Virtual Sky...", slot(*this, &NovaApp::on_new_virtual_sky_activate));
	MenuElem new_obs("Observatory...", slot(*this, &NovaApp::on_new_observatory_activate));
	MenuElem new_tlist("Target List...", slot(*this, &NovaApp::on_new_target_list_activate));
	MenuElem new_ephem("Ephemeris...", slot(*this, &NovaApp::on_new_ephemeris_activate));
	list_file_new.push_back (new_vsky);
	list_file_new.push_back (new_obs);
	list_file_new.push_back (new_tlist);
	list_file_new.push_back (new_ephem);
	
	// file
	StockMenuElem file_new(Gtk::Stock::NEW, *file_new_menu);
	StockMenuElem file_open(Gtk::Stock::OPEN, slot(*this, &NovaApp::on_open_activate));
	StockMenuElem file_save(Gtk::Stock::SAVE, slot(*this, &NovaApp::on_save_activate));
	StockMenuElem file_save_as(Gtk::Stock::SAVE_AS, slot(*this, &NovaApp::on_save_as_activate));
	MenuElem file_import("Import...", slot(*this, &NovaApp::on_import_activate));
	StockMenuElem file_print(Gtk::Stock::PRINT, slot(*this, &NovaApp::on_print_activate));
	StockMenuElem file_close(Gtk::Stock::CLOSE, slot(*this, &NovaApp::on_close_activate));
	StockMenuElem file_exit(Gtk::Stock::QUIT, slot(*this, &NovaApp::on_quit_activate));

	// file menu items
	list_file.push_back (file_new);
	list_file.push_back (file_open);
	list_file.push_back (file_save);
	list_file.push_back (file_save_as);
	list_file.push_back (SeparatorElem());
	list_file.push_back (file_import);
	list_file.push_back (SeparatorElem());
	list_file.push_back (file_print);
	list_file.push_back (SeparatorElem());
	list_file.push_back (file_close);
	list_file.push_back (SeparatorElem());
	list_file.push_back (file_exit);
	
	// get menuitem refs
	m_file_new_vsky = new_vsky.get_child();
	m_file_new_obs = new_obs.get_child();
	m_file_new_tlist = new_tlist.get_child();
	m_file_new_ephemeris = new_ephem.get_child();
	m_file_save = file_save.get_child();
	m_file_save_as = file_save_as.get_child();
	m_file_import = file_import.get_child();
	m_file_print = file_print.get_child();
	m_file_close = file_close.get_child();
	
	// set default sensitivity	
	m_file_new_obs->set_sensitive(false);
	m_file_new_tlist->set_sensitive(false);
	m_file_new_ephemeris->set_sensitive(false);
	m_file_save->set_sensitive(false);
	m_file_save_as->set_sensitive(false);
	m_file_import->set_sensitive(false);
	m_file_print->set_sensitive(false);
	m_file_close->set_sensitive(false);

	// add menus to menubar
	m_menubar.items().push_front(MenuElem("_File",AccelKey("<control>f"),*file_menu));	
}

/*! \fn void NovaApp::create_menu_sky ()
*
* Create and install sky menu
*/
void NovaApp::create_menu_sky ()
{
	// activate the helpers for easy menu setup.
	using namespace Gtk::Menu_Helpers;
	
	// sky view near submenu
	Gtk::Menu * sky_view_near_menu = Gtk::manage (new Gtk::Menu());
	MenuList & list_sky_near = sky_view_near_menu->items();
	MenuElem view_moon("Moon", slot(*this, &NovaApp::on_sky_view_moon_activate));
	MenuElem view_mercury("Mercury", slot(*this, &NovaApp::on_sky_view_mercury_activate));
	MenuElem view_venus("Venus", slot(*this, &NovaApp::on_sky_view_venus_activate));
	MenuElem view_mars("Mars", slot(*this, &NovaApp::on_sky_view_mars_activate));
	MenuElem view_jupiter("Jupiter", slot(*this, &NovaApp::on_sky_view_jupiter_activate));
	MenuElem view_saturn("Saturn", slot(*this, &NovaApp::on_sky_view_saturn_activate));
	MenuElem view_uranus("Uranus", slot(*this, &NovaApp::on_sky_view_uranus_activate));
	MenuElem view_neptune("Neptune", slot(*this, &NovaApp::on_sky_view_neptune_activate));
	MenuElem view_pluto("Pluto", slot(*this, &NovaApp::on_sky_view_pluto_activate));
	MenuElem view_asteroids("Asteroids", slot(*this, &NovaApp::on_sky_view_asteroids_activate));
	MenuElem view_comets("Comets", slot(*this, &NovaApp::on_sky_view_comets_activate));
	MenuElem view_sun("Sun", slot(*this, &NovaApp::on_sky_view_sun_activate));
	list_sky_near.push_back (view_moon);
	list_sky_near.push_back (view_mercury);
	list_sky_near.push_back (view_venus);
	list_sky_near.push_back (view_mars);
	list_sky_near.push_back (view_jupiter);
	list_sky_near.push_back (view_saturn);
	list_sky_near.push_back (view_uranus);
	list_sky_near.push_back (view_neptune);
	list_sky_near.push_back (view_pluto);
	list_sky_near.push_back (SeparatorElem());
	list_sky_near.push_back (view_asteroids);
	list_sky_near.push_back (view_comets);
	list_sky_near.push_back (SeparatorElem());
	list_sky_near.push_back (view_sun);
	
	// sky view deep submenu
	Gtk::Menu * sky_view_deep_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_sky_deep = sky_view_deep_menu->items();
	MenuElem view_star("Star...", slot(*this, &NovaApp::on_sky_view_star_activate));
	MenuElem view_nebula("Nebula...", slot(*this, &NovaApp::on_sky_view_nebula_activate));
	MenuElem view_galaxies("Galaxies...", slot(*this, &NovaApp::on_sky_view_galaxy_activate));
	MenuElem view_other("Other...", slot(*this, &NovaApp::on_sky_view_other_activate));
	list_sky_deep.push_back (view_star);
	list_sky_deep.push_back (view_nebula);
	list_sky_deep.push_back (view_galaxies);
	list_sky_deep.push_back (view_other);
	
	// sky settings submenu
	Gtk::Menu * sky_settings_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_settings = sky_settings_menu->items();
	MenuElem settings_location("Location...", slot(*this, &NovaApp::on_sky_local_activate));
	MenuElem settings_markers("Markers...", slot(*this, &NovaApp::on_sky_vsky_activate));
	MenuElem settings_near("Near Sky...", slot(*this, &NovaApp::on_sky_near_sky_activate));
	MenuElem settings_deep("Deep Sky...", slot(*this, &NovaApp::on_sky_deep_sky_activate));
	list_settings.push_back (settings_location);
	list_settings.push_back (settings_markers);
	list_settings.push_back (settings_near);
	list_settings.push_back (settings_deep);
	
	// sky view object submenu
	Gtk::Menu * sky_view_object_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_sky_view_object = sky_view_object_menu->items();
	list_sky_view_object.push_back (MenuElem ("Solar System", *sky_view_near_menu));
	list_sky_view_object.push_back (MenuElem ("Deep Sky", *sky_view_deep_menu));
	list_sky_view_object.push_back (SeparatorElem());
	list_sky_view_object.push_back (MenuElem ("Coordinates", slot(*this, &NovaApp::on_sky_view_coordinates_activate)));
	
	// ephemeris submenu
	Gtk::Menu * sky_view_ephemeris_menu = Gtk::manage (new Gtk::Menu ());	
	MenuList &list_sky_view_ephemeris = sky_view_ephemeris_menu->items();
	MenuElem ephem_manage("Manage...", slot(*this, &NovaApp::on_sky_ephemeris_manage_activate));
	//sky_view_ephemeris_none = new CheckMenuElem("none", slot(*this, &NovaApp::on_sky_view_ephemeris_activate));
	list_sky_view_ephemeris.push_back (ephem_manage);
	list_sky_view_ephemeris.push_back (SeparatorElem());
	//list_sky_view_ephemeris.push_back (*sky_view_ephemeris_none);
	
	// sky view sub menu
	Gtk::Menu * sky_view_menu = Gtk::manage (new Gtk::Menu ());	
	MenuList &list_sky_view = sky_view_menu->items();
	list_sky_view.push_back (MenuElem("Epheremis",*sky_view_ephemeris_menu));
	list_sky_view.push_back (SeparatorElem());
	list_sky_view.push_back (MenuElem("Object",*sky_view_object_menu));
	
	// sky menu
	Gtk::Menu * sky_menu = Gtk::manage (new Gtk::Menu ());	
	MenuList &list_sky = sky_menu->items();
#if 0
	list_sky.push_back (MenuElem ("View",*sky_view_menu));
	list_sky.push_back (SeparatorElem());
	list_sky.push_back (MenuElem ("Settings", *sky_settings_menu));
#endif

	// add menus to menubar
	m_menubar.items().push_front(MenuElem("_Sky",AccelKey("<control>s"),*sky_menu));
}

/*! \fn void NovaApp::create_menu_observatory ()
*
* Create and install observatory menu 
*/
void NovaApp::create_menu_observatory ()
{
	// Activate the helpers for easy menu setup.
	using namespace Gtk::Menu_Helpers;
	
	// obs telescope goto near submenu
	Gtk::Menu * obs_goto_near_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_obs_tscope_near = obs_goto_near_menu->items();
	MenuElem goto_moon("Moon", slot(*this, &NovaApp::on_goto_moon_activate));
	MenuElem goto_mercury("Mercury", slot(*this, &NovaApp::on_goto_mercury_activate));
	MenuElem goto_venus("Venus", slot(*this, &NovaApp::on_goto_venus_activate));
	MenuElem goto_mars("Mars", slot(*this, &NovaApp::on_goto_mars_activate));
	MenuElem goto_jupiter("Jupiter", slot(*this, &NovaApp::on_goto_jupiter_activate));
	MenuElem goto_saturn("Saturn", slot(*this, &NovaApp::on_goto_saturn_activate));
	MenuElem goto_uranus("Uranus", slot(*this, &NovaApp::on_goto_uranus_activate));
	MenuElem goto_neptune("Neptune", slot(*this, &NovaApp::on_goto_neptune_activate));
	MenuElem goto_pluto("Pluto", slot(*this, &NovaApp::on_goto_pluto_activate));
	MenuElem goto_asteroids("Asteroids", slot(*this, &NovaApp::on_goto_asteroids_activate));
	MenuElem goto_comets("Comets", slot(*this, &NovaApp::on_goto_comets_activate));
	MenuElem goto_sun("Sun", slot(*this, &NovaApp::on_goto_sun_activate));
	list_obs_tscope_near.push_back (goto_moon);
	list_obs_tscope_near.push_back (goto_mercury);
	list_obs_tscope_near.push_back (goto_venus);
	list_obs_tscope_near.push_back (goto_mars);
	list_obs_tscope_near.push_back (goto_jupiter);
	list_obs_tscope_near.push_back (goto_saturn);
	list_obs_tscope_near.push_back (goto_uranus);
	list_obs_tscope_near.push_back (goto_neptune);
	list_obs_tscope_near.push_back (goto_pluto);
	list_obs_tscope_near.push_back (SeparatorElem());
	list_obs_tscope_near.push_back (goto_asteroids);
	list_obs_tscope_near.push_back (goto_comets);
	list_obs_tscope_near.push_back (SeparatorElem());
	list_obs_tscope_near.push_back (goto_sun);
	
	// telescope goto deep submenu
	Gtk::Menu * obs_goto_deep_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_tscope_deep = obs_goto_deep_menu->items();
	MenuElem goto_nebula("Nebula", slot(*this, &NovaApp::on_goto_nebula_activate));
	MenuElem goto_galaxies("Galaxies", slot(*this, &NovaApp::on_goto_galaxy_activate));
	MenuElem goto_star("Star", slot(*this, &NovaApp::on_goto_star_activate));
	MenuElem goto_other("Other", slot(*this, &NovaApp::on_goto_other_activate));
	list_tscope_deep.push_back (goto_nebula);
	list_tscope_deep.push_back (goto_galaxies);
	list_tscope_deep.push_back (goto_star);
	list_tscope_deep.push_back (goto_other);
	
	// telescope goto submenu
	Gtk::Menu * obs_goto_menu = Gtk::manage (new Gtk::Menu());
	MenuList &list_tscope_goto = obs_goto_menu->items();
	MenuElem goto_coords("Coordinates...", slot(*this, &NovaApp::on_goto_coords_activate));
	MenuElem goto_vsky("Virtual Sky Coordinates...", slot(*this, &NovaApp::on_goto_vsky_coords_activate));
	list_tscope_goto.push_back (MenuElem ("Near Sky", *obs_goto_near_menu));
	list_tscope_goto.push_back (MenuElem ("Deep Sky", *obs_goto_deep_menu));
	list_tscope_goto.push_back (SeparatorElem());
	list_tscope_goto.push_back (goto_coords);
	list_tscope_goto.push_back (goto_vsky);


	// observatory menu
	Gtk::Menu * obs_menu = Gtk::manage (new Gtk::Menu ());	
	MenuList &list_obs = obs_menu->items();
	MenuElem connect("Connect",slot(*this, &NovaApp::on_obs_connect_activate));
	MenuElem disconnect("Disconnect",slot(*this, &NovaApp::on_obs_disconnect_activate));
#if 0
	list_obs.push_back (connect);
	list_obs.push_back (disconnect);
	list_obs.push_back (SeparatorElem());
	list_obs.push_back (MenuElem ("Goto",*obs_goto_menu));
	list_obs.push_back (SeparatorElem());
	list_obs.push_back (MenuElem ("Control", slot(*this, &NovaApp::on_obs_control_activate)));
#endif

	// add menus to menubar
	m_menubar.items().push_front(MenuElem("_Observatory",AccelKey("<control>O"),*obs_menu));	
}

/*! \fn void NovaApp::create_menu_target ()
*
* Create and install target menu
*/
void NovaApp::create_menu_target ()
{
	// Activate the helpers for easy menu setup.
	using namespace Gtk::Menu_Helpers;
	
	// target menu
	Gtk::Menu * target_menu = Gtk::manage (new Gtk::Menu ());	
	MenuList &list_target = target_menu->items();
	StockMenuElem add(Gtk::Stock::ADD, slot(*this, &NovaApp::on_target_add_activate));
	StockMenuElem del(Gtk::Stock::DELETE, slot(*this, &NovaApp::on_target_delete_activate));
	StockMenuElem properties(Gtk::Stock::PROPERTIES, slot(*this, &NovaApp::on_target_properties_activate));
	StockMenuElem up(Gtk::Stock::GO_UP, slot(*this, &NovaApp::on_target_up_activate));
	StockMenuElem down(Gtk::Stock::GO_DOWN, slot(*this, &NovaApp::on_target_down_activate));
	StockMenuElem sort(Gtk::Stock::SORT_ASCENDING, slot(*this, &NovaApp::on_target_order_activate));
	StockMenuElem run(Gtk::Stock::EXECUTE, slot(*this, &NovaApp::on_target_execute_activate));
	StockMenuElem stop(Gtk::Stock::STOP, slot(*this, &NovaApp::on_target_stop_activate));
#if 0	
	list_target.push_back (add);
	list_target.push_back (del);
	list_target.push_back (properties);
	list_target.push_back (SeparatorElem());
	list_target.push_back (up);
	list_target.push_back (down);
	list_target.push_back (sort);
	list_target.push_back (SeparatorElem());
	list_target.push_back (run);
	list_target.push_back (stop);
#endif	
	// add menus to menubar
	m_menubar.items().push_front(MenuElem("_Target",AccelKey("<control>t"),*target_menu));	
}

void NovaApp::create_menu_log ()
{
}

/*! \fn void NovaApp::create_menu_help ()
*
* Create and install help menu
*/
void NovaApp::create_menu_help ()
{
	// Activate the helpers for easy menu setup.
	using namespace Gtk::Menu_Helpers;
	
	// about image
	Gtk::Image * image_help = Gtk::manage (new Gtk::Image(Gtk::StockID("gnome-stock-about"), Gtk::IconSize(1)));
	
	// help menu
	Gtk::Menu * help_menu = Gtk::manage (new Gtk::Menu ());	
	MenuList &list_help = help_menu->items();
	
	list_help.push_back (StockMenuElem (Gtk::Stock::HELP, slot(*this, &NovaApp::on_contents_activate)));
	list_help.push_back (SeparatorElem());
	list_help.push_back (ImageMenuElem ("About", *image_help, slot(*this, &NovaApp::on_about_activate)));
	
	// add menus to menubar
	m_menubar.items().push_front(MenuElem("_Help",AccelKey("<control>h"),*help_menu));	
}

/*! \fn void NovaApp::install_menus ()
*
* Install menuitems
*/
void NovaApp::install_menus ()
{
	create_menu_help ();
	create_menu_log ();
	create_menu_target ();
	create_menu_observatory ();
	create_menu_sky ();
	create_menu_file ();
	
	// liam install_menu_hints();
	m_app.pack_start(m_menubar, Gtk::PACK_SHRINK, 0);
}

void NovaApp::create_vsky(Vega::VirtualSky* page)
{
	m_page_height = m_toolbar.get_height() + m_menubar.get_height() + 3;
	page->set_size(get_width(), get_height() - m_page_height);
	page->create_sky();
}

/*! \fn void NovaApp::on_new_virtual_sky_activate()
*
* Create and run the new sky druid.
*/
void NovaApp::on_new_virtual_sky_activate()
{  
	VSkyDruid * druid = new VSkyDruid();
	Vega::VirtualSky* page = Gtk::manage (new Vega::VirtualSky());
	druid->set_vsky(page);
	gint result = druid->run();
	
	switch (result) {
		case Gtk::RESPONSE_OK: // create new vsky
			m_nova_book.append_page (*page, "sky");
			m_nova_book.set_current_page(1);
			m_pages.push_back(page);
			create_vsky(page);
			m_file_close->set_sensitive(true);
			m_file_save_as->set_sensitive(true);
			break;
		default:
			delete page;
		break;
	}
    delete druid;
}

void NovaApp::on_new_target_list_activate()
{  
}

void NovaApp::on_new_ephemeris_activate()
{  
}

void NovaApp::on_new_observatory_activate()
{  
}

/*! \fn void NovaApp::on_open_activate()
*
* Open an existing sky view, target list, ephemeris
* or observatory from file.
*/
void NovaApp::on_open_activate()
{  
	NovaFile fs("Open a Nova Sky, Ephemeris or Target List");

	if (fs.run() != Gtk::RESPONSE_OK)
		return;
	
	Glib::ustring file = fs.get_filename();
	
	// try virtual sky
	Vega::VirtualSky* vsky = Gtk::manage(new Vega::VirtualSky());
	if(vsky->open(file)) {
		m_nova_book.append_page (*vsky, "sky");
		m_nova_book.set_current_page(1);
		m_pages.push_back(vsky);
		create_vsky(vsky);
		m_file_close->set_sensitive(true);
		m_file_save->set_sensitive(true);
		m_file_save_as->set_sensitive(true);
		return;		
	}
	delete vsky;
	
	// try others
	
	// none found
	std::cout << __FILE__ << " " << __LINE__ << " tried to open unknown file" << std::endl;
	return;
}

/*! \fn void NovaApp::on_save_activate()
*
* Save the current sky view, target list , ephemeris or
* observatory to file.
*/
void NovaApp::on_save_activate()
{  
	Polaris::NovaPage* npage;
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((npage = dynamic_cast<Polaris::NovaPage*>(page)) != 0)
		npage->save();
}

/*! \fn void NovaApp::on_save_as_activate()
*
* Save the current sky view, target list , ephemeris or
* observatory to file with a new name.
*/
void NovaApp::on_save_as_activate()
{  
	Polaris::NovaPage* npage;
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((npage = dynamic_cast<Polaris::NovaPage*>(page)) != 0) {
		NovaFile fs("Save Nova Sky As");
		int response = fs.run();
	
		std::string file = fs.get_filename();
		if (npage->save_as(file))
			m_file_save->set_sensitive(true);
	}
}

/*! \fn void NovaApp::on_import_activate()
*
* Import an astronomical data catalog into Nova
*/
void NovaApp::on_import_activate()
{  
	// should be a druid
}

/*! \fn void NovaApp::on_print_activate()
*
* Print the curent Nova document.
*/
void NovaApp::on_print_activate()
{  
	Polaris::NovaPage* npage;
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((npage = dynamic_cast<Polaris::NovaPage*>(page)) != 0)
		npage->print();
}

/*! \fn void NovaApp::on_close_activate()
*
* Get the currently active page, check for unsaved data
* then close
*/
void NovaApp::on_close_activate()
{  
	Polaris::NovaPage* npage;
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((npage = dynamic_cast<Polaris::NovaPage*>(page)) == 0)
		return;
	
	if (npage->is_modified()) {
		Gtk::MessageDialog dlg("Warning the document has unsaved data.\nDo you still wish to close ?",
			Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true, true);
		int response = dlg.run();
		if (response != Gtk::RESPONSE_OK)
			return;
	}		
	
	m_nova_book.remove(*npage);
}

/*! \fn void NovaApp::on_quit_activate()
*
* Check for unsaved data then quit Nova
*/
void NovaApp::on_quit_activate()
{
	Gtk::Main::quit();
}

void NovaApp::on_sky_local_activate()
{  
}

void NovaApp::on_sky_vsky_activate()
{  
}

void NovaApp::on_sky_near_sky_activate()
{  
}

void NovaApp::on_sky_deep_sky_activate()
{  
}

void NovaApp::on_eph1_activate()
{  
}

void NovaApp::on_sky_ephemeris_manage_activate ()
{
}

void NovaApp::on_sky_view_sun_activate()
{  
}

void NovaApp::on_sky_view_mercury_activate()
{  
}

void NovaApp::on_sky_view_venus_activate()
{  
}

void NovaApp::on_sky_view_mars_activate()
{  
}

void NovaApp::on_sky_view_jupiter_activate()
{  
}

void NovaApp::on_sky_view_saturn_activate()
{  
}

void NovaApp::on_sky_view_uranus_activate()
{  
}

void NovaApp::on_sky_view_neptune_activate()
{  
}

void NovaApp::on_sky_view_pluto_activate()
{  
}

void NovaApp::on_sky_view_asteroids_activate()
{  
}

void NovaApp::on_sky_view_comets_activate()
{  
}

void NovaApp::on_sky_view_moon_activate()
{  
}

void NovaApp::on_sky_view_star_activate()
{  
}

void NovaApp::on_sky_view_galaxy_activate()
{  
}

void NovaApp::on_sky_view_nebula_activate()
{  
}

void NovaApp::on_sky_view_other_activate()
{  
}

void NovaApp::on_sky_view_deep_sky_activate()
{  
}

void NovaApp::on_sky_view_coordinates_activate()
{  
}

void NovaApp::on_sky_view_fainter_activate()
{
}

void NovaApp::on_sky_view_brighter_activate()
{
}
void NovaApp::on_obs_connect_activate()
{  
}

void NovaApp::on_obs_disconnect_activate()
{  
}

void NovaApp::on_goto_ephemeris_activate()
{  
}

void NovaApp::on_goto_sun_activate()
{  
}

void NovaApp::on_goto_mercury_activate()
{  
}

void NovaApp::on_goto_venus_activate()
{  
}

void NovaApp::on_goto_mars_activate()
{  
}

void NovaApp::on_goto_jupiter_activate()
{  
}

void NovaApp::on_goto_saturn_activate()
{  
}

void NovaApp::on_goto_uranus_activate()
{  
}

void NovaApp::on_goto_neptune_activate()
{  
}

void NovaApp::on_goto_pluto_activate()
{  
}

void NovaApp::on_goto_asteroids_activate()
{  
}

void NovaApp::on_goto_comets_activate()
{  
}

void NovaApp::on_goto_moon_activate()
{  
}

void NovaApp::on_goto_solar_system_activate()
{  
}

void NovaApp::on_goto_star_activate()
{  
}

void NovaApp::on_goto_galaxy_activate()
{  
}

void NovaApp::on_goto_nebula_activate()
{  
}

void NovaApp::on_goto_other_activate()
{  
}

void NovaApp::on_goto_coords_activate()
{
}

void NovaApp::on_goto_vsky_coords_activate()
{
}

void NovaApp::on_obs_control_activate()
{  
}

void NovaApp::on_target_add_activate()
{  
}

void NovaApp::on_target_delete_activate()
{  
}

void NovaApp::on_target_up_activate()
{  
}

void NovaApp::on_target_down_activate()
{  
}

void NovaApp::on_target_order_activate()
{  
}

void NovaApp::on_target_execute_activate()
{  
}

void NovaApp::on_target_stop_activate()
{  
}

void NovaApp::on_target_properties_activate()
{  
}

void NovaApp::on_log_add_activate()
{  
}

void NovaApp::on_log_search_activate()
{  
}

void NovaApp::on_log_properties_activate()
{  
}

void NovaApp::on_change_proj()
{
	Vega::VirtualSky* npage;
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((npage = dynamic_cast<Vega::VirtualSky*>(page)) != 0) {
		npage->change_projection();
		npage->set_size(get_width(), get_height() - m_page_height);
	}
}

/*! \fn void NovaApp::on_contents_activate()
* \todo implementation
* Display help contents
*/
void NovaApp::on_contents_activate()
{  
	TodoDialog::display ();
}

/*! \fn void NovaApp::on_about_activate()
*
* Display the about box.
*/
void NovaApp::on_about_activate()
{  
	m_about->show();
	m_about->raise();
}


/*! \fn void NovaApp::on_zoom_in_button_clicked()
*
* Zoom in the current virtual sky view.
*/
void NovaApp::on_zoom_in_button_clicked()
{  
	// get vsky page
	Vega::VirtualSky* vsky;
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((vsky = dynamic_cast<Vega::VirtualSky*>(page)) != 0)
	{
		if (vsky->zoom (0.75)) {
			// cant zoom in many more, shade out zoom button
		}
	}
}

/*! \fn void NovaApp::on_zoom_out_button_clicked()
*
* Zoom out the current virtual sky view.
*/
void NovaApp::on_zoom_out_button_clicked()
{  
	// get vsky page
	Vega::VirtualSky* vsky; 
	Gtk::Widget * page = m_nova_book.get_current()->get_child();
	if ((vsky = dynamic_cast<Vega::VirtualSky*>(page)) != 0)
	{
		if (vsky->zoom (1.5)) {
			// cant zoom in many more, shade out zoom button
		}
	}
}


void NovaApp::on_goto_button_clicked()
{  
}

};


syntax highlighted by Code2HTML, v. 0.9.1