------------------------------------------------------------------------------
-- Gmface-Gm_Application-Gtk_Interface : GtkAda Gm interface of Gmface.     --
------------------------------------------------------------------------------

with Gmface.Gm_Virtual.Gmface.Gmface_Work;
use Gmface.Gm_Virtual.Gmface.Gmface_Work;
with Gmface.Gm_Virtual.Gmidi.Gmidi_Work;
use Gmface.Gm_Virtual.Gmidi.Gmidi_Work;

with Gmface.Gm_Common;                  use Gmface.Gm_Common; 
with Gmface.Gm_Virtual.Gmface.Gmface_Plugins;
use Gmface.Gm_Virtual.Gmface.Gmface_Plugins;
with Gmface.Gm_Processing.Gm_Common;    use Gmface.Gm_Processing.Gm_Common;
with Gmface.Gm_Processing.Gmface.Work_Processing;
use Gmface.Gm_Processing.Gmface.Work_Processing;

with Gmface.Gm_Application.Gtk_Plugins_Initialization;
use Gmface.Gm_Application.Gtk_Plugins_Initialization;

with Gmface.Gm_Midi.Drivers;            use Gmface.Gm_Midi.Drivers;

with Gmface.Gm_Application.Preferences; use Gmface.Gm_Application.Preferences;

with Glib.Application;                  use Glib.Application;
with Glib;                              use Glib;
with Glib.Convert;                      use Glib.Convert;
with Glib.Error;                        use Glib.Error;
with Glib.Values;                       use Glib.Values;
with Glib.Object;                       use Glib.Object;

with Gtk.Widget;                        use Gtk.Widget;
with Gtk.Dialog;                        use Gtk.Dialog;
with Gtk.About_Dialog;                  use Gtk.About_Dialog;


with Gtk.Handlers;                      
pragma Elaborate_All (Gtk.Handlers);
use Gtk.Handlers;

with GNAT.Strings;

with Gtk.Arguments;                     use Gtk.Arguments;


with Gtk.Enums;                         use Gtk.Enums;
with Gtk.Stock;                         use Gtk.Stock;


with Gtk.Tree_Selection;                use Gtk.Tree_Selection;
with Gtk.Tree_Sortable;                 use Gtk.Tree_Sortable;
with Gtk.Tree_View_Column;              use Gtk.Tree_View_Column;
with Gtk.Cell_Renderer_Text;            use Gtk.Cell_Renderer_Text;
with Gtk.Cell_Renderer_Toggle;          use Gtk.Cell_Renderer_Toggle;

with Gtk.Adjustment;                    use Gtk.Adjustment;
with Gtk.Scrolled_Window;               use Gtk.Scrolled_Window;

with Gtk.Main;                          use Gtk;

with Gtkada.File_Selection;             use Gtkada.File_Selection;
with Gtk.File_Chooser;                  use Gtk.File_Chooser;
with Gtk.File_Chooser_Dialog;           use Gtk.File_Chooser_Dialog;


with Ada.Calendar.Formatting;           use Ada.Calendar;

with Ada.Strings.Fixed;                 use Ada.Strings;

with Text_Io;                           use Text_Io;

