------------------------------------------------------------------------------
--                                  G P S                                   --
--                                                                          --
--                     Copyright (C) 2005-2013, AdaCore                     --
--                                                                          --
-- This is free software;  you can redistribute it  and/or modify it  under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  This software is distributed in the hope  that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY 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  distributed  with  this  software;   see  file --
-- COPYING3.  If not, go to http://www.gnu.org/licenses for a complete copy --
-- of the license.                                                          --
------------------------------------------------------------------------------

--  This package helps build simple views that are associated with a single
--  window, that are saved in the desktop, and have a simple menu in Tools/
--  to open them.
--  This package must be instanciated at library-level

with GPS.Kernel.Modules;
with GPS.Kernel.MDI;
with Glib.Object;
with XML_Utils;
with Gtk.Scrolled_Window;
with Gtk.Widget;
with Gtkada.MDI;

package Generic_Views is

   -----------------
   -- View_Record --
   -----------------

   type View_Record is new Gtk.Scrolled_Window.Gtk_Scrolled_Window_Record
      with null record;

   function Save_To_XML
     (View : access View_Record) return XML_Utils.Node_Ptr;
   --  Return an XML represention of the view. This is used to save the view
   --  to the desktop, and possibly for debug purposes.
   --  By default, this returns null

   procedure Load_From_XML
     (View : access View_Record; XML : XML_Utils.Node_Ptr);
   --  Initialize View from XML. XML is the contents of the desktop node for
   --  the View, and was generated by Save_To_XML.
   --  By default, this function does nothing

   ------------------
   -- Simple_Views --
   ------------------

   generic
      Module_Name : String;
      --  The name of the module, and name used in the desktop file. It mustn't
      --  contain any space.

      View_Name   : String;
      --  Name of MDI window that is used to create the view

      type Formal_View_Record is new View_Record with private;
      --  Type of the widget representing the view

      Reuse_If_Exist : Boolean;
      --  If True a single MDI child will be created and shared

      with function Initialize
        (View   : access Formal_View_Record'Class;
         Kernel : access GPS.Kernel.Kernel_Handle_Record'Class)
         return Gtk.Widget.Gtk_Widget is <>;
      --  Function used to create the view itself.
      --  The Gtk_Widget returned, if non-null, is the Focus Widget to pass
      --  to the MDI.

   package Simple_Views is

      type View_Access is access all Formal_View_Record'Class;

      procedure Register_Module
        (Kernel      : access GPS.Kernel.Kernel_Handle_Record'Class;
         ID          : GPS.Kernel.Modules.Module_ID := null;
         Menu_Name   : String := View_Name;
         Before_Menu : String := "");
      --  Register the module. This sets it up for proper desktop handling, as
      --  well as create a menu in Tools/ so that the user can open the view.
      --  ID can be passed in parameter if a special tagged type needs to be
      --  used.
      --  Menu_Name is the name of the menu, in tools, that is used to create
      --  the view.
      --  If Before_Menu is not empty, the menu entry will be added before it.

      function Get_Module return GPS.Kernel.Modules.Module_ID;
      --  Return the module ID corresponding to that view

      function Get_Or_Create_View
        (Kernel : access GPS.Kernel.Kernel_Handle_Record'Class;
         Focus  : Boolean := True;
         Group  : Gtkada.MDI.Child_Group := GPS.Kernel.MDI.Group_View)
         return View_Access;
      --  Return the view (create a new one if necessary, or always if
      --  Reuse_If_Exist is False).
      --  The view gets the focus automatically if Focus is True.

   private
      --  The following subprograms need to be in the spec so that we can get
      --  access to them from callbacks in the body

      procedure On_Open_View
        (Widget : access Glib.Object.GObject_Record'Class;
         Kernel : GPS.Kernel.Kernel_Handle);
      On_Open_View_Access : constant
        GPS.Kernel.MDI.Kernel_Callback.Marshallers.Void_Marshaller.Handler :=
          On_Open_View'Access;
      --  Create a new view if none exists, or raise the existing one

      function Load_Desktop
        (MDI  : Gtkada.MDI.MDI_Window;
         Node : XML_Utils.Node_Ptr;
         User : GPS.Kernel.Kernel_Handle) return Gtkada.MDI.MDI_Child;
      Load_Desktop_Access : constant
        GPS.Kernel.MDI.Load_Desktop_Function := Load_Desktop'Access;
      function Save_Desktop
        (Widget : access Gtk.Widget.Gtk_Widget_Record'Class;
         User   : GPS.Kernel.Kernel_Handle) return XML_Utils.Node_Ptr;
      Save_Desktop_Access : constant
        GPS.Kernel.MDI.Save_Desktop_Function := Save_Desktop'Access;
      --  Support functions for the MDI
   end Simple_Views;

end Generic_Views;
