/*
 * Copyright 2000 Murray Cumming
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef APP_WITHDOC_H
#define APP_WITHDOC_H

#include "App.h"
#include "../Document/Document.h"
#include "../FileSelection/FileSelection.h"

namespace Bakery
{

//Features:
//- Derive from this class
//- 1 document per application instance. Uses Document-derived class polymorphically.
//- Override pure virtual method to create new blank document.
//- Appropriate Default handling of document open, save, save as.
//- Appropriate checking of document 'modified' status - asks user about unsaved changes.
//- Asks user about overwriting existing documents.
//- Override methods to add/change menus/toolbars/statusbar.
//  - Default is basic File, Edit, Help menus and toolbar icons.
//- Shows document name (or 'untitled') in window title.
//- Shows * in title bar for unsaved docs. Overridable to e.g. shade a Save icon.
//- Enforces a file extension.
//- Recent Documents menu item

//TODO:

//- Bonobo integration - when Bonobo is ready. (An App subclass?)
//- Printing - GnomePrint?
//  - Print Setup
//  - Print Preview
//- Multiple document-types:
//  - File/New sub menu
//  - Some way to associate a view with a document type: class factory.
//  Gnome::MDI App.

class App_WithDoc : public App
{
public: 
  App_WithDoc(const string& appname, const string& title); //Don't forget to call init() too.
  virtual ~App_WithDoc();

  virtual void init(); //overriden to create document.
	 
protected:
  virtual void init_menus_file(); //overridden to add open/save/save as.
  virtual void init_toolbars(); //overridden to add open/save
  virtual void init_create_document(); //override this to new() the specific document type.
  virtual void init_menus(); //overriden to get widget pointers.

  virtual Document* get_document(); //static_cast<> or dynamic_cast<> this pointer to the correct type.
  virtual void set_Document_modified(bool bModified = true);
  virtual bool open_document(const std::string& strFilepath); //bool indicates success.

  static void document_history_add(const std::string& strFilepath);
  static void document_history_remove(const std::string& strFilepath);

  //Signal handlers:

  //Menu items:
  virtual void on_menu_File_Open();
  virtual void on_menu_File_OpenRecent(guint index); //use with SigC::bind.
  virtual void on_menu_File_SaveAs(); //signal handler.
  virtual void offer_SaveAs(); //For direct use.
  virtual void on_menu_File_Save(Gtk::Widget* pWidget = 0); //signal handler.
  virtual void on_menu_File_Close();
  virtual void on_menu_File_Exit();

  virtual void on_menu_Edit_Copy();
  virtual void on_menu_Edit_Paste();
  virtual void on_menu_Edit_Clear();
  
  //Document:
  virtual void on_Document_modified(); //Update visual status.
  virtual void on_Document_load(); //override this to show document contents.

  //Session Client:
  virtual gint on_Session_save_yourself(gint phase, GnomeSaveStyle save_style, gint is_shutdown, GnomeInteractStyle interact_style, gint is_fast); //override
  static void session_load_document_history();
  static void session_save_document_history();

  void session_load_documents_open();
  static void session_save_documents_open();


  virtual void offer_to_save_changes();
  virtual void cancel_close_or_exit(); //Stop the File|Close or the File|Exit.
  virtual void close_mark_or_destroy(); //destroy it or mark it for destruction.
  virtual void exit_close_next_instance(); //During a File|Exit tell the next instance to close too.
  virtual void exit_destroy_marked_instances(); //Destroy any marked instances, at the end of a File|Exit.
  
  virtual void update_window_title();
  static void show_document_history(); //In all instances' menus.
  virtual void after_successful_save(); //e.g. disable File|Save.
  

  //Document:
  Document* m_pDocument; //An instance of a derived type.
  bool m_bCloseAfterSave;
  bool m_bMarkedForDestroy; //Whether the instance should be destroyed soon.

  //Member widets:
  Bakery::FileSelection m_FileSelection_Open, m_FileSelection_Save;

  //Menu stuff:
  guint m_iMenuPos_File, m_iMenuPos_File_Save;
  Gtk::Widget* m_pMenuItem_File_Save;
  Gtk::Widget* m_pToolbarItem_Save;

  typedef std::vector<std::string> type_vecStrings;
  static type_vecStrings m_vecDocHistory; //Previously-opened files.
  bool m_bMenuOpenRecentCreated;
};

} //namespace

#endif