package body Gmface.Gm_Application.Gtk_Interface is
   
   use Gtk;
   function Gmface_Initialize(Work          : in Work_Access;
			      Work_Id       : in Work_Num;
			      Process       : in Work_Processing_Access;
			      Gtk_Interface : in Gtk_Interface_Pointer) 
			     return Gtk_Work_Window_Pointer;
   
   function Gmidi_Initialize(Work          : in Work_Access;
			     Work_Id       : in Work_Num;
			     Process       : in Work_Processing_Access;
			     Gtk_Interface : in Gtk_Interface_Pointer) 
			    return Gtk_Work_Window_Pointer;
         
   ------------------------------------------------------------------
   --                Main action menu of Application               --
   ------------------------------------------------------------------
   
   procedure New_Action (Action, Application : in System.Address);
   pragma Convention (C, New_Action);
   --  Called when Main->New actions has been selected
   
   procedure Open_Action (Action, Main_Window : in System.Address);
   pragma Convention (C, Open_Action);
   --  Called when Main->Open actions has been selected   
   
   
   procedure Quit_Action (Action, Gtk_Interface : in System.Address);
   pragma Convention (C, Quit_Action);
   --  Called when Main->Quit actions has been selected
   
   procedure Preferences_Action (Action, Gtk_Interface : System.Address);
   pragma Convention (C, Preferences_Action);
   --  Called when Options->Preferences actions has been selected
   
   procedure About_Action (Action, Main_Window : System.Address);
   pragma Convention (C, About_Action);
   --  Called when Help->About actions has been selected
   
   function Close_Window(Window : access Gtk_Window_Record'Class;
			 App    : Gtk_Interface_Pointer) return Boolean;
   --  Called when delete-event signal is sended
   
   
   procedure Focus_Window(Window : access Gtk_Window_Record'Class;
			  App    : Gtk_Interface_Pointer);
   --  Called when activate-focus signal is sended
   
   
   procedure Close_Action (Action, Application : in System.Address);
   pragma Convention (C, Close_Action);
   --  Called when Main->Close actions has been selected
   
   
   procedure Focus_Window(Window : access Gtk_Window_Record'Class;
			 App    : Gtk_Interface_Pointer) is
      
      
   begin
      
      for Id in App.Gtk_Works_Windows'Range loop
	 if App.Gtk_Works_Windows(Id).window = Window then      
	    App.Cur_Window := Id;
	 end if;
      end loop;
      
   end Focus_Window;
   
   procedure Inputs_Finalization(Int : in Gtk_Interface_Pointer) is

   begin
      --Put_Line("CUCU 0.0.0");
      for Device_Id in Int.Bandmaster.Orchester'Range loop
      	 if Int.Bandmaster.Orchester(Device_Id) /= null then
   	    --Put_Line("CUCU 0.1.0");
   	    if Int.Bandmaster.Orchester(Device_Id).Input_Device_Driver /= null then
   	       declare
   		  Dialog : Gtk_Dialog;
   		  Ok    : Gtk.Widget.Gtk_Widget;
   		  Label  : Gtk_Label;
   		  Vbox   : Gtk_Box;

   	       begin
   		  --Put_Line("CUCU 0.1.1");
   		  Gtk.Dialog.Gtk_New(Dialog, "Halting drivers...", Int.Window, Gtk.dialog.modal);
   		  Set_Decorated(Dialog, False);
   		  Vbox := Get_content_area(Dialog);
   		  --Put_Line("CUCU 0.1.1.1");
   		  Gtk_New(Label, "Please action some controler of device named : " &
   			    Int.Bandmaster.Orchester(Device_Id).Input_Device_Driver.Device_Info.Name.all);
   		  Pack_Start(Vbox, Label);
   		  --Put_Line("CUCU 0.1.1.2");
   		  Ok := Gtk.Dialog.Add_button(Dialog, "Ok", Gtk.Dialog.Gtk_Response_Ok);
   		  Set_Response_Sensitive(Dialog, Gtk.Dialog.Gtk_Response_Ok, False);
   		  Show_All(Vbox);
   		  --Put_Line("CUCU 0.1.2");
   		  declare
   		     task End_Message_Type is


   		     end End_Message_Type;

   		     task body End_Message_Type is
   		     begin


   			--if Int.Bandmaster.Orchester(Device_Id).Input_Device_Driver.Device_Info.Id /= -1 then
   			   if Int.Bandmaster.Orchester(Device_Id).Input_Device_Driver /= null then
   			      --Put_Line("CUCU 0.1.2.1");
   			      Put_Line("Stopping input driver...");
   			      Int.Bandmaster.Orchester(Device_Id).Input_Device_Driver.Input_Driver.Halt;
   			      --Put_Line("CUCU 0.1.2.2");
   			      Put_Line("Stopping tempo sync...");
   			      int.Bandmaster.Orchester(Device_Id).Tempo_Sync.Halt;
   			      --Put_Line("CUCU 0.1.2.3");
   			      Put_Line("Stopping mod sequencer...");
   			      Int.Bandmaster.Orchester(Device_Id).Mod_Seq.Halt;
   			      --Put_Line("CUCU 0.1.2.4");

   			   end if;
   			--end if;
   			Set_Response_Sensitive(Dialog, Gtk.Dialog.Gtk_Response_Ok, True);
   		     end End_Message_Type;
   		  begin
   		     --Put_Line("CUCU 0.1.3");
   		     case Gtk.Dialog.Run(Dialog) is
   			when others =>
   			   --Text_Io.Put_Line("Destroy Dialog");
   			   Gtk.Dialog.Destroy(Dialog);
   		     end case;
   		     --Put_Line("CUCU 0.1.3");
   		  end;
   	       end;
   	    end if;
   	 end if;
      end loop;
      Put_Line("Input finalization done.");
   end Inputs_Finalization;

   use Gtk_Work_Window_Conversions;
   
   function Close_window(Window : access Gtk_Window_Record'Class;
			 App    : Gtk_Interface_Pointer) return Boolean is
      
      Only_One : Natural := 0;
      
   begin
      --Put_Line("Close 0.0.0");
      for Id in 1..Work_Num(App.Work_Last) loop
	 --Put_Line("Close 0.0.1");
	 if App.Gtk_Works_Windows(Id) /= null and then 	   
	   App.Gtk_Works_Windows(Id).Window /= null then	    	    
	    --Put_Line("Close 0.0.2");
	    if App.Gtk_Works_Windows(Id).Window = Window then
	       --Put_Line("Close 0.0.3");
	       
	       Gmface_Work_Processing(App.Gtk_Works_Windows(Id).Process.all).Process.Stop;
	       Put_Line("Processes stopped");	       
	       Gmface_Work_Processing(App.Gtk_Works_Windows(Id).Process.all).Process.Halt;
	       App.Gtk_Works_Windows(Id).Process.Box.Halt;
	       Put_Line("Processes halted");	  
	       
	       if Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(Id).all).Flow_Control /= Glib.Main.No_Source_Id then
		  
	       	  Glib.Main.Remove(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(Id).all).Flow_Control);
	       	  Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(Id).all).Flow_Control := Glib.Main.No_Source_Id;
	       end if;
	       if Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(Id).all).State_Control /= Glib.Main.No_Source_Id then

	       	  Glib.Main.Remove(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(Id).all).State_Control);
	       	  Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(Id).all).State_Control := Glib.Main.No_Source_Id;
	       end if;
	       ---------------------------------------
	       -- Free(App.Gtk_Works_Windows(Id));  --
	       ---------------------------------------
	       	       
	       Remove_Window(App.Application, App.Gtk_Works_Windows(Id).Window);
	       Destroy(Window);
	       if id < Work_Num(App.Work_Last) then
		  for Work in Id..Work_Num(App.Work_Last-1) loop
		     App.Works(Work) := App.Works(Work+1);
		     App.Works_processes(Work) := App.Works_processes(Work+1);
		     App.Gtk_Works_Windows(Work) := App.Gtk_Works_Windows(Work+1);		     
		  end loop;		  		  
	       end if;
	       App.Work_Last := App.Work_Last - 1;
	    end if;
	 end if;
      end loop;
      
      Put_Line("Work_last = " & Integer'Image (App.Work_Last));
      if App.Work_Last = 0  then	 	 	 
	 
	 if App.Main_Automation /= Glib.Main.No_Source_Id then
	    Glib.Main.Remove(App.Main_Automation);
	 end if;
	 
	 
	 Inputs_Finalization(App.all'access);
	 Finalize(App.Bandmaster);
	 Destroy(App.Window);

	 
	 return True;	 
      end if;      
      return False;      
   end Close_Window;
   
   
   procedure Quit_Action (Action, Gtk_Interface : in System.Address) is
      
      pragma Unreferenced(Action);
      
      Gtk_Int : constant Gtk_Interface_Pointer :=
	Gtk_Interface_Conversions.To_Pointer(Gtk_Interface);
      
      End_Of_Application : Boolean := False;
      
   begin
      if Gtk_Int.Work_Last > 0 then	 	 	 
	 --  -- Halting all process
	 Put_Line("Halting all process...");
	 	 
	 for Work in 1..Work_Num(Gtk_Int.Work_Last) loop	    
	    End_Of_Application := Close_Window(Gtk_Int.Gtk_Works_Windows(Work).Window, Gtk_Int);
	 end loop;
	 
      end if;
      if End_Of_Application then
	 Put_Line("End of Program.");
	 Glib.Application.Quit(Gapplication(Gtk_Int.Application));
      end if;
   end Quit_Action;
   
   procedure Set_Input_Device (Combo : access Gtk_Combo_Box_Text_record'Class;
			       Gtk_Int : in Gtk_Interface_Pointer) is
      
           
   begin
      if Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1) /= null then
	 Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1).Input.Id := 
	   Integer(Get_Active(Combo)+1);
	 Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1).Input.name := 
	   new String ' (Get_Active_Text(Combo));
      end if;
      Inputs_Devices(Gtk_Int.Cur_Page+1) :=
	Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1).Input.Id;
   end Set_Input_Device;
   
   procedure Set_Output_Device (Combo : access Gtk_Combo_Box_Text_record'Class;
			       Gtk_Int : in Gtk_Interface_Pointer) is
      
           
   begin
      if Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1) /= null then
	 Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1).Output.Id := 
	   Integer(Get_Active(Combo)+1);
	 Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1).Output.name := 
	   new String ' (Get_Active_Text(Combo));
      end if;	 
      Outputs_Devices(Gtk_Int.Cur_Page+1) :=
	Gtk_Int.Gm_Application.Devices_Info(Gtk_Int.Cur_Page+1).Output.Id;
   end Set_Output_Device;

   
   package Devices_User_Callback is
      new Handlers.User_Callback
     (Gtk_Combo_Box_Text_Record, Gtk_Interface_Pointer);      

   
   -------------------------------------------------------------------------------
   -- Create device page : (add and remove device(s)                            --
   -------------------------------------------------------------------------------   
   procedure Create_Device_Page(Notebook      : access Gtk_Notebook_Record'Class;
				Gtk_Interface : in Gtk_Interface_Pointer;
				Device_Num    : in positive) is
      
      Vbox : Gtk_Vbox;
      
      Hbox : Gtk_Hbox;
      
      Page_Num : constant Gint := Get_N_Pages(Notebook);      
      Label    : Gtk_Label;
      
      Input_Label  : Gtk_Label;
      Output_Label : Gtk_Label;
      
      Input_List : constant Devices_List_Access := Inputs_List;
      Output_List : constant Devices_List_Access := Outputs_List;
   begin
      
      Put_Line("Create :: page num = " & Gint'Image(Page_Num));
      
      Gtk_New_Vbox (Vbox, False, 0);
      Gtk_New(Label, "Device Id :" & Gint'Image(Page_Num+1));                  
      
      if Gtk_Interface.Gm_Application.Devices_Info(Device_Num) = null then
	 Gtk_Interface.Gm_Application.Devices_Info(Device_Num) := new Device_Record;
      end if;
      
      Gtk_Interface.Devices_Pages(Positive(Page_Num+1)) := new Device_Page_Record;
            
      Gtk.Combo_Box_text.Gtk_New(Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Input_Device);
      --
      for Input in Input_List'Range loop
	 if Input_List(Input).Name /= null then
	    Gtk.Combo_Box_text.Append_Text
	      (Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Input_Device,
	       Input_List(Input).Name.all);
	 end if;
      end loop;
      Put_Line("Device num : " & Integer'Image(Device_Num));
      Put_Line("Active Input : " & Integer'Image(Inputs_Devices(Device_Num)));
      if Inputs_Devices(Device_Num) > (-1) then
	 Gtk.Combo_Box_text.Set_Active
	   (Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Input_Device,
	    Gint(Inputs_Devices(Device_Num))-1);
      end if;
	    
      Devices_User_Callback.Connect
	(Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Input_Device,
	 "changed",
	 Devices_User_Callback.To_Marshaller(Set_Input_Device'Access),
	 Gtk_Interface);
				           
      Gtk.Combo_Box_text.Gtk_New(Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Output_Device);
      --
      for Output in Output_List'Range loop
	 if Output_List(Output).Name /= null then
	    Gtk.Combo_Box_Text.Append_Text
	      (Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Output_Device,
	       Output_List(Output).Name.all);
	 end if;
      end loop;
      Put_Line("Active Output : " & Integer'Image(Inputs_Devices(Device_Num)));
      if Outputs_Devices(Device_Num) > (-1) then
	 Gtk.Combo_Box_text.Set_Active
	   (Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Output_Device,
	    Gint(Outputs_Devices(Device_Num))-1);
      end if;

      Devices_User_Callback.Connect
	(Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Output_Device,
	 "changed",
	 Devices_User_Callback.To_Marshaller(Set_Output_Device'Access),
	 Gtk_Interface);

      
      
      
      Gtk_New(Input_Label, "Input  : ");
      Gtk_New(Output_Label, "Output : ");
      
      Gtk_New_Hbox(Hbox, False, 0);
      Pack_Start(Hbox, Input_Label);      
      Pack_Start(Hbox, Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Input_Device);
      
      Pack_Start(Vbox, Hbox);
      
      Gtk_New_Hbox(Hbox, False, 0);
      Pack_Start(Hbox, Output_Label);      
      Pack_Start(Hbox, Gtk_Interface.Devices_Pages(Positive(Page_Num+1)).Output_Device);
      
      Pack_Start(Vbox, Hbox);
      
      Append_Page (Notebook, Vbox, Label);
      Show_All(Notebook);
      if Page_Num >= 0 then
	 for I in Get_Current_Page(Notebook) .. Get_N_Pages(Notebook)+1 loop
	    Next_Page(Notebook);
	 end loop;	 
      end if;      
      if Get_Current_Page(Notebook) >= 0 then
	 Gtk_Interface.Cur_Page := Integer(Get_Current_Page(Notebook));      
      end if;
   end Create_Device_Page;      
   
   procedure Remove_Device_Page(Notebook : access Gtk_Notebook_Record'Class;
				Gtk_Interface : in Gtk_Interface_Pointer) is
      
      Page_Num : constant Gint := Get_Current_Page(Notebook);
      
   begin
      if Page_Num < 0 then
	 return;
      end if;
      Put_Line("Remove page num : " & Gint'Image(Page_Num));
      Inputs_Devices(Positive(Page_num+1)) := (-1);
      Outputs_Devices(Positive(Page_num+1)) := (-1);
      
      
      
      Gtk_Interface.Gm_Application.Devices_info(Positive(Page_Num + 1)) := null;
      
      Gtk_Interface.Devices_Pages(Positive(Page_Num + 1)) := null;
      if Page_Num >= 0 then
	 for Page in Page_Num..Get_N_Pages(Notebook) - 1 loop
	    Gtk_Interface.Gm_Application.Devices_info(Positive(Page + 1)) := 
	      Gtk_Interface.Gm_Application.Devices_info(Positive(Page + 2));	 	    
	 end loop;
      end if;      
      Remove_Page (Notebook, Page_Num);
      if Get_N_Pages(Notebook) > 0 then
	 if Page_Num < Get_N_Pages(Notebook) then	    	    
	    Set_Current_Page(Notebook, Get_N_Pages(Notebook));
	 else
	    Set_Current_Page(Notebook, Page_Num - 1);
	 end if;
      end if;
      Gtk_Interface.Cur_Page := Integer(Get_Current_Page(Notebook));      
      
      
      for Page in reverse Page_Num..Get_N_Pages(Notebook) -1 loop
	 
	 Inputs_Devices(Positive(Page+1)) := Inputs_Devices(Positive(Page+2));
	 Outputs_Devices(Positive(Page+1)) := Outputs_Devices(Positive(Page+2));
	 Inputs_Devices(Positive(Page+2)) := (-1);
	 Outputs_Devices(Positive(Page+2)) := (-1);      
      end loop;
      Show_All(Notebook);
      
   end Remove_Device_Page;
   
   procedure Page_Switch
     (Notebook : access Gtk_Notebook_Record'Class;      
      Params   : Gtk.Arguments.Gtk_Args) is
      Page_Num : constant Gint := Gint (To_Guint (Params, 2));      
      pragma Unreferenced (Notebook);
   begin      
      Put_Line("Switch page to device page Id : " & Gint'Image(Page_Num));
   end Page_Switch;
     
   
   Gtk_Response_Add : constant Gtk_Response_Type := -12;
   Gtk_Response_Remove : constant Gtk_Response_Type := -13;
   
   package Notebook_Callback is
      new Handlers.Callback
     (Gtk_Notebook_Record);      
   
   procedure Preferences_Action (Action, Gtk_Interface : System.Address) is
      
      pragma Unreferenced(Action);
      
      Gtk_Int : constant Gtk_Interface_Pointer :=
	Gtk_Interface_Conversions.To_Pointer(Gtk_Interface);
      ------------
      -- Dialog --
      ------------
      Dialog : Gtk_Dialog;
      Widget : Gtk_Widget;
      Vbox   : Gtk_Vbox;
      
      ---------------------------------------
      -- Devices notebook :                --
      ---------------------------------------            
      
      
	
   begin
      
      
      loop
	 
	 declare
	    Device_Num : Positive := 1;
	 begin
	    
	    Gtk_New(Dialog, "Preferences", Gtk_Int.Window, Gtk.dialog.Modal);
	    Set_Default_Size(Gtk_Window(Dialog), 450, 150);
	    Set_Decorated(Dialog, False);
	    Vbox := Get_Content_Area(Dialog);                  
	    
	    ---------------------------------
	    --   Orchester construction    --
	    ---------------------------------
	    Gtk_New (Gtk_Int.Notebook);      
	    
	    Set_Scrollable(Gtk_Int.Notebook, True);
	    
	    
	    for Num in Gtk_Int.Gm_Application.Devices_Info'Range loop
	       if Gtk_Int.Gm_Application.Devices_Info(Device_Num) /= null then
		  Create_Device_Page(Gtk_Int.Notebook, Gtk_Int, Device_num);
		  Device_Num := Device_Num + 1;
	       elsif Inputs_Devices(Device_Num) /= (-1) or
		 Outputs_Devices(Device_Num) /= (-1) then
		  Create_Device_Page(Gtk_Int.Notebook, Gtk_Int, Device_num);
		  Device_Num := Device_Num + 1;
	       else
		  exit;
	       end if;
	    end loop;
	    
	    Notebook_Callback.Connect
	      (Gtk_Int.Notebook,
	       "switch_page",
	       Page_Switch'Access);
	    
	    Pack_Start(Vbox, Gtk_Int.Notebook);
	    
	    
	    ---------------------------------
	    -- End orchester construction  --
	    ---------------------------------
	    Widget := Gtk.Dialog.Add_button(Dialog, "Add", Gtk_Response_Add);
	    Widget := Gtk.Dialog.Add_button(Dialog, "Remove", Gtk_Response_Remove);	    
	    Widget := Gtk.Dialog.Add_button(Dialog, "Ok", Gtk_Response_Ok);
	    
	    
	    Show_All(Dialog);
	    case Gtk.Dialog.Run(Dialog) is
	       when Gtk_Response_Ok =>
		  Gtk.Dialog.Destroy(Dialog);
		  exit;
	       when Gtk_Response_Add =>
		  Create_Device_Page(Gtk_Int.Notebook, Gtk_Int, Device_Num);
		  Gtk.Dialog.Destroy(Dialog);	       
	       when Gtk_Response_Remove =>
		  Remove_Device_Page(Gtk_Int.Notebook, Gtk_Int);
		  Gtk.Dialog.Destroy(Dialog);
	       when others =>
		  Gtk.Dialog.Destroy(Dialog);
		  exit;
	    end case;
	 end;
      end loop;
   end Preferences_Action;
   
   
   procedure About_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);

      Frame : Gtk_Frame;
      About_Help : Gtk_About_Dialog;
   begin

      Gtk_New(Frame);
      Set_Label (Frame, "About dialog");

      Gtk_New(About_Help);
      Set_Transient_For (About_Help, Gtk_interface_Conversions.To_Pointer(Main_Window).Window);
      Set_Destroy_With_Parent (About_Help, True);
      Set_Modal (About_Help, True);



      Set_Artists(About_Help, (1 => new String ' ("localghost")));
      Set_Authors(About_Help, (1 => new String ' ("E. Sens")));
      Set_Comments(About_Help, Glib.Convert.Locale_To_UTF8("General MIDI Interface"));
      Set_Copyright(About_Help, Glib.Convert.Locale_To_UTF8("Copyright (C) 2018 Manuel De Girardi"));
      Set_Documenters(About_Help, (1 => new String ' ("")));
      Set_License
      	(About_Help, Glib.Convert.Locale_To_UTF8
      	   ("This program is free software; you can redistribute it and/or modify" & Character'Val(10) &
      	      "It Under The Terms of The GNU General Public License As Published By" & Character'Val(10) &
      	      "The Free Software Foundation; Either Version 2 of The License, or"  & Character'Val(10) &
      	      "(at Your Option) Any Later Version." & Character'Val(10)
      	      & Character'Val(10) &
      	      "This Program is Distributed in The Hope That It Will Be Useful,"  & Character'Val(10) &
      	      "But WITHOUT ANY WARRANTY; Without Even The Implied Warranty of"  & Character'Val(10) &
      	      "MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.  See The"  & Character'Val(10) &
      	      "GNU General Public License for More Details."));
      --Set_Logo(About_Help,
      Set_Program_Name(About_Help, Glib.Convert.Locale_To_UTF8("Gmface"));
      --Set_translator_credits(About_Help,
      Set_Version(About_Help, Glib.Convert.Locale_To_UTF8(Gmface.Version));

      if Run (About_Help) /= Gtk_Response_Close then
         null;
      end if;
      Destroy (About_Help);
   end About_Action;

   
   ---------------------------------------------------
   --             Main menu aplication              --
   ---------------------------------------------------
   App_Main_Entries : constant Action_Entry_Array :=
     (1 => Create (Name => "MainMenu",        Label => "_Main"),
      2 => Create (Name => "Close",
      		   Stock_Id    => Stock_Close,
      		   Label       => "_Close Window",
      		   Accelerator => "<control>N",
      		   Tooltip     => "Close",
      		   Callback    => Close_action'Access),
      3 => Create (Name => "New",
      		   Stock_Id    => Stock_New,
      		   Label       => "_New",
      		   Accelerator => "<control>N",
      		   Tooltip     => "New",
      		   Callback    => New_action'Access),
      4 => Create (Name => "Open",
      		   Stock_Id    => Stock_Open,
      		   Label       => "_Open",
      		   Accelerator => "<control>O",
      		   Tooltip     => "Open",
      		   Callback    => Open_Action'Access),
      
      5 => Create (Name => "Quit",
      		   Stock_Id    => Stock_Quit,
      		   Label       => "_Quit",
      		   Accelerator => "<control>Q",
      		   Tooltip     => "Quit",
      		   Callback    => Quit_Action'Access),
      
      
      
      6 => Create (Name => "OptionsMenu",        Label => "_Options"),
      7 => Create (Name => "Preferences",
      		   Stock_Id    => Stock_Preferences,
      		   Label       => "Preferences",
      		   Accelerator => "<control>F",
      		   Tooltip     => "Preferences",
      		   Callback    => Preferences_Action'Access),
      8 => Create (Name => "HelpMenu",        Label => "_Help"),
      9 => Create (Name => "About",
      		   Stock_Id    => Stock_About,
      		   Label       => "About",
      		   Accelerator => "<control>B",
      		   Tooltip     => "About",
      		   Callback    => About_Action'Access)
     );
   
   
   App_Main_UI_Info : constant String :=
     "<ui>"
     & "  <menubar name='MenuBar'>"
     & "    <menu action='MainMenu'>"  
     & "      <menuitem action='Close'/>"
     & "      <menuitem action='New'/>"
     & "      <menuitem action='Open'/>"
     & "      <menuitem action='Quit'/>"
     & "    </menu>"
     & "    <menu action='OptionsMenu'>"          
     & "      <menuitem action='Preferences'/>"
     & "    </menu>" 
     & "    <menu action='HelpMenu'>"          
     & "      <menuitem action='About'/>"
     & "    </menu>"          
     & "  </menubar>"
     & "</ui>";
   --                                                  --
   ------------------------------------------------------         
   ------------------------------------------------------
   --
   
   --  ------------------------------------------------------
   --  --            Window menu actions                   --
   --  ------------------------------------------------------
   
   procedure Save_Action (Action, Main_Window : in System.Address);
   pragma Convention (C, Save_Action);
   --  Called when Save actions has been selected         
      
   procedure Start_Action(Action, Main_Window : in System.Address);
   pragma Convention (C, Start_Action);
   --  Called when start actions has been selected

   procedure Stop_Action (Action, Main_Window : in System.Address);
   pragma Convention (C, Stop_Action);
   --  Called when stop actions has been selected

   procedure Play_On_Action(Action, Main_Window : in System.Address);
   pragma Convention (C, Play_On_Action);
   --  Called when Play_on actions has been selected

   procedure Rec_On_Action (Action, Main_Window : in System.Address);
   pragma Convention (C, Rec_On_Action);
   --  Called when Rec_on actions has been selected

   procedure Play_Off_Action(Action, Main_Window : in System.Address);
   pragma Convention (C, Play_Off_Action);
   --  Called when Play_Off actions has been selected

   procedure Rec_Off_Action (Action, Main_Window : in System.Address);
   pragma Convention (C, Rec_Off_Action);
   --  Called when Rec_off actions has been selected
     
   
   --  ---------------------------------------------------
   --  --               Window(s) menu                  --
   --  ---------------------------------------------------
   Win_Main_Entries : constant Action_Entry_Array :=
     (1 => Create (Name => "FileMenu",        Label => "_File"),      
      2 => Create (Name => "Save",
      		   Stock_Id    => Stock_Save,
      		   Label       => "_Save",
      		   Accelerator => "<control>S",
      		   Tooltip     => "Save",
      		   Callback    => Save_Action'Access),      
      
      3 => Create (Name => "TransportMenu",        Label => "_Transport"),
      4 => Create (Name => "Start",
   		    Stock_Id    => Stock_Media_Play,
      		    Label       => "Start",
      		    Accelerator => "<alt>P",
      		    Tooltip     => "Start",
      		    Callback    => Start_Action'Access),
      5 => Create (Name => "Stop",
      		    Stock_Id    => Stock_media_Stop,
      		    Label       => "Stop",
      		    Accelerator => "<Control>P",
      		    Tooltip     => "Stop",
      		    Callback    => Stop_Action'Access),
      6 => Create (Name => "Rec_on",
      		    Stock_Id    => Stock_Media_Record,
      		    Label       => "Rec on",
      		    Accelerator => "<alt>C",
      		    Tooltip     => "Rec_on",
      		    Callback    => Rec_On_Action'Access),
      7 => Create (Name => "Play_on",
      		    Stock_Id    => Stock_Media_Play,
      		    Label       => "Play on",
      		    Accelerator => "<alt>P",
      		    Tooltip     => "Play_on",
      		    Callback    => Play_On_Action'Access),
      8 => Create (Name => "Rec_off",
      		    Stock_Id    => Stock_Media_stop,
      		    Label       => "Rec off",
      		    Tooltip     => "Rec_off",
		   Callback    => Rec_Off_Action'Access),
      9 => Create (Name => "Play_off",
      		    Stock_Id    => Stock_Media_Play,
      		    Label       => "Play off",
      		    Tooltip     => "Play_off",
      		    Callback    => Play_Off_Action'Access));
   

   Win_Main_UI_Info : constant String :=
     "<ui>"
     & "  <menubar name='MenuBar'>"
     & "    <menu action='FileMenu'>"
     & "      <menuitem action='Save'/>"     
     & "    </menu>"     
     & "    <menu action='TransportMenu'>"
     & "      <menuitem action='Start'/>"
     & "      <menuitem action='Stop'/>"
     & "      <menuitem action='Rec_on'/>"
     & "      <menuitem action='Play_on'/>"
     & "      <menuitem action='Rec_off'/>"
     & "      <menuitem action='Play_off'/>"
     & "    </menu>"     
     & "  </menubar>"
     & "</ui>";


   
   --
   ------------------------------------------------------
   
   type Gtk_Gmface_Work_Window_Access is access all Gtk_Gmface_Work_Window_Record;
   
   procedure Load_Window (Work_Window : Gtk_Gmface_Work_Window_Access;
			  Gtk_Int     : in Gtk_Interface_Pointer);
   
   package Gmface_Window_User_Return_Callback is 
      new Handlers.User_Return_Callback
     (Gtk_Window_Record, Boolean, Gtk_Interface_Pointer);
   
   package Gmface_Window_User_Callback is 
      new Handlers.User_Callback
     (Gtk_Window_Record, Gtk_Interface_Pointer);
   
   
   ------------------------------------------------------------------
   --                Initialize Gmface work Window                 --
   ------------------------------------------------------------------
   
   function Gmface_Initialize(Work          : in Work_Access;
			      Work_Id       : in Work_Num;
			      Process       : in Work_Processing_Access;
			      Gtk_Interface : in Gtk_Interface_Pointer) 
		      return Gtk_Work_Window_Pointer is
      
      Work_Window : constant Gtk_Work_Window_Pointer :=
	new Gtk_Gmface_Work_Window_Record(Work, Work_Id);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access :=
	Gtk_Gmface_Work_Window_Record(Work_Window.all)'Access;
      
      Error : aliased Gerror;
   begin
      
      --Put_Line("TITI 0.0");
      Work_Window.Process := Process;
      --Put_Line("TITI 0.0.0");
      Gmface_Work_Processing(Work_Window.Process.all).Process.Initialize;      
      --Put_Line("TITI 0.0.1");
      
      
      Application_Window.Gtk_New(Work_Window.Window, Gtk_Interface.Application);
      Application_Window.Set_Default_Size(Work_Window.Window, 1024, 768);
      Application_Window.Set_Title(Work_Window.Window, "Gmface [ " & Work.Filename.all &" ]");
      Application_Window.Set_Position(Work_window.Window, Win_Pos_Center_always);
      
      ---------------------------------------------------
      -- Global initialization :
      ---------------------------------------------------
      Gtk_New (Gmface_Window.Master_Frame, "Band Master");
      --Put_Line("TITI 0.2");
      Gtk_New_hbox(Gmface_Window.Main_Hbox);

      Gtk_New(Gmface_Window.Plugins_Frame, "Plugins");



      --Put_Line("TITI 0.4");
      Gtk_New (Gmface_Window.Flow_Frame, "Flow");
      
      Gtk_New (Gmface_Window.Devices_Frame, "Devices");
      --Put_Line("TITI 0.5");
      Gtk_New_Vpaned (Gmface_Window.Main_paned);
      Gtk_New_Hpaned (Gmface_Window.Flow_Paned);
      Pack1 (Gmface_Window.Flow_Paned, Gmface_Window.Flow_Frame);
      Add2 (Gmface_Window.flow_Paned, Gmface_Window.Devices_Frame);
      Set_Position (Gmface_Window.Flow_Paned, 600);
      --Put_Line("TITI 0.6");
      Gtk_New (Gmface_Window.State_Frame, "State");
      --Put_Line("TITI 0.7");
      Gtk_New_Vpaned (Gmface_Window.Main_Paned);
      Pack1 (Gmface_Window.Main_Paned, Gmface_Window.Plugins_Frame);
      Add2 (Gmface_Window.Main_Paned, Gmface_Window.Flow_Paned);
      Set_Position (Gmface_Window.Main_Paned, 350);
      --                                               --
      ---------------------------------------------------
      
      
      
      
      --Put_Line("TITI 0.8");
      ---------------------------------------------------
      --             Main menu application             --
      ---------------------------------------------------
      Gtk_New (Work_Window.App_Action_Group, "Actions");
      Add_Actions (Work_Window.App_Action_Group, App_Main_Entries,
		   Gtk_Interface_Conversions.To_Address (Gtk_Interface));
      
      Gtk_New (Work_Window.App_UI);
      --Put_Line("TITI 0.9");
      Insert_Action_Group (Work_Window.App_UI, Work_Window.App_Action_Group, 0);

      Add_Accel_Group
	(Work_Window.Window, Get_Accel_Group (Work_Window.App_UI));

      if Add_UI_From_String
      	(Work_Window.App_UI, App_Main_UI_Info, Error'Unchecked_Access) = 0 then
      	 Put_Line
      	   ("Building menus failed: " & Get_Message (Error));
      	 Error_Free (Error);
      end if;            
      Gtk_New_Hbox(Work_Window.Menus_Hbox, False, 0);
      --Put_Line("TITI 0.10");
      Gtk.Box.Pack_Start
	(Work_Window.Menus_Hbox,
	 Get_Widget (Work_Window.App_UI, "/MenuBar"),
	 Expand => False, Padding => 0);
      
      Gtk_New_Vbox(Work_Window.Main_Vbox, False, 0);
      
      Pack_Start(Work_Window.Main_Vbox, Work_Window.Menus_Hbox, false);
      --                                                             --
      -----------------------------------------------------------------
      
      -- Window app menu.
      --  --------------------------------------------------
      --  --             Window(s) menu                   --
      --  --------------------------------------------------
      --Put_Line("TITI 0.11");
      Gtk_New (Work_Window.Win_Action_Group, "Actions");
      Add_Actions (Work_Window.Win_Action_Group, Win_Main_Entries, Gtk_Work_Window_Conversions.To_Address (Work_Window));
      Gtk_New (Work_Window.Win_UI);

      Insert_Action_Group (Work_Window.Win_UI, Work_Window.Win_Action_Group, 0);

      Add_Accel_Group
      	(Work_Window.Window, Get_Accel_Group (Work_Window.Win_UI));

      if Add_UI_From_String
      	(Work_Window.Win_UI, Win_Main_UI_Info, Error'Unchecked_Access) = 0 then
      	 Put_Line
      	   ("Building menus failed: " & Get_Message (Error));
      	 Error_Free (Error);
      end if;                  
      
      Gtk.Box.Pack_Start
      	(Work_Window.Menus_Hbox,
      	 Get_Widget (Work_Window.Win_UI, "/MenuBar"),
      	 Expand => False, Padding => 0);
      -------------------------------------------------------
      --             End of All menus.                     --
      -------------------------------------------------------
      
      
      -----------------------------------------------------------------    
      --                                                             --            
      --Put_Line("TITI 0.12");
      Pack_Start (Gmface_Window.Main_Hbox, Gmface_Window.Master_Frame, False, False, 0);
      Pack_Start (Gmface_Window.Main_Vbox, Gmface_Window.Main_Hbox, False, False, 0);
      Pack_Start (Gmface_Window.Main_Vbox, Gmface_Window.Main_Paned, True, True, 0);
      Pack_Start (Gmface_Window.Main_Vbox, Gmface_Window.State_Frame, False, False, 0);


      --Put_Line("TITI 0.13");

      True_Table_Initialize(Gmface_Work_Record(work.all).Options.True_Table);
      
      Load_Window (Gmface_Window, Gtk_Interface);
      --Put_Line("TITI 0.14");
      Gmface_Window_User_Return_Callback.Connect
	(Work_Window.Window, "delete-event",
	 Gmface_Window_User_Return_Callback.To_Marshaller(Close_Window'Access),
	 Gtk_Interface);
      
      Gmface_Window_User_Callback.Connect
	(Work_Window.Window, "activate-focus",
	 Gmface_Window_User_Callback.To_Marshaller(Focus_Window'Access),
	 Gtk_Interface);
      
      
      --Put_Line("TITI 0.15");
      ------------------------------------------------
      --                                            --
      Add (Work_Window.Window, Work_Window.Main_Vbox);
      
      Application_Window.Show_All(Work_window.Window);
      --Put_Line("TITI 0.16");
      return Work_Window;
   end Gmface_Initialize;
   
   package Object_Callback is new Gtk.Handlers.User_Callback (GObject_Record, Gtk_Gmface_Work_Window_Record);
   
   
   
   
   package Gmface_Work_Window_Conversions
   is new System.Address_To_Access_Conversions
     (Gtk_Gmface_Work_Window_Record);
   
   
   package Pointer_Object_Callback is new Gtk.Handlers.User_Callback (GObject_Record, Gtk_Gmface_Work_Window_Access);
   
   
   procedure Text_Edited_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record);
      
   -----------------
   -- Custom_Sort --
   -----------------

   function Custom_Sort
     (Model : Gtk_Tree_Model;
      A, B  : Gtk_Tree_Iter) return Gint
   is
      Text_A : constant String := Get_String (Model, A, Text_Column);
      Text_B : constant String := Get_String (Model, B, Text_Column);
   begin

      if Text_A /= "" and then
	Text_A < Text_B then
         return -1;  --  A first
      elsif Text_B /= "" and then
	Text_A > Text_B then
         return 1;   --  Same
      else
         return 0;   --  B first
      end if;
   end Custom_Sort;


   function Add_Line
     (Model    : access Gtk_Tree_Store_Record'Class;
      names    : String;
      Ids      : string;
      Types    : String;
      Editable : Boolean := False;
      Muttable  : Boolean := False;
      Active   : Boolean := False;
      Parent   : Gtk_Tree_Iter := Null_Iter) return Gtk_Tree_Iter;

   
   procedure Load_Devices (Work_Window : access Gtk_Gmface_Work_Window_Record;
   			   Devices     : in Bandmaster_Record) is
                  
      
      
      Scrolled   : Gtk_Scrolled_Window;
      
      -- Comon Tree
      Col      : Gtk_Tree_View_Column;
      Num      : Gint;
      Text_Render   : Gtk_Cell_Renderer_Text;
      Toggle_Render : Gtk_Cell_Renderer_Toggle;
      Edit_Toggle_Render : Gtk_Cell_Renderer_Toggle;

      Parent, Iter  : Gtk_Tree_Iter;
      pragma Unreferenced (Num);
      pragma Warnings (Off, Iter);



      Input_Device           : Gtk_Combo_Box_Text;
      Output_Device          : Gtk_Combo_Box_Text;
      Devices_Lists          : Devices_List_Access;
      
      
      Devices_Names : String_Access := new String ' ("");

      Num_Devices : integer := -1;
      
   begin

      Gtk_New (Work_Window.Devices_Model,
   	       (Text_Column       => GType_String,
                Id_Column         => GType_String,
   		Type_Column       => GType_String,
                Editable_Column   => GType_Boolean,
                Active_Column     => GType_Boolean,
                Foreground_Column => GType_String,
   		Printable_Column  => GType_Boolean,
   		Muttable_Column   => GType_Boolean));

      Gtk_New (Work_Window.Devices_Tree, Work_Window.Devices_Model);
      Set_Grid_Lines (Work_Window.Devices_Tree, Grid_Lines_Vertical);
      Set_Enable_Tree_Lines (Work_Window.Devices_Tree, True);
      Set_Rubber_Banding (Work_Window.Devices_Tree, True);
      Set_Mode (Get_Selection (Work_Window.Devices_Tree), Selection_Multiple);
      Gtk_New (Scrolled);
      Set_Policy (Scrolled, Policy_Always, Policy_Always);
      Add (Scrolled, Work_Window.Devices_Tree);

      Add (Work_Window.Devices_Frame, Scrolled);

      Gtk_New (Text_Render);

      Gtk_New (Col);
      Num := Append_Column (Work_Window.Devices_Tree, Col);
      Set_Sort_Column_Id (Col, Text_Column);
      Set_Title (Col, "Name");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column);
      Add_Attribute (Col, Text_Render, "editable", Editable_Column);
      Object_Callback.Object_Connect
        (Text_Render, "edited", Text_Edited_Callback'Access,
   	 Slot_Object => Work_Window.Devices_Model,
   	 User_Data => Work_Window.all);


      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Devices_Tree, Col);

      Set_Title (Col, "Id");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Id_Column);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Devices_Tree, Col);

      Set_Title (Col, "Type");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Type_Column);


      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Work_Window.Devices_Tree, Col);
      Set_Title (Col, "Print");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Printable_Column);



      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Work_Window.Devices_Tree, Col);
      Set_Title (Col, "Mute");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Muttable_Column);
      

      Set_Headers_Clickable (Work_Window.Devices_Tree, True);
      Set_Sort_Func (+Work_Window.Devices_Model, Text_Column, Custom_Sort'Access);


      Parent := Null_Iter;
      if Devices.Inst_Last > 0 then
	 for Device_Id in 1..Instrument_Id(Devices.Inst_Last) loop	 
	    declare
	       Devices_Names : constant String :=
		 "Input  : " & Devices.Orchester(Device_Id).Input_Device_Driver.Device_Info.Name.all & Character'Val(10) &
		 "Output : " & Devices.Orchester(Device_Id).Output_Device_Driver.Device_Info.Name.all;
	    begin	      	 	 
	       Iter := Add_Line
		 (Work_Window.Devices_Model, "", Positive'image (Positive(Device_Id)), Devices_names,
		  Editable => False, Muttable => False, Active => False, Parent => parent);
	    end;
	 end loop;      
	 
	 
      end if;

      -- Show_All(Work_Window.Window);
      -- End Devices View

   end Load_Devices;
   
   
   
   package Window_Cb is new Gtk.Handlers.User_Callback
     (Gtk.Widget.Gtk_Widget_Record,
      Gtk_Gmface_Work_Window_Access);
   
   
   procedure Set_Tempo_Callback
     (Model  : access Gtk_Widget_Record'Class;
      User_Data : Gtk_Gmface_Work_Window_Access);

   procedure Set_Signature_Callback
     (Model  : access Gtk_Widget_Record'Class;
      User_Data : Gtk_Gmface_Work_Window_Access);

   procedure Track_Length_Callback
     (Widget  : access Gtk_Widget_Record'Class;
      User_Data : Gtk_Gmface_Work_Window_Access);

   
   procedure Set_Master_Form (Widget : access Gtk_Widget_Record'class;
			      Work_Window : Gtk_Gmface_Work_Window_Access);

   
   
   
   
   procedure Load_Master (Work_Window : Gtk_Gmface_Work_Window_Access;
			  Options  : in Gmface_Options_Record) is
      Form_Label : Gtk_Label;
   begin
      --Put_Line("TOTO 1.10.1");
      Gtk_New_Vbox (Work_Window.State_Box);
      Gtk_New_Hbox (Work_Window.Tools_Box);
      --Put_Line("TOTO 1.10.2");

      Gtk_New (Work_Window.State_Label, "Tempo :");
      Gtk_New (Work_Window.Tempo_Button, 1.0, 240.0, 0.1);
      Set_value (Work_Window.Tempo_Button, Gdouble(Options.Tempo));
      --Put_Line("TOTO 1.10.3");
      Window_Cb.Connect
        (Work_Window.Tempo_Button, "value_changed", Window_Cb.To_Marshaller(Set_Tempo_Callback'Access),
	 User_Data => Work_Window);
      Pack_Start (Work_Window.Tools_Box, Work_Window.State_Label, Expand => false);
      Pack_Start (Work_Window.Tools_Box, Work_Window.Tempo_Button, Expand => false);
      -- Time Signature.
      Gtk_New (Work_Window.Signature);
      --Put_Line("TOTO 1.10.4");
      Set_Text (Work_Window.Signature, Image (Options.Signature));
      Set_Editable (Work_Window.Signature, True);
      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Signature, Expand => False, Padding => 0);
      Window_Cb.Connect
        (Work_Window.Signature, "activate", Window_Cb.To_Marshaller(Set_Signature_Callback'Access),
	 User_Data => Work_Window);
      --Put_Line("TOTO 1.10.7");
      Gtk_New (Work_Window.State_Label, "Track length : ");
      Gtk_New (Work_Window.Track_Length_Button, 1.0, 65537.0, 1.0);
      Set_value (Work_Window.Track_Length_Button, Gdouble(Options.Track_Length));
      Pack_Start (Work_Window.Tools_Box, Work_Window.State_Label, Expand => false);
      Pack_Start (Work_Window.Tools_Box, Work_Window.Track_Length_Button, Expand => false);
      Window_Cb.Connect
        (Work_Window.Track_Length_Button, "value_changed", Window_Cb.To_Marshaller(Track_Length_Callback'Access),
	 User_Data => Work_Window);
      --Put_Line("TOTO 1.10.8");


      Gtk.Combo_Box_text.Gtk_New(Work_Window.Played_Form);
      for I in 0 .. Options.Forms_Names'Length-1 loop
      	 Gtk.Combo_Box_text.Insert_Text
	   (Work_Window.Played_Form, Glib.Gint(I),
	    Glib.Convert.Locale_To_UTF8(Options.Forms_names(Form_Index_Type(I+1)).all));
      end loop;
      --Put_Line("TOTO 1.10.9");
      Gtk.Combo_Box_text.Set_Active(Work_Window.Played_Form, Gint(Options.Current_Form-1));
      Gtk.Label.Gtk_New(Form_label, "Played form     : ");
      Gtk.Box.Pack_Start(Work_Window.Tools_Box, Form_Label, False, False, 0);
      Gtk.Box.Pack_Start(Work_Window.Tools_Box, Work_Window.Played_Form, False, False, 0);
      --Put_Line("TOTO 1.10.10");
      Window_Cb.Connect(Work_Window.Played_Form, "changed",
			Window_Cb.To_Marshaller(Set_Master_Form'Access),
			Work_Window);
      --Put_Line("TOTO 1.10.14");
      Pack_Start (Work_Window.State_Box, Work_Window.Tools_Box, Expand => False);
      --Put_Line("TOTO 1.10.15");
      Add (Work_Window.Master_Frame, Work_Window.State_Box);
      --Put_Line("TOTO 1.10.16");
   end Load_Master;
   
   
   procedure Set_Tempo_Callback
     (Model  : access Gtk_Widget_Record'Class;

      User_Data : Gtk_Gmface_Work_Window_Access) is
   begin
      Gmface_Work_Record(User_Data.Work.all).Options.Tempo := Tempo_Type(Get_Value(Gtk_Spin_Button(Model)));
      
      Set_Focus (User_Data.Window, Gtk_Widget (User_Data.Media_Play));
   exception
      when others =>
	 null;
   end Set_Tempo_Callback;


   procedure Set_Signature_Callback
     (Model  : access Gtk_Widget_Record'Class;

      User_Data : Gtk_Gmface_Work_Window_Access) is

      Number : Time_Number_Type   := 4;
      Unit   : Time_unit_Type := 4;

      Separator : constant Natural :=
	Fixed.Index
	(Glib.Convert.Locale_From_UTF8 (Get_Text (Gtk_Gentry (Model))), "/");
      Last      : constant Natural :=
	Fixed.Index_Non_Blank
	(Glib.Convert.Locale_From_UTF8 (Get_Text (Gtk_Gentry (Model))), backward);
   begin
      if Separator /= 0 then
      	 Number := Time_Number_Type'Value
	   (Glib.Convert.Locale_From_UTF8 (Get_Text (Gtk_Gentry (Model))) (1..Separator-1));
      	 Unit := Time_Unit_Type'Value
	   (Glib.Convert.Locale_From_UTF8 (Get_Text (Gtk_Gentry (Model))) (Separator+1..last));
      	 Gmface_Work_Record(User_Data.Work.all).Options.Signature := (Number, Unit);
	 
      	 Set_Focus (User_Data.Window, Gtk_Widget (User_Data.Media_Play));
      end if;
   exception
      when others =>
	 null;
   end Set_Signature_Callback;


   procedure Track_Length_Callback
     (Widget  : access Gtk_Widget_Record'Class;
      User_Data : Gtk_Gmface_Work_Window_Access) is
   begin
      Put_Line("Track length set...");
      Gmface_Work_Record(User_Data.Work.all).Options.Track_Length :=
	Integer(Get_Value(Gtk_Spin_Button(Widget)));
      Put_Line("Track length set to vale " & Positive'Image(Gmface_Work_Record(User_Data.Work.all).Options.Track_Length));
      Set_Focus (User_Data.Window, Gtk_Widget (User_Data.Media_Play));
   exception
      when others =>
	 null;
   end Track_Length_Callback;

   procedure Set_Master_Form (Widget : access Gtk_Widget_Record'class;
			      Work_Window : Gtk_Gmface_Work_Window_Access) is
   begin

      Gmface_Work_Record(Work_Window.Work.all).Options.Current_Form :=
	Form_Index_Type(Gtk.Combo_Box_text.Get_Active(Gtk_Combo_Box_text(widget))+1);
   end Set_Master_Form;

   --
   -----------------------------------------------------------------------------
   
   -----------------------------------------------------------------------------
   --
   procedure Load_Flow (Work_Window : access Gtk_Gmface_Work_Window_record) is
      --                 Buffer  : in Flow_Buffer_Type) is

      Scrolled   : Gtk_Scrolled_Window;

      -- Comon Tree
      Col      : Gtk_Tree_View_Column;
      Num      : Gint;
      Text_Render   : Gtk_Cell_Renderer_Text;
      Toggle_Render : Gtk_Cell_Renderer_Toggle;

      Parent, Iter  : Gtk_Tree_Iter;
      pragma Unreferenced (Num);
      pragma Warnings (Off, Iter);
   begin
      ------------------------------------------------
      -- Flow begin.
      Gtk_New (Scrolled);
      Set_Border_Width (Scrolled, 5);
      Set_Policy (Scrolled, Policy_Automatic, Policy_Automatic);

      Gtk_New (Work_Window.Flow_Model,
               (Text_Column       => GType_String,
                Text_Column+1       => GType_String,
		Text_Column+2       => GType_String,
		Text_Column+3       => GType_String,
		Text_Column+4       => GType_String,
		Text_Column+5       => GType_String,
		Text_Column+6       => GType_String,
		Text_Column+7       => GType_String,
		Text_Column+8       => GType_String));

      Gtk_New (Work_Window.Flow_Tree, Work_Window.Flow_Model);

      Set_Grid_Lines (Work_Window.Flow_Tree, Grid_Lines_Vertical);
      Gtk_New (Scrolled);
      Set_Policy (Scrolled, Policy_Always, Policy_Always);
      Add (Scrolled, Work_Window.Flow_Tree);

      add (Work_Window.Flow_Frame, Scrolled);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Source");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Destination");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+1);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Type");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+2);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Channel");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+3);


      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Data1");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+4);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Data2");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+5);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Time");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+6);



      Set_Sort_Column_Id (Col, Text_Column+6);
      Set_Headers_Clickable (Work_Window.Flow_Tree, True);
      Set_Sort_Func (+Work_Window.Flow_Model, Text_Column, Custom_Sort'Access);


      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Hexa");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+7);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Flow_Tree, Col);

      Set_Title (Col, "Long");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column+8);
      -- End Flow.
      ------------------------------------------------
   end Load_Flow;
   ---------------------------------------------------
   --
   
   --------------
   -- Add_Line --
   --------------

   function Add_Line
     (Model            : access Gtk_Tree_Store_Record'Class;
      Source           : String;
      Destination      : string;
      Types            : String;
      Channel          : String;
      Data1            : String;
      Data2            : string;
      Hour             : String;
      Hexa             : String;
      Long             : String;
      Parent   : Gtk_Tree_Iter := Null_Iter) return Gtk_Tree_Iter

   is
      Verax : Boolean := False;

      Iter   : Gtk_Tree_Iter;
   begin

      Append (Model, iter, Parent);

      Set (Model, Iter, Text_Column, Source);
      Set (Model, Iter, Text_Column+1, Destination);
      Set (Model, Iter, Text_Column+2, Types);
      Set (Model, Iter, Text_Column+3, channel);
      Set (Model, Iter, Text_Column+4, data1);
      Set (Model, Iter, Text_Column+5, data2);
      Set (Model, Iter, Text_Column+6, hour);
      Set (Model, Iter, Text_Column+7, hexa);
      Set (Model, Iter, Text_Column+8, long);

      Iter := Get_Iter_First(Model);



      return Iter;
   end Add_Line;

   function Flow_Print (Work_Window : Gtk_Gmface_Work_Window_Access) return Boolean is
      


      Message : Printed_Message_Access;
      Parent : Gtk_Tree_Iter := Null_Iter;
      Adj         : Gtk_Adjustment;

      Verax : Boolean := False;

   begin


      loop
	 Work_Window.Process.Box.Send(Message);
	 if (Message /= null) and then
	   Message.Source /= null then
	    Work_Window.Iter := Add_Line
	      (Work_Window.Flow_Model,
	       Message.Source.all,
	       Message.Destination.all,
	       Message.Data_Type.all,
	       Message.Channel.all,
	       Message.Data1.all,
	       Message.Data2.all,
	       Message.Hour.all,
	       Message.Hexa_Sum.all,
	       Message.Long_Sum.all,
	       Parent => parent);
	    Work_Window.Line_Counter := Work_Window.Line_Counter + 1;

	    Free(Message.Source);
	    Free(Message.Destination);
	    Free(Message.Data_Type);
	    Free(Message.Channel);
	    Free(Message.Data1);
	    Free(Message.Data2);
	    Free(Message.Hour);
	    Free(Message.Hexa_Sum);
	    Free(Message.Long_Sum);
	    
	    Free(Message);
	 else
	    exit;
	 end if;
      end loop;
      Work_Window.Iter := Get_Iter_First(Work_Window.Flow_Model);
      if Work_Window.Line_Counter > 64 then
	 for I in 32..Work_Window.Line_Counter loop

	    Parent := Work_Window.Iter;
	    Next(Work_Window.Flow_Model, Work_Window.iter);
	    Remove(Work_Window.Flow_Model, parent);
	    Work_Window.Line_Counter := Work_Window.Line_Counter - 1;


	 end loop;
      end if;            
      while Gtk.Main.Events_Pending loop
      	 Verax := Gtk.Main.Main_Iteration;
      end loop;
      
      Adj := Get_Vadjustment(Work_Window.Flow_Tree);
      
      Set_Value(Adj, Get_Upper(Adj) - Get_Page_Size(Adj));
      Set_Vadjustment(Work_Window.Flow_Tree, Adj);
      return True;
   end Flow_Print;
   
   --
   
   --
   
   function Work_State_Update (Work_Window : in Gtk_Gmface_Work_Window_Access) return Boolean;

   function Work_State_Update (Work_Window : in Gtk_Gmface_Work_Window_Access) return Boolean is

      Verax : Boolean := False;


      Years    : Natural;
      Months   : Natural;
      Days     : Natural;
      Houres   : Natural;
      Minutes  : Natural;
      Second   : Natural;
      Rest     : Duration;

      Timer_Hour : Duration := 0.0;
   begin

      Difference_In_Years(Gmface_Work_Record(Work_Window.Work.all).States.Start_time,
			  clock,
			  Years,
			  Months,
			  Days,
			  Houres,
			  Minutes,
			  Second,
			  Rest);

      Timer_Hour := Formatting.Seconds_Of(Houres, Minutes, Second, Rest);

      Set_Text(Work_Window.Elapsed, Integer_Image(Days) & "d, " & Formatting.Image(Timer_Hour, true));


      Set_Text (Work_Window.Position, Image (Gmface_Work_Record(Work_Window.Work.all).States.Bar_Beat));

      return True;
   end Work_State_Update;
   
   
   ----------
   -- Play --
   ----------
   procedure Play (Widget : access Gtk_Widget_Record'class;
                   Main_Window : in Gtk_Gmface_Work_Window_Access);

   ----------
   -- Stop --
   ----------
   procedure Stop (Widget : access Gtk_Widget_Record'class;
                   Main_Window : in Gtk_Gmface_Work_Window_Access);

   procedure Play_On (Widget : access Gtk_Widget_Record'class;
		      Main_Window : in Gtk_Gmface_Work_Window_Access);
   procedure Play_Off (Widget : access Gtk_Widget_Record'class;
		       Main_Window : in Gtk_Gmface_Work_Window_Access);
   procedure Reset (Widget : access Gtk_Widget_Record'class;
		    Main_Window : in Gtk_Gmface_Work_Window_Access);

   procedure Rec_On (Widget : access Gtk_Widget_Record'class;
		     Main_Window : in Gtk_Gmface_Work_Window_Access);
   procedure Rec_Off (Widget : access Gtk_Widget_Record'class;
		      Main_Window : in Gtk_Gmface_Work_Window_Access);

   
   procedure Load_State (Work_Window : Gtk_Gmface_Work_Window_Access) is
			 --State  : in Work_State_Type) is
   begin
      -- Transport begin.
      Gtk_New_Vbox (Work_Window.State_Box);

      ---------------
      -- Main Tools box --
      ---------------
      Gtk_New_Hbox (Work_Window.Tools_Box);
      Gtk_New_From_stock (Work_Window.Media_Play, Stock_Media_Play);

      Window_Cb.Connect
        (Work_Window.Media_Play, "clicked", Window_Cb.To_Marshaller (Play'access), Work_Window);
      
      Gtk_New_From_stock (Work_Window.Media_Stop, Stock_Media_Stop);
      
      Window_Cb.Connect
	(Work_Window.Media_Stop, "clicked", Window_Cb.To_Marshaller (Stop'access), Work_Window);


      
      Pack_Start (Work_Window.Tools_Box, Work_Window.Media_Play, Expand => false);
      Pack_Start (Work_Window.Tools_Box, Work_Window.Media_Stop, Expand => false);


      -- Modulation

      --------------------------
      -- Modulation Tools box --
      --------------------------


      Gtk.Button.Gtk_New (Work_Window.Modulation_Play_On, "Play on");
      Window_Cb.Connect
        (Work_Window.Modulation_Play_On, "clicked", Window_Cb.To_Marshaller(Play_On'Access),
	 User_Data => Work_Window);


      Gtk.Button.Gtk_New (Work_Window.Modulation_Play_Off, "Play off");
      Window_Cb.Connect
        (Work_Window.Modulation_Play_Off, "clicked", Window_Cb.To_Marshaller(Play_Off'Access),
	 User_Data => Work_Window);


      Gtk.Button.Gtk_New (Work_Window.Modulation_Record_On, "Rec on");
      Window_Cb.Connect
        (Work_Window.Modulation_Record_On, "clicked", Window_Cb.To_Marshaller(Rec_On'Access),
	 User_Data => Work_Window);



      Gtk.Button.Gtk_New (Work_Window.Modulation_Record_Off, "Rec off");
      Window_Cb.Connect
        (Work_Window.Modulation_Record_off, "clicked", Window_Cb.To_Marshaller(Rec_Off'Access),
	 User_Data => Work_Window);



      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Modulation_Play_on, Expand => false);
      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Modulation_Play_off, Expand => false);

      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Modulation_Record_on, Expand => false);
      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Modulation_Record_off, Expand => false);

      -- Mod reset --

      Gtk.Button.Gtk_New_From_Stock (Work_Window.Mod_Reset, Stock_delete);
      Window_Cb.Connect
        (Work_Window.Mod_Reset, "clicked", Window_Cb.To_Marshaller(Reset'Access),
	 User_Data => Work_Window);


      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Mod_Reset, Expand => False);

      Pack_Start (Work_Window.State_Box, Work_Window.Tools_Box, Expand => False);


      -- Timers --
      -- Tools box.

      Gtk_New_Hbox (Work_Window.Tools_Box);



      -- bar_beat.
      Gtk_New (Work_Window.Position);
      Set_Text (Work_Window.Position, Image (Gmface_Work_Record(Work_Window.Work.all).States.Bar_Beat));
      Set_Editable (Work_Window.Position, False);
      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Position, Expand => False, Padding => 2);


      -- Elapsed.

      Gtk_New (Work_Window.Elapsed);
      Set_Text(Work_Window.Elapsed, Integer_Image(0) & "d, " & Formatting.Image(0.0, true));
      Set_Editable (Work_Window.Elapsed, False);
      Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.Elapsed, Expand => False, Padding => 0);
      
      
      --  Gtk_New (Work_Window.In_Loop);
      --  Gtk_New (Work_Window.State_Label, "In loop : ");
      --  Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.State_Label, Expand => False, Padding => 0);
      --  Gtk.Box.Pack_Start (Work_Window.Tools_Box, Work_Window.In_Loop, Expand => False, Padding => 0);

      --  Set_Active (Work_Window.In_Loop, False);
      --  Window_Cb.Connect
      --    (Work_Window.In_Loop, "toggled", Window_Cb.To_Marshaller(Set_In_loop'Access),
      --  	 User_Data => Work_Window,
      --  	 After => false);

      Pack_Start (Work_Window.State_Box, Work_Window.Tools_Box, Expand => False, Padding => 2);
      --Put_Line("TOTO 2.2");
      Add (Work_Window.State_Frame, Work_Window.State_Box);
   end Load_State;
   
   ---------------------------------------------------------
   --
   
   package Gmface_G_Source is new Glib.Main.Generic_Sources(Gtk_Gmface_Work_Window_Access);
   
   procedure Play (Widget : access Gtk_Widget_Record'class;
                   Main_Window : in Gtk_Gmface_Work_Window_Access) is
      
      pragma Unreferenced (Widget);
   begin

      if Main_Window.Flow_Control = Glib.Main.No_Source_Id then
	 Main_Window.Flow_Control :=
	   Gmface_G_Source.Timeout_Add
	   (1,
	    Flow_Print'Access,
	    Main_Window);
      end if;
      if Main_Window.State_Control = Glib.Main.No_Source_Id then
	 Main_Window.State_Control :=
	   Gmface_G_Source.Timeout_Add
	   (100,
	    Work_State_Update'Access,
	    Main_Window);
      end if;
      Gmface_Work_Processing(Main_Window.Process.all).Process.Start;
   end Play;

   procedure Stop (Widget : access Gtk_Widget_Record'class;
                   Main_Window : in Gtk_Gmface_Work_Window_Access) is

      pragma Unreferenced (Widget);

   begin      
      if Main_Window.Flow_Control /= Glib.Main.No_Source_Id then
	 
	 Glib.Main.Remove(Main_Window.Flow_Control);
	 Main_Window.Flow_Control := Glib.Main.No_Source_Id;
      end if;
      if Main_Window.State_Control /= Glib.Main.No_Source_Id then
	 
	 Glib.Main.Remove(Main_Window.State_Control);
	 Main_Window.State_Control := Glib.Main.No_Source_Id;
      end if;
      Put_Line("Stopping work process...");
      
      Gmface_Work_Processing(Main_Window.Process.all).Process.Stop;

      Put_Line("Work process stopped.");      
   end Stop;

   
   -------------------------------------------------------
   -- Modulation Sequencer :                            --
   -------------
   -- Play On --
   -------------
   procedure Play_On (Widget : access Gtk_Widget_Record'class;
		      Main_Window : in Gtk_Gmface_Work_Window_Access) is
   begin
      
      Gmface_Work_Processing(Main_Window.Process.all).Process.Mod_Play(True);
   end Play_On;

   --------------
   -- Play Off --
   --------------
   procedure Play_Off (Widget : access Gtk_Widget_Record'class;
		       Main_Window : in Gtk_Gmface_Work_Window_Access) is
   begin

      Gmface_Work_Processing(Main_Window.Process.all).Process.Mod_Play(False);
   end Play_Off;

   ---------------
   -- Record On --
   ---------------
   procedure Rec_On (Widget : access Gtk_Widget_Record'class;
		     Main_Window : in Gtk_Gmface_Work_Window_Access) is
   begin

      Gmface_Work_Processing(Main_Window.Process.all).Process.Mod_Rec(True);
   end Rec_On;

   ----------------
   -- Record Off --
   ----------------
   procedure Rec_Off (Widget : access Gtk_Widget_Record'class;
		      Main_Window : in Gtk_Gmface_Work_Window_Access) is
   begin

      Gmface_Work_Processing(Main_Window.Process.all).Process.Mod_Rec(False);
   end Rec_Off;


   -----------
   -- Reset --
   -----------
   procedure Reset (Widget : access Gtk_Widget_Record'class;
		    Main_Window : in Gtk_Gmface_Work_Window_Access) is
   begin
      Gmface_Work_Processing(Main_Window.Process.all).Process.Mod_Reset;
   end Reset;

   --
   ---------------------------------------------------
   
   ---------------------------------------------------
   --
   procedure Plugin_Printed_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record
     );

   procedure Plugin_Edited_Callback
     (Model  : access GObject_Record'Class;
            Params : Glib.Values.GValues;
	    User_Data : Gtk_Gmface_Work_Window_access
     );

   procedure Plugin_Mutted_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record
     );

   procedure Create_Plugin_Page (Model  : access GObject_Record'Class;
				 Params : in Glib.Values.GValues;
				 Work_Window : in Gtk_Gmface_Work_Window_Access;
				 Plugin : in Abstract_Plugin_Access;
				 Id : in Plugin_Num);


   procedure Name_Edited_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record)

   is
      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);
      Path_String : constant String := Get_String (Nth (Params, 1));
      Name_Value  : constant GValue := Nth (Params, 2);
      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);

      Id : Plugin_Num := 1;

   begin
      Id := Plugin_Num'Value
	(Get_String (M, Get_Iter_From_String
		       (M, Get_String (Nth (Params, 1))), Id_Column));

      if User_Data.Work.Plugins (Id) /= null then
	 User_Data.Work.Plugins (Id).Name := new String ' (Get_String(Name_Value));
	 Set_Value (M, Iter, Text_Column, Name_Value);
      end if;
   end Name_Edited_Callback;

   
   function Add_True_Line
     (Model    : access Gtk_Tree_Store_Record'Class;
      Id     : Integer;
      Null_Break : Boolean;
      Down_Break : Boolean;
      Up_Break : Boolean;
      Full_Break : Boolean;
      Parent   : Gtk_Tree_Iter := Null_Iter) return Gtk_Tree_Iter;

   line_Column   : constant := 0;
   Null_Column : constant := 1;
   Down_Column : constant := 2;
   Up_Column : constant := 3;
   Full_Column : constant := 4;


   function Add_True_Line
     (Model    : access Gtk_Tree_Store_Record'Class;
      Id     : Integer;
      Null_Break : Boolean;
      Down_Break : Boolean;
      Up_Break : Boolean;
      Full_Break : Boolean;
      Parent   : Gtk_Tree_Iter := Null_Iter) return Gtk_Tree_Iter is
      Iter     : Gtk_Tree_Iter;
   begin
      --Put_Line("Add true line 0.0");
      Append (Model, Iter, Parent);
      --Put_Line("Add true line 0.1");
      Set (Model, Iter, line_Column, Break_Type'Image(Break_Type'Val(Id)));
      --Put_Line("Add true line 0.2");
      Set (Model, Iter, Null_Column, Null_break);
      --Put_Line("Add true line 0.3");
      Set (Model, Iter, Down_Column, Down_break);
      --Put_Line("Add true line 0.4");
      Set (Model, Iter, Up_Column, Up_break);
      --Put_Line("Add true line 0.5");
      Set (Model, Iter, Full_Column, Full_break);
      return Iter;
   end Add_True_Line;


   procedure Load_True_Table (Work_Window : in Gtk_Gmface_Work_Window_Access;
			      Page : in out Plugin_Page_Type;
			      Plugin : in Abstract_Plugin_Access
			     ) is

      Scrolled   : Gtk_Scrolled_Window;

      -- Comon Tree
      Col      : Gtk_Tree_View_Column;
      Num      : Gint;
      Text_Render   : Gtk_Cell_Renderer_Text;
      Toggle_Render : Gtk_Cell_Renderer_Toggle;

      Parent, Iter  : Gtk_Tree_Iter;
      pragma Unreferenced (Num);
      pragma Warnings (Off, Iter);
   begin
      --Put_Line("Load_table 1.0");
      Gtk_New (Page.True_Table_Model,
	       (line_Column          => GType_String,
		Null_column         => GType_Boolean,
		Down_Column         => GType_Boolean,
		Up_Column         => GType_Boolean,
		Full_Column       => GType_Boolean)
	      );

      --Put_Line("Load_table 1.1");
      Gtk_New (Page.True_Table_Tree, Page.True_Table_Model);
      --Put_Line("Load_table 1.1.1");
      Set_Grid_Lines (Page.True_Table_Tree, Grid_Lines_Vertical);
      --Put_Line("Load_table 1.1.2");
      Set_Enable_Tree_Lines (Page.True_Table_Tree, True);
      --Put_Line("Load_table 1.1.3");
      Set_Rubber_Banding (Page.True_Table_Tree, True);
      --Put_Line("Load_table 1.1.4");
      Set_Mode (Get_Selection (Page.True_Table_Tree), Selection_Multiple);
      --Put_Line("Load_table 1.1.5");
      Gtk_New (Scrolled);
      --Put_Line("Load_table 1.1.6");
      Set_Policy (Scrolled, Policy_Always, Policy_Always);
      --Put_Line("Load_table 1.1.7");
      Add_With_Viewport (Scrolled, Page.True_Table_Tree);
      --Put_Line("Load_table 1.1.8");
      Add (Page.True_Table_Frame, Scrolled);
      --Add (Page.True_Table_Frame, Page.True_Table_Tree);


      --Put_Line("Load_table 1.2");
      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Page.True_Table_Tree, Col);
      Set_Sort_Column_Id (Col, Line_Column);
      Set_Title (Col, "Id");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", line_Column);


      --Put_Line("Load_table 1.3");
      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Page.True_Table_Tree, Col);
      Set_Title (Col, "null break");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Null_Column);


      --Put_Line("Load_table 1.4");
      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Page.True_Table_Tree, Col);
      Set_Title (Col, "down break");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Down_Column);

      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Page.True_Table_Tree, Col);
      Set_Title (Col, "up break");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Up_Column);


      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Page.True_Table_Tree, Col);
      Set_Title (Col, "Full break");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Full_Column);


      --------------------------------------------------------
      -- READING FILE HERE.
      -------------------------------------------------------
      Parent := Null_Iter;

      if Plugin /= null then
	 for Prev_id in Break_Type loop
	    --Put_Line("Load_table 1.1");
	    Iter := Add_True_Line

	      (
	       Page.True_Table_Model,
	       Id => Break_Type'Pos(Prev_Id),
	       Null_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(Plugin.Cat_Id, Prev_Id, Null_Break),

	       Down_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(Plugin.Cat_Id, Prev_Id, Down_break),

	       Up_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(Plugin.Cat_Id, Prev_Id, Up_break),

	       Full_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(Plugin.Cat_Id, Prev_Id, Full_Break),
	       Parent => Parent);
	    --Put_Line("Load_table 1.2");
	 end loop;
      else

	 for Prev_id in Break_Type loop
	    --Put_Line("Load_table 1.1");
	    Iter := Add_True_Line

	      (
	       Page.True_Table_Model,
	       Id => Break_Type'Pos(Prev_Id),
	       Null_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(1, Prev_Id, Null_Break),

	       Down_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(1, Prev_Id, Down_break),

	       Up_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(1, Prev_Id, Up_break),

	       Full_Break => Gmface_Work_Record(Work_Window.Work.all).Options.True_Table(1, Prev_Id, Full_Break),
	       Parent => Parent);
	    --Put_Line("Load_table 1.2");
	 end loop;
      end if;

      --Put_Line("End True_Table View");


   end Load_True_Table;

   
   package Plugin_CB is new Gtk.Handlers.User_Callback
     (Gtk_Widget_Record,
      Gmface_Plugin_Access);
   
   procedure Set_Form (Widget : access Gtk_Widget_Record'class;
   		       plugin : Gmface_Plugin_Access) is
   begin
      if Plugin /= null then
   	 Plugin.Form_Id := Form_Index_Type(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box_text(widget))+1);
      end if;
   end Set_Form;

   procedure Set_Category (Widget : access Gtk_Widget_Record'class;
   			   Plugin : Gmface_Plugin_Access) is
   begin
      if Plugin /= null then
   	 Plugin.Cat_Id := Category_Index_Type(Get_Active(Gtk_Combo_Box_Text(widget))+1);
      end if;
   end Set_Category;


   procedure Load_Plugin_Page (Work_Window : in Gtk_Gmface_Work_Window_Access;
			       Page : in out Plugin_Page_Type;
			       Plugin : in Abstract_Plugin_Access;
			       Id : in Plugin_Num) is
   begin
      Page.Plugin_Id := Id;
      --Put_Line("Plug 2.1");
      if Plugin /= null then
	 Page.Plugin_Spec := Initialize(Plugin.Class, Plugin, Id);--New Step_Seq_Specifications;
								  --  case Plugin.Class is
      end if;
      
      Load_True_Table (Work_Window, Page, Plugin_Class(Plugin.all)'access);
      --Put_Line("Plug 2.4");
   end Load_Plugin_Page;




   procedure Create_Plugin_Page (Model  : access GObject_Record'Class;
				 Params : in Glib.Values.GValues;
				 Work_Window : in Gtk_Gmface_Work_Window_Access;
				 Plugin : in Abstract_Plugin_Access;
				 Id : in Plugin_Num) is

      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);
      Path_String : constant String := Get_String (Nth (Params, 1));
      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);

      Value : Gvalue;

      Dialog  : Gtk_Dialog;
      Ok      : Gtk.Widget.Gtk_Widget;
      Cancel  : Gtk.Widget.Gtk_Widget;
      Label   : Gtk_Label;
      Vbox    : Gtk_Box;


      Class : Plugin_Enum := Null_Plugin;


      Hbox : Gtk_Box;
      Timbre_Category_Label : Gtk_Label;
      Channel_Label         : Gtk_Label;
      Form_Label            : Gtk_Label;
      Device_Label          : Gtk_Label;

   begin

      declare

	 Class_Dialog : Gtk_Dialog;
	 Ok           : Gtk.Widget.Gtk_Widget;
	 Cancel       : Gtk.Widget.Gtk_Widget;
	 Vbox         : Gtk_Box;
	 Classes      : Gtk_Combo_Box_text;
      begin

	 Gtk.Dialog.Gtk_New(Class_Dialog, "Plugin id" & Plugin_Num'Image(Id), Gtk_Window(Work_Window.Window), Gtk.Dialog.Modal);
	 Set_Default_Size(Class_Dialog, 200, 75);
	 Vbox := Get_Content_area(Class_Dialog);
	 Ok := Gtk.Dialog.Add_button(Class_Dialog, "Ok", Gtk.Dialog.Gtk_Response_Ok);
	 Cancel := Gtk.Dialog.Add_button(Class_Dialog, "Cancel", Gtk.Dialog.Gtk_Response_Cancel);
	 Gtk.Combo_Box_Text.Gtk_New(classes);
	 for I in 0..Plugin_Enum'Pos(Plugin_Enum'Last)-1 loop
	    Gtk.Combo_Box_Text.Insert_Text
	      (Classes, Glib.Gint(I), Glib.Convert.Locale_To_UTF8(Plugin_Enum'Image(Plugin_Enum'Val(I))));
	 end loop;
	 if Plugin = null then
	    Gtk.Combo_Box_Text.Set_Active(Classes, Gint(0));
	 else
	    Gtk.Combo_Box_Text.Set_Active(Classes, Plugin_Enum'Pos(Plugin.Class));
	 end if;
	 Pack_Start(Vbox, Classes);
	 Show_All(Vbox);
	 case Run(Class_Dialog) is
	    when Gtk_Response_Ok =>
	       --Put_Line("Plugin select 0.0.0");
	       Class := Plugin_Enum'Val(Gtk.Combo_Box_Text.Get_Active(Classes));
	       --Put_Line("Plugin select 0.0.1");
	       --if Class /= Null_Plugin then
		  --Put_Line("Plugin select 0.0.2");
	       if Work_Window.Work.Plugins (Id) = null or else
		    Work_Window.Work.Plugins (Id).Class /= Class then
		     --Put_Line("Plugin select 0.0.3");
		  Work_Window.Work.Plugins (Id) :=
		    Initialize(class, Id, 1, 1, 1, 1);
		     --Put_Line("Plugin select 0.0.4");
		  end if;
		  --Put_Line("Plugin select 0.0.5");
	       --end if;
	       --Put_Line("Plugin select 0.0.6");
	       Work_Window.Plugins_Pages(Id) := new Plugin_Page_Type;
	       --Load_Plugin_Page(Work_Window, Work_Window.Plugins_Pages(Id).all, Work_Window.Work.Plugins (Id), Id);
	       --Put_Line("Plugin select 0.0.7");
	       Destroy(Class_Dialog);
	    when Gtk_Response_Cancel =>
	       Destroy(Class_Dialog);
	       return;
	    when others =>
	       Destroy(Class_Dialog);
	       return;
	 end case;
      end;
      if Class /= Null_Plugin then
	 --Put_Line("CUCU 0.1.1");
	 Gtk.Dialog.Gtk_New(Dialog, "Plugin " & Plugin_Num'Image(Id), Gtk_Window(Work_Window.Window), Gtk.Dialog.Modal);
	 Set_Default_Size(Dialog, 1024, 768);

	 Vbox := Get_Content_area(Dialog);
	 --Put_Line("CUCU 0.1.1.1");
	 --Put_Line("CUCU 0.1.1.2");
	 Ok := Gtk.Dialog.Add_button(Dialog, "Ok", Gtk.Dialog.Gtk_Response_Ok);
	 Cancel := Gtk.Dialog.Add_button(Dialog, "Cancel", Gtk.Dialog.Gtk_Response_Cancel);



	 --Put_Line("Plug 1.0");
	 Gtk_New (Work_Window.Plugins_Pages(Id).Page_Handler, "N°" & Plugin_Num'Image (Id));
	 --Put_Line("Plug 1.1");
	 Gtk_New (Work_Window.Plugins_Pages(Id).Plugin_Frame);
	 --Put_Line("Plug 1.2");

	 --Put_Line("Plug 1.3");
	 Gtk_New (Work_Window.Plugins_Pages(Id).Details_Frame, "Details");
	 --Put_Line("Plug 1.4");
	 Gtk_New (Work_Window.Plugins_Pages(Id).True_Table_Frame, "True Table");
	 --Put_Line("Plug 1.5");
	 Gtk_New_Hpaned (Work_Window.Plugins_Pages(Id).Plugin_Paned);
	 --Put_Line("Plug 1.6");
	 Gtk_New_Vpaned (Work_Window.Plugins_Pages(Id).Options_Paned);
	 --Put_Line("Plug 1.7");
	 Pack1 (Work_Window.Plugins_Pages(Id).Options_Paned, Work_Window.Plugins_Pages(Id).Details_Frame);
	 --Put_Line("Plug 1.8");
	 Add2 (Work_Window.Plugins_Pages(Id).Options_Paned, Work_Window.Plugins_Pages(Id).True_Table_Frame);
	 --Put_Line("Plug 1.9");
	 Set_Position (Work_Window.Plugins_Pages(Id).Options_Paned, 350);

	 Load_Plugin_Page(Work_Window, Work_Window.Plugins_Pages(Id).all, Work_Window.Work.Plugins (Id), Id);
	 --Put_Line("Plug 1.10");

	 if Work_Window.Plugins_Pages(Id).Plugin_Spec /= null then
	    Pack1 (Work_Window.Plugins_Pages(Id).Plugin_Paned, Work_Window.Plugins_Pages(Id).Plugin_Spec.Specifications_Frame);
	 end if;
	 --Put_Line("Plug 1.11");
	 Add2 (Work_Window.Plugins_Pages(Id).Plugin_Paned, Work_Window.Plugins_Pages(Id).Options_Paned);
	 --Put_Line("Plug 1.12");
	 Set_Position (Work_Window.Plugins_Pages(Id).Plugin_Paned, 550);
	 --Put_Line("Plug 1.13");
	 Pack_Start(Vbox, Work_Window.Plugins_Pages(Id).Plugin_Paned);
	 --Append_Page (Work_Window.Plugins_Notebook, Work_Window.Plugins_Pages(Id).Plugin_Paned, Work_Window.Plugins_Pages(Id).Page_Handler);
	 --Put_Line("Plug 1.14");

	 ---------------------------------------------------------------------------
	 Gtk_New_Vbox(Work_Window.Plugins_Pages(Id).Details_Box);
	 --Put_Line("Plug 1.15");

	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
	 --Put_Line("Plug 1.16");
	 Gtk.Combo_Box_Text.Gtk_New(Work_Window.Plugins_Pages(Id).Device_Id);
	 --Put_Line("Plug 2.2.0");
	 for I in 0..Device_num'Last-1 loop
	    Gtk.Combo_Box_Text.insert_Text(Work_Window.Plugins_Pages(Id).Device_Id, Glib.Gint(I), Natural'Image(Natural(I+1)));
	 end loop;

	 if Plugin /= null then
	    --Put_Line("Plug 2.2.0.1 plugin full");
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Device_Id, Gint(Plugin.Device_id-1));
	 else
	    --Put_Line("Plug 2.2.0.1 Plugin empty");
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Device_Id, Gint(0));
	 end if;
	 Gtk.Label.Gtk_New(Device_Label, "Device Id             :             ");
	 --Put_Line("Plug 2.2.0.2");
	 Gtk.Box.Pack_Start(Hbox, Device_Label, False, False, 0);
	 Gtk.Box.Pack_Start(Hbox, Work_Window.Plugins_Pages(Id).Device_Id, False, False, 0);
	 --Put_Line("Plug 2.2.0.3");
	 Gtk.Box.Pack_Start(Work_Window.Plugins_Pages(Id).Details_Box, Hbox, False, False, 0);
	 --Put_Line("Plug 2.2.0.4");
	 --Plugin_Cb.Connect(Work_Window.Plugins_Pages(Id).Device_Id, "changed",
	 --		Plugin_Cb.To_Marshaller(Set_Device_Id'Access),
	 --		Plugin);
	 --Put_Line("Plug 2.2.1");
	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
	 Gtk.Combo_Box_Text.Gtk_New(Work_Window.Plugins_Pages(Id).Timbre_Channel);
	 for I in 0..15 loop
	    Gtk.Combo_Box_Text.insert_Text(Work_Window.Plugins_Pages(Id).Timbre_Channel, Glib.Gint(I), Natural'Image(I+1));
	 end loop;
	 if Plugin /= null then
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Timbre_Channel, Gint(Plugin.Ch_Id-1));
	 else
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Timbre_Channel, Gint(0));
	 end if;


	 Gtk.Label.Gtk_New(Channel_Label, "Num channel       :                ");
	 Gtk.Box.Pack_Start(Hbox, Channel_Label, False, False, 0);
	 Gtk.Box.Pack_Start(Hbox, Work_Window.Plugins_Pages(Id).Timbre_Channel, False, False, 0);
	 Gtk.Box.Pack_Start(Work_Window.Plugins_Pages(Id).Details_Box, Hbox, False, False, 0);
	 --  Plugin_Cb.Connect(Work_Window.Plugins_Pages(Id).Timbre_Channel, "changed",
	 --  			Plugin_Cb.To_Marshaller(Set_Channel'Access),
	 --  			Plugin);
	 --Put_Line("Plug 2.2.2");
	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
	 Gtk.Label.Gtk_New(Timbre_Category_Label, "Timbre category :");
	 Gtk.Combo_Box_Text.Gtk_New(Work_Window.Plugins_Pages(Id).Timbre_Category);
	 for I in 0 .. Gmface_Work_Record(Work_Window.Work.all).Options.Categories.Last - 1 loop
	    Gtk.Combo_Box_Text.Insert_Text
	      (Work_Window.Plugins_Pages(Id).Timbre_Category,
	       Glib.Gint(I),
	       Gmface_Work_Record(Work_Window.work.all).Options.Categories.category(I + 1).all);
	 end loop;
	 if Plugin /= null then
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Timbre_Category, Gint(Plugin.Cat_Id-1));
	 else
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Timbre_Category, Gint(0));
	 end if;
	 Gtk.Box.Pack_Start(Hbox, Timbre_Category_label, False, False);
	 Gtk.Box.Pack_Start(Hbox, Work_Window.Plugins_Pages(Id).Timbre_Category, False, False);
	 Gtk.Box.Pack_Start(Work_Window.Plugins_Pages(Id).Details_Box, hbox, False, False);
	 Plugin_Cb.Connect(Work_Window.Plugins_Pages(Id).Timbre_Category, "changed",
			   Plugin_Cb.To_Marshaller(Set_Category'Access),
			   Gmface_Plugin_Class(Plugin.all)'Access);
	 --  Window_Cb.Connect(Work_Window.Plugins_Pages(Id).Timbre_Category, "changed",
	 --  			Window_Cb.To_Marshaller(True_Table_Changed'Access),
	 --  			Work_Window);
	 --Put_Line("Plug 2.2.3");
	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
	 Gtk.Combo_Box_Text.Gtk_New(Work_Window.Plugins_Pages(Id).Played_Form);
	 for I in 0 .. Gmface_Work_Record(Work_Window.Work.all).Options.Forms_Names'Length-1 loop
	    Gtk.Combo_Box_Text.Insert_Text
	      (Work_Window.Plugins_Pages(Id).Played_Form, Glib.Gint(I),
	       Glib.Convert.Locale_To_UTF8(Gmface_Work_Record(Work_Window.work.all).Options.Forms_names(Form_Index_Type(I+1)).all));
	 end loop;
	 if Plugin /= null then
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Played_Form, Gint(Plugin.Form_id-1));
	 else
	    Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Played_Form, Gint(0));
	 end if;
	 Gtk.Label.Gtk_New(Form_label, "Played form     : ");
	 Gtk.Box.Pack_Start(Hbox, Form_Label, False, False, 0);
	 Gtk.Box.Pack_Start(Hbox, Work_Window.Plugins_Pages(Id).Played_Form, False, False, 0);
	 Gtk.Box.Pack_Start(Work_Window.Plugins_Pages(Id).Details_Box, Hbox, False, False, 0);
	 Plugin_Cb.Connect(Work_Window.Plugins_Pages(Id).Played_Form, "changed",
	 			Plugin_Cb.To_Marshaller(Set_Form'Access),
	 			Gmface_Plugin_Class(Plugin.all)'Access);
	 --  Window_Cb.Connect(Work_Window.Plugins_Pages(Id).Played_Form, "changed",
	 --  			Window_Cb.To_Marshaller(True_Table_Changed'Access),
	 --  			Work_Window);
	 --Put_Line("Plug 2.2.4");
	 --Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
	 --  Gtk.Combo_Box_Text.Gtk_New(Work_Window.Plugins_Pages(Id).Algo_Combo_Box);
	 --  for I in Algo_Type'Range loop
	 --  	 Gtk.Combo_Box_Text.insert_Text(Work_Window.Plugins_Pages(Id).Algo_Combo_box, Glib.Gint(Algo_Type'Pos(I)), Algo_Type'Image(I));
	 --  end loop;
	 --  Gtk.Combo_Box_Text.Set_Active(Work_Window.Plugins_Pages(Id).Algo_Combo_Box, Gint(Algo_Type'Pos(Plugin.Algo)));
	 --  Gtk.Label.Gtk_New(Form_label, "Algo :");

	 --Gtk.Box.Pack_Start(Hbox, Work_Window.Plugins_Pages(Id).Algo_Combo_Box, False, False, 0);

	 --Plugin_Cb.Connect(Work_Window.Plugins_Pages(Id).Algo_Combo_Box, "changed",
	 --		Plugin_Cb.To_Marshaller(Set_Algo'Access),
	 --		Plugin);

	 --Put_Line("Plug 2.2.5");
	 Add(Work_Window.Plugins_Pages(Id).Details_Frame, Work_Window.Plugins_Pages(Id).Details_Box);
	 --Put_Line("Plug 2.2.6");
	 --                                                                        --
	 ----------------------------------------------------------------------------


	 --Put_Line("Plug 2.10");
	 --  Work_Window.Plugins_Pages(Id).Page_Num :=
	 --  	Get_N_Pages (Work_Window.Plugins_Notebook);
	 --Put_Line("Plug 2.11");
	 Work_Window.Plugins_pages (Id).Opened := True;
	 --Put_Line("Plug 2.12");

	 --rk_Window.Work.Plugins (Id).Opened := True;
	 --Put_Line("Plug 2.13");
	 --Show_All (Work_Window.Plugins_Notebook);
	 --Put_Line("Plug 2.14");

	 Show_All(Vbox);
	 case Run(Dialog) is
	    when Gtk_Response_Ok =>
	       if Work_Window.Work.Plugins (Id) /= null then
		  --Put_Line("Plug 2.15");
		  Work_Window.Work.Plugins (Id).Device_Id := Device_num(Gtk.Combo_Box_Text.Get_Active(Work_Window.Plugins_Pages(Id).Device_Id)+1);
		  --Put_Line("Plug 2.15.1");
		  Work_Window.Work.Plugins (Id).Ch_Id := Channel_Num(Gtk.Combo_Box_Text.Get_Active(Work_Window.Plugins_Pages(Id).Timbre_Channel)+1);
		  --Put_Line("Plug 2.15.2");
		  Work_Window.Work.Plugins (Id).Cat_Id := Category_Index_Type(Gtk.Combo_Box_Text.Get_Active(Work_Window.Plugins_Pages(Id).Timbre_Category)+1);
		  --Put_Line("Plug 2.15.3");
		  Work_Window.Work.Plugins (Id).Form_Id := Form_Index_Type(Gtk.Combo_Box_Text.Get_Active(Work_Window.Plugins_Pages(Id).Played_Form)+1);
		  --Put_Line("Plug 2.15.4");
	       end if;
	       Init(Value, Gtype_boolean);
	       Set_boolean(Value, false);
	       Set_Value (M, Iter, Printable_Column, Value);
	       Set_Value (M, Iter, Muttable_Column, Value);
	       Init(Value, Gtype_String);
	       Set_String(Value, Plugin_Enum'Image(Work_Window.Work.Plugins (Id).Class));
	       Set_Value (M, Iter, Type_Column, Value);
	       Destroy(Dialog);
	    when Gtk_Response_Cancel =>
	       Destroy(Dialog);
	    when others =>
	       null;
	 end case;
      else
	 Init(Value, Gtype_boolean);
	 Set_boolean(Value, false);
	 Set_Value (M, Iter, Printable_Column, Value);
	 Set_Value (M, Iter, Muttable_Column, Value);
	 Init(Value, Gtype_String);
	 Set_String(Value, Plugin_Enum'Image(Work_Window.Work.Plugins (Id).Class));
	 Set_Value (M, Iter, Type_Column, Value);
      end if;
   end Create_Plugin_Page;


   ---------------------
   -- Printed_Callback --
   ---------------------
   
   procedure Plugin_Printed_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record
     )
   is
      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);
      Path_String : constant String := Get_String (Nth (Params, 1));
      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);


      Old_Value   : Boolean;

      Id : Plugin_num := 1;

   begin
      Old_Value := Get_Boolean (M, Iter, printable_Column);

      Id := Plugin_Num'Value
	(Get_String (M, Get_Iter_From_String
		       (M, Get_String (Nth (Params, 1))), Id_Column));

      if User_Data.Work.Plugins (Id) /= null then
      	 if not Old_Value then
      	    Text_Io.Put_Line ("Printing plugin N° " & Plugin_Num'Image (Id));
      	    Set (M, Iter, printable_Column, not Old_Value);
      	    User_Data.Work.Plugins (Id).Printed := True;

      	    Text_Io.Put_Line ("Done.");
      	 else
      	    Text_Io.Put_Line ("Unprinting plugin N° " & Plugin_Num'Image (Id));
      	    Set (M, Iter, printable_Column, not Old_Value);
      	    User_Data.Work.Plugins (Id).Printed := False;
      	    Text_Io.Put_Line ("Done.");
      	 end if;
      end if;

   end Plugin_Printed_Callback;



   procedure Plugin_Mutted_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record
     )
   is
      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);
      Path_String : constant String := Get_String (Nth (Params, 1));
      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);
      Old_Value   : Boolean;

      Id : Plugin_Num := 1;

   begin
      Old_Value := Get_Boolean (M, Iter, Muttable_Column);

      Id := Plugin_Num'Value
	(Get_String (M, Get_Iter_From_String
		       (M, Get_String (Nth (Params, 1))), Id_Column));

      if User_Data.Work.Plugins (Id) /= null then
      	 if not Old_Value then
      	    Text_Io.Put_Line ("Mutting plugin N° " & Plugin_Num'Image (Id));
      	    Set (M, Iter, Muttable_Column, not Old_Value);
      	    User_Data.Work.Plugins (Id).Mutted := True;
      	    Text_Io.Put_Line ("Done.");
      	 else
      	    Text_Io.Put_Line ("Unmutting plugin N° " & Plugin_Num'Image (Id));
      	    Set (M, Iter, Muttable_Column, not Old_Value);
      	    User_Data.Work.Plugins (Id).Mutted := False;
      	    Text_Io.Put_Line ("Done.");
      	 end if;
      end if;

   end Plugin_Mutted_Callback;

   procedure Plugin_Edited_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_access
     )
   is
      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);
      Path_String : constant String := Get_String (Nth (Params, 1));
      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);
      Old_Value   : Boolean;

      Id : Plugin_Num := 1;

   begin
      Old_Value := Get_Boolean (M, Iter, Active_Column);
      Id := Plugin_Num'Value
	(Get_String (M, Get_Iter_From_String
		       (M, Get_String (Nth (Params, 1))), Id_Column));
      if not Old_Value then
	 --  if User_Data.Work.Plugins (Id) = null then
	 --     User_Data.Work.Plugins (Id) :=
	 --       Initialize(Null_Plugin, Id, 1, 1, 1, 1);
	 --  end if;

	 Text_Io.Put_Line ("Editting plugin N° " & Plugin_Num'Image (Id));

	 Create_Plugin_Page
	   (Model,
	    Params,
	    User_Data,
	    User_Data.Work.Plugins (Id), id);

	 Set (M, Iter, Active_Column, True);
      else
	 --  if User_Data.Plugins_Pages(Id).Opened then
	 --     if (User_Data.Work.Plugins (Id) /= null) then
	 --        if (Get_N_Pages (User_Data.Plugins_Notebook) >=
	 --  	     User_Data.Plugins_Pages(Id).Page_Num) then

	 --  	  Text_Io.Put_Line ("Deletting plugin N° " & Plugin_Num'Image (Id));

	 --  	  Remove_Page (User_Data.Plugins_Notebook,
	 --  		       User_Data.Plugins_Pages(Id).Page_Num-1);

	 --  	  for Page_Id in User_Data.Plugins_Pages'Range loop
	 --  	     if (User_Data.Plugins_Pages(Page_Id).Page_Num /= (-1)) and
	 --  	       User_Data.Plugins_Pages(Page_Id).Page_Num > User_Data.Plugins_Pages(Id).Page_Num then
	 --  		User_Data.Plugins_Pages(Page_Id).Page_Num := User_Data.Plugins_Pages(Page_Id).Page_Num - 1;
	 --  	     end if;
	 --  	  end loop;
	 --  	  User_Data.Plugins_Pages (Id).Page_Num := -1;
	 --  	  User_Data.Plugins_Pages (Id).Opened := False;
	 --  	  User_Data.Work.Plugins (Id).Opened := False;

	 --  	  Set (M, Iter, Active_Column, False);
	 --        end if;
	 --     end if;
	 --  end if;
	 null;

      end if;

      Set (M, Iter, Active_Column, Old_Value);
   end Plugin_Edited_Callback;



   procedure Load_Plugins (Work_Window : in Gtk_Gmface_Work_Window_Access;
			   Plugins  : in Plugin_set) is


      Scrolled   : Gtk_Scrolled_Window;
      Vbox       : Gtk_Vbox;
      
      
      -- Comon Tree
      Col      : Gtk_Tree_View_Column;
      Num      : Gint;
      Text_Render   : Gtk_Cell_Renderer_Text;
      Toggle_Render : Gtk_Cell_Renderer_Toggle;

      Parent, Iter  : Gtk_Tree_Iter;
      pragma Unreferenced (Num);
      pragma Warnings (Off, Iter);
   begin

      Gtk_New (Work_Window.Plugins_Model,
	       (Text_Column       => GType_String,
                Id_Column         => GType_String,
		Type_Column       => GType_String,
                Editable_Column   => GType_Boolean,
                Active_Column     => GType_Boolean,
                Foreground_Column => GType_String,
		Printable_Column  => GType_Boolean,
		Muttable_Column   => GType_Boolean));

      Gtk_New (Work_Window.Plugins_Tree, Work_Window.Plugins_Model);
      Set_Grid_Lines (Work_Window.Plugins_Tree, Grid_Lines_Vertical);
      Set_Enable_Tree_Lines (Work_Window.Plugins_Tree, True);
      Set_Rubber_Banding (Work_Window.Plugins_Tree, True);
      Set_Mode (Get_Selection (Work_Window.Plugins_Tree), Selection_Multiple);
      Gtk_New (Scrolled);
      Set_Policy (Scrolled, Policy_Always, Policy_Always);
      Add (Scrolled, Work_Window.Plugins_Tree);
      Gtk_New_Vbox(Vbox, Homogeneous => false);
      Pack_Start(Vbox, Scrolled, True, True);
      Add (Work_Window.Plugins_frame, vbox);




      Gtk_New (Text_Render);

      Gtk_New (Col);
      Num := Append_Column (Work_Window.Plugins_Tree, Col);
      Set_Sort_Column_Id (Col, Text_Column);
      Set_Title (Col, "Name");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Text_Column);
      Add_Attribute (Col, Text_Render, "editable", Editable_Column);
      Object_Callback.Object_Connect
	(Text_Render, "edited", Name_Edited_Callback'Access,
	 Slot_Object => Work_Window.Plugins_Model,
	 User_Data => Work_Window.all);

      Gtk_New (Text_Render);
      Gtk_New (Col);
      Num := Append_Column (Work_Window.Plugins_Tree, Col);

      Set_Title (Col, "Id");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Id_Column);

      Gtk_New (Col);
      Num := Append_Column (Work_Window.Plugins_Tree, Col);

      Gtk_New (Text_Render);
      Set_Title (Col, "Type");
      Pack_Start (Col, Text_Render, True);
      Set_Sizing (Col, Tree_View_Column_Autosize);
      Add_Attribute (Col, Text_Render, "text", Type_Column);


      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Work_Window.Plugins_Tree, Col);
      Set_Title (Col, "Edit");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Active_Column);


      Pointer_Object_Callback.Object_Connect
	(Toggle_Render, "toggled", Plugin_Edited_Callback'Access,
	 Slot_Object => Work_Window.Plugins_Model,
	 User_Data => Work_Window);

      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Work_Window.Plugins_Tree, Col);
      Set_Title (Col, "Print");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Printable_Column);

      Object_Callback.Object_Connect
	(Toggle_Render, "toggled", Plugin_Printed_Callback'Access,
	 Slot_Object => Work_Window.Plugins_Model,
	 User_Data => Work_Window.all,
	 After => False);


      Gtk_New (Toggle_Render);
      Gtk_New (Col);
      Set_Sort_Column_Id (Col, -1);  --  unsortable
      Num := Append_Column (Work_Window.Plugins_Tree, Col);
      Set_Title (Col, "Mute");
      Pack_Start (Col, Toggle_Render, False);
      Add_Attribute (Col, Toggle_Render, "active", Muttable_Column);

      Object_Callback.Object_Connect
	(Toggle_Render, "toggled", Plugin_Mutted_Callback'Access,
	 Slot_Object => Work_Window.Plugins_Model,
	 User_Data => Work_Window.all,
	 After => False);


      Set_Headers_Clickable (Work_Window.Plugins_Tree, True);
      Set_Sort_Func (+Work_Window.Plugins_Model, Text_Column, Custom_Sort'Access);


      Parent := Null_Iter;
      for Plugin_Id in Plugins'Range loop
	 if Plugins (Plugin_Id) /= null and then 
	   Plugins (Plugin_Id).Class /= Null_Plugin then

	    Plugins(Plugin_Id).Id := Plugin_Id;

	    --if Plugins (Plugin_Id).Opened then
	    Iter := Add_Line
	      (Work_Window.Plugins_Model, Plugins (Plugin_Id).Name.all, Plugin_Num'image (Plugin_Id), Plugin_Enum'Image(Plugins (Plugin_Id).Class),
	       Editable => True, Muttable => Plugins (Plugin_Id).Mutted, Active => Plugins (Plugin_Id).Printed, Parent => parent);
	 else
	    -- Add line without plugin : Null_Plugin
	    Iter := Add_Line
	   (Work_Window.Plugins_Model, "", Plugin_Num'image (Plugin_Id), Plugin_Enum'Image(Plugin_Enum'First),
	    Editable => True, Muttable => False, Active => False, Parent => parent);
	 end if;
      end loop;


   end Load_Plugins;

   --
   ---------------------------------------------------
   
   procedure Load_Window (Work_Window : Gtk_Gmface_Work_Window_Access;
			  Gtk_Int     : in Gtk_Interface_Pointer) is
                  
   begin
      null;
      
      --Put_Line("TOTO 1.10");
      Load_Master (Work_Window, Gmface_Work_Record(Work_Window.Work.all).Options.all);
      --Put_Line("TOTO 1.12");
      Load_Devices (Work_Window,
		    Gtk_Int.bandmaster);
      --Put_Line("TOTO 1.13");
      Load_Plugins (Work_Window.all'Unrestricted_access, Work_Window.Work.Plugins);
      --Put_Line("TOTO 1.14");
      Load_Flow (Work_Window);
      --Put_Line("TOTO 1.15");
      Load_State (Work_Window);
      --Put_Line("TOTO 1.17");
   end Load_Window;
   
   
   -------------------------------------------------------------------
   --                Devices callbacks                              --
   -------------------------------------------------------------------
   --------------
   -- Add_Line --
   --------------

   function Add_Line
     (Model    : access Gtk_Tree_Store_Record'Class;
      names    : String;
      Ids      : string;
      Types    : String;
      Editable : Boolean := False;
      Muttable  : Boolean := False;
      Active   : Boolean := False;
      Parent   : Gtk_Tree_Iter := Null_Iter) return Gtk_Tree_Iter
   is
      Iter : Gtk_Tree_Iter;
   begin

      Append (Model, Iter, Parent);

      Set (Model, Iter, Text_Column, Names);

      Set (Model, Iter, Id_Column, ids);
      
      Set (Model, Iter, Type_Column, Types);

      Set (Model, Iter, Active_Column, False);

      Set (Model, Iter, Editable_Column, Editable);

      Set (Model, Iter, Printable_Column, Active);

      Set (Model, Iter, Muttable_Column, Muttable);

      Set (Model, Iter, Foreground_Column, "black");

      return Iter;
   end Add_Line;
   
   
   

   procedure Text_Edited_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Gtk_Gmface_Work_Window_Record
     )

   is
      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);
      Path_String : constant String := Get_String (Nth (Params, 1));
      Text_Value  : constant GValue := Nth (Params, 2);
      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);
      pragma Unreferenced (User_Data);
   begin
      Set_Value (M, Iter, Text_Column, Text_Value);
   end Text_Edited_Callback;
   
   
   ------------------------------------------------------------------
   -- End Gmface application                                       --
   ------------------------------------------------------------------
   
   
   
   ------------------------------------------------------------------
   --                Initialize Gmidi work Window                  --
   ------------------------------------------------------------------
   
   
   
   
   function Gmidi_Initialize(Work          : in Work_Access;
			     Work_Id       : in Work_Num;
			     Process       : in Work_Processing_Access;
			     Gtk_Interface : in Gtk_Interface_Pointer) 
		      return Gtk_Work_Window_Pointer is
      
      Work_Window : constant Gtk_Work_Window_Pointer := new Gtk_Gmidi_Work_Window_Record(Work_Id);
      
      Error : aliased Gerror;
   begin                        
      
      
      Application_Window.Gtk_New(Work_Window.Window, Gtk_Interface.Application);
      Application_Window.Set_Default_Size(Work_Window.Window, 1024, 768);
      Application_Window.Set_Title(Work_Window.Window, "Gmidi [  ]");
      Application_Window.Set_Position(Work_window.Window, Win_Pos_Center_always);
      
      
      
      ---------------------------------------------------
      --             Main menu application             --
      ---------------------------------------------------
      Gtk_New (Work_Window.App_Action_Group, "Actions");
      Add_Actions (Work_Window.App_Action_Group, App_Main_Entries,
		   Gtk_Interface_Conversions.To_Address (Gtk_Interface));
      
      Gtk_New (Work_Window.App_UI);
      
      Insert_Action_Group (Work_Window.App_UI, Work_Window.App_Action_Group, 0);

      Add_Accel_Group
	(Work_Window.Window, Get_Accel_Group (Work_Window.App_UI));

      if Add_UI_From_String
      	(Work_Window.App_UI, App_Main_UI_Info, Error'Unchecked_Access) = 0 then
      	 Put_Line
      	   ("Building menus failed: " & Get_Message (Error));
      	 Error_Free (Error);
      end if;            
      Gtk_New_Hbox(Work_Window.Menus_Hbox, False, 0);
      
      Gtk.Box.Pack_Start
	(Work_Window.Menus_Hbox,
	 Get_Widget (Work_Window.App_UI, "/MenuBar"),
	 Expand => False, Padding => 0);
      
      Gtk_New_Vbox(Work_Window.Main_Vbox, False, 0);
      
      Pack_Start(Work_Window.Main_Vbox, Work_Window.Menus_Hbox, false);
      
      Add (Work_Window.Window, Work_Window.Main_Vbox);
      
      Application_Window.Show_All(Work_window.Window);
      
      return Work_Window;
   end Gmidi_Initialize;
   
   
   function Self (Main : in Gtk_Interface_Pointer) return Boolean;
   
   function Cmd_Line (App : access GtkAda_Application_Record'Class;
		      Gtk_Int : Gtk_Interface_Pointer)
		     return Boolean is
      
      Source : constant Main_Sources.G_Source_Func := Self'Access;
   begin
      Window.Gtk_New(Gtk_Int.Window);
      --Put_Line("Tata 0.0");
      Window.Set_Default_Size(Gtk_Int.Window, 250, 125);      
      Window.Set_Title(Gtk_int.Window, GApplication_Id);      
      Window.Show_All(Gtk_Int.Window);
      Hide(Gtk_Int.Window);
      -----------------------------------------------------------
      --Put_Line("Tata 0.1");
      
      for Work in Gtk_Int.Works'Range loop
	 if Gtk_Int.Works(Work) /= null then
	    case Gtk_Int.Works(Work).Class is
	       when Gmface_Work =>
		  Gtk_Int.Works_Processes(Work) := new Gmface_Work_Processing;		  
		  Gtk_Int.Works_Processes(Work).Initialize(Gtk_Int.Works(Work),
		  					   Gtk_Int.Bandmaster'access);
		  
		  Gtk_Int.Gtk_Works_Windows(Work) :=
		    Gmface_Initialize(Gtk_Int.Works(Work),
				      Work, 
				      Gtk_Int.Works_Processes(Work),
				      Gtk_Int);
		  		  
		  Add_Window(App, Gtk_Int.Gtk_Works_Windows(Work).Window);
		  
		  Gtk_Int.Work_Last := Gtk_Int.Work_Last + 1;
	       when others =>
		  null;
	    end case;
	 end if;
      end loop;
      --Put_Line("Tata 0.2");
      
      
      if Gtk_Int.Auto_Play then
	 Gtk_Int.Main_Automation := Main_Sources.Timeout_Add (Interval => 1500,
							      Data     => Gtk_Int,
							      Func     => Source);
      end if;
      -----------------------------------------------------------
      
      
      Put_Line("Gtk application created.");
      return True;
   end Cmd_Line;
   
   --  package App_User_Callback is
   --     new Handlers.User_Callback
   --    (GtkAda_Application_Record,
   --     Gtk_Interface_Pointer);
   
   
   package App_User_Return_Callback is
      new Handlers.User_Return_Callback
     (GtkAda_Application_Record, Boolean,
      Gtk_Interface_Pointer);
   
   
   ------------------------------------------------------------------
   --                     Initialize Application                   --
   ------------------------------------------------------------------
   procedure Gtk_New(Gtk_Int   : out Gtk_Interface_Pointer;
		     Works     : access Work_Array;
		     Auto_Play : in Boolean;
		     In_Loop   : in boolean) is
      
      State : Gint;
      Argc : constant Gint := 0;
      Argv : GNAT.Strings.String_List(1..0);
   begin
      --Put_Line("Tonton 0.0");
      Gtk_Int := new Gtk_Interface_Record;
      
      Gtk_Int.Auto_Play := Auto_Play;
      Gtk_Int.In_Loop := In_Loop;
      
      
      Gtk_Int.Gm_Application := new Gm_Interface_Record;
      Gtk_Int.Works := Works.all;
      --Put_Line("Tonton 0.0");
      Gtk_Int.Bandmaster.Initialize;
      --Put_Line("Tonton 0.0");
      Gtk_Int.Application := 
	Gtkada.Application.Gtk_Application_New
	(
	 Locale_To_Utf8(GApplication_Id),         
	 G_Application_Handles_Command_Line,
	 Gtkada_Application_Handles_Open
	);      
      App_User_Return_Callback.Connect
        (Gtk_Int.Application, "command-line",
	 App_User_Return_Callback.To_Marshaller(Cmd_line'Access),
	 Gtk_Int);
      State := Run(Gtk_Int.Application, Argc, Argv);      
   end Gtk_New;
   
   
   Initialized : Boolean := False;

   function Self (Main : in Gtk_Interface_Pointer) return Boolean is
      Running : Boolean := False;
      Focus : Boolean := False;
   begin            
      
      for I in Main.Gtk_Works_Windows'range loop
	 if not (Main.Gtk_Works_Windows(I) /= null) and then
	   Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(I).all).Work.Started then
	    Running := True;
	 end if;
      end loop;
      if Main.Auto_Play then

	 if not running then
	    Running := True;
	    if not initialized then
	       Put_Line("auto stop last");
	       stop(null, Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Work_Last).all)'access);
	       Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Work_Last).all).Work.Started := False;
	       Put_Line("auto start");
	       Play(null, Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Cur_Win).all)'access);
	       Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Cur_Win).all).Work.Started := True;
	       Put_Line("auto start done.");
	       present(Main.Gtk_Works_Windows(Main.Cur_Win).Window);
	       Initialized := True;

	    else


	       Put_Line("auto stop cur");
	       stop(null, Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Cur_Win).all)'access);
	       Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Cur_Win).all).Work.Started := False;
	       Main.Cur_Win := Main.Cur_Win + 1;
	       if Natural(Main.Cur_Win) > Main.Work_Last then
		  Main.Cur_Win := 1;
		  Running := Main.In_Loop;
		  Initialized := False;
	       end if;
	       Put_Line("Last : " & Work_Num'Image(Main.Work_Last));
	       Put_Line("Cur  : " & Work_Num'Image(Main.Cur_Win));

	       Put_Line("auto start");
	       Play(null, Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Cur_Win).all)'access);
	       Gtk_Gmface_Work_Window_Record(Main.Gtk_Works_Windows(Main.Cur_Win).all).Work.Started := True;
	       present(Main.Gtk_Works_Windows(Main.Cur_Win).Window);
	       Put_Line("auto start done.");
	    end if;

	 end if;
      end if;

      return running;
   end Self;
         
   procedure ReLoad_Window (Work_Window : in Gtk_Gmface_Work_Window_Access) is

   begin
      
      
      Load_Master (Work_Window, Gmface_Work_Record(Work_Window.Work.all).Options.all);
      --Put_Line("TOTO 1.12");
      --Put_Line("TOTO 1.13");
      Load_Plugins (Work_Window.all'Unrestricted_access, Work_Window.Work.Plugins);
      --Put_Line("TOTO 1.14");
      Load_Flow (Work_Window);
      --Put_Line("TOTO 1.15");
      Load_State (Work_Window);
      --Put_Line("TOTO 1.17");            
   end ReLoad_Window;
   
   procedure Open_Action (Action, Main_Window : in System.Address) is
      
      pragma Unreferenced(Action);
      
      
      App : constant Gtk_Interface_Pointer :=
	Gtk_Interface_Conversions.To_Pointer(Main_Window);
      
      
      Name : String_access;

      Widget : Gtk_Widget;
   begin
      null;
      	 
      Name := new string ' (GtkAda.File_Selection.File_Selection_dialog
			      ("Open file",
			       "",
			       Dir_Only => False,
			       Must_Exist => True));

      if Name'Length /= 0 then
	 
   	 Destroy(Get_Child(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Master_Frame));
   	 Destroy(Get_Child(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Flow_Frame));
	 
   	 Destroy(Get_Child(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Plugins_Frame));
   	 Destroy(Get_Child(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).State_Frame));
	 
	 
	 
	 --
	 Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.Filename := new String ' (Name.all);
	 Gmface_Work_Record(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.all).Initialize
	   (Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.Id,
	    Name.all);

	 App.Works(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.id) := Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work;
	 
	 App.Works_Processes(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.id).Initialize(App.Works(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.id), App.bandmaster'access);  
	 Put_Line("Open Action :: copy process...");
	 App.Gtk_Works_Windows(App.Cur_Win).Process := App.Works_Processes(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Work.id);
	 Put_Line("Open Action :: initialize process...");
	 Gmface_Work_Processing(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Process.all).Process.Initialize;
	 --
	 
	 ReLoad_Window(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all)'access);
	 Show_All(Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Window);

	 
	 
	 Set_Title (Gtk_Gmface_Work_Window_Record(App.Gtk_Works_Windows(App.Cur_Win).all).Window,
		    "Ultrason [" & Name.all & ']');
	 
	 Free(name);
	 
      end if;
   end Open_Action;
      
   
   procedure Close_Action (Action, Application : in System.Address) is
      pragma Unreferenced(Action);
      App : constant Gtk_Interface_Pointer :=
	Gtk_Interface_Conversions.To_Pointer(Application);
      
      Main_Window : Gtk_Work_Window_Pointer :=
	App.Gtk_Works_Windows(App.Cur_Window);
      
      
      Status : Boolean;
      
   begin
      Status := Close_Window(Main_Window.Window, App);      
   end Close_Action;
   
   procedure New_Action (Action, Application : in System.Address) is
      pragma Unreferenced(Action);
      App : constant Gtk_Interface_Pointer :=
	Gtk_Interface_Conversions.To_Pointer(Application);
      
      Name : constant String_Access := new String ' ("");
      
   begin

      for Id in App.Gtk_Works_Windows'Range loop
	 if App.Works(Id) = null and then
	   App.Gtk_Works_Windows(Id) = null then
	    --Put_Line("new 0.0.0");
	    App.Works(Id) := new Gmface_Work_Record;
	    --Put_Line("new 0.0.1");
	    Gmface_Work_Record(App.Works(Id).all).Initialize(Id, Name.all);
	    --Put_Line("new 0.0.2");
	    App.Works_Processes(Id) := new Gmface_Work_Processing;
	    --Put_Line("new 0.0.3");
	    
	    App.Works_Processes(Id).Initialize(App.Works(Id),
					       App.Bandmaster'access);
	    App.Gtk_Works_Windows(Id) := Gmface_Initialize(App.Works(Id), Id, App.Works_Processes(Id), App);
	    	    
	    Add_Window(App.Application, App.Gtk_Works_Windows(Id).Window);
	    --Put_Line("new 0.0.4");
	    App.Work_Last := App.Work_Last + 1;	    
	   exit;
      
	 end if;
      end loop;
   end New_Action;
   
   procedure Save_Action (Action, Main_Window : in System.Address) is
      
      pragma Unreferenced(Action);
      
      
      Dialog : Gtk_File_Chooser_Dialog;
      
      Name : String_access;
      
      Widget : Gtk_Widget;
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
      
   begin
      
      Gtk.File_Chooser_Dialog.Gtk_New(Dialog => Dialog, Title => "Save file to",
				      Parent => Gmface_Window.Window,
				      Action => Action_Save
				      );
      
      Gtk.File_Chooser_Dialog.Set_Current_Name(Dialog, Gmface_Window.Work.Filename.all);
      
      widget := Gtk.Dialog.Add_button(Gtk_Dialog(Dialog), "Ok", Gtk.Dialog.Gtk_Response_Ok);
      widget := Gtk.Dialog.Add_button(Gtk_Dialog(Dialog), "Cancel", Gtk.Dialog.Gtk_Response_Cancel);
      
      case Run(Dialog) is
	 when Gtk_Response_Ok =>
	    
	    Name := new String ' (Gtk.File_Chooser_Dialog.Get_Filename(Dialog));
	    
	    if Name'Length > 0 then
	       Gmface_Window.Work.Filename := new String ' (Name.all);
	       
	       Save(Gmface_Work_Record(Gmface_Window.Work.all), Name.all);
	       
	       Set_Title (Gmface_Window.Window,
			  "Ultrason [" & Gmface_Window.Work.Filename.all & ']');
	       
	    end if;
	    
	    Destroy(Dialog);
	 when others =>
	    Destroy(Dialog);
      end case;
	    
	    

   end Save_Action;

   procedure Play_On_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
      
   begin

      Play_On(null, Gmface_Window);
   end Play_On_Action;

   procedure Rec_On_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
   begin

      Rec_on(null, Gmface_Window);
   end Rec_On_Action;

   procedure Play_off_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
   begin

      Play_off(null, Gmface_Window);
   end Play_off_Action;

   procedure Rec_off_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
   begin

      Rec_off(null, Gmface_Window);
   end Rec_off_Action;


   procedure Start_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
   begin

      Play(null, Gmface_Window);
   end Start_Action;
   procedure Stop_Action (Action, Main_Window : System.Address) is

      pragma Unreferenced (Action);
      
      Gmface_Window : constant Gtk_Gmface_Work_Window_access := 
	Gmface_Work_Window_Conversions.To_Pointer(Main_Window).all'access;
   begin

      Stop(null, Gmface_Window);
   end Stop_Action;
   
end Gmface.Gm_Application.Gtk_Interface;