with Gtk.Widget;                        use Gtk.Widget;
with Gtk.Dialog;                        use Gtk.Dialog;
with Gtk.Handlers;                      use Gtk.Handlers;

pragma Elaborate_All (Gtk.Handlers);

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


with Gtk.Enums;                         use Gtk.Enums;
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.About_Dialog;                  use Gtk.About_Dialog;
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 Gtk.Stock;                         use Gtk.Stock;
with Gtk.Adjustment;                    use Gtk.Adjustment;
with Gtk.Scrolled_Window;               use Gtk.Scrolled_Window;


with Glib.Application;                  use Glib.Application;
with Gtk.Application;                   use Gtk.Application;
with Glib.Option;                       use Glib.Option;

with Gtk.Main;                          use Gtk.Main;


with Gnat.Strings;

with Libsens.Common;                    use Libsens.Common;

with Libsens.MIDI.Drivers;              use Libsens.MIDI.Drivers;
with Libsens.MIDI.Messages;              use Libsens.MIDI.Messages;
with Libsens.MIDI.Instruments;          use Libsens.MIDI.Instruments;

with Libsens.Virtual.Aux;               use Libsens.Virtual.Aux;

with Libsens.Processing.Common;         use Libsens.Processing.Common;
with Libsens.Processing.Work_Processing;use Libsens.Processing.Work_Processing;
with Libsens.Arch;                      use Libsens.Arch;
with Libsens.Gtk_Plugins_Initialization;use Libsens.Gtk_Plugins_Initialization;

with Libsens.Util;                      use Libsens.Util;


with Ada.Calendar.Formatting;           use Ada.Calendar;
with Ada.Strings.Fixed;                 use Ada.Strings;



with Interfaces.C.Strings;              use Interfaces.C.Strings;

with Text_Io;                           use Text_Io;

package body Libsens.Applications.Gm_Interface is
   
   
   procedure Inputs_Finalization(Int : in Gm_Interface_Pointer);
   
   function Self (Main : in Gm_Interface_Pointer) return Boolean;
   
   use Gtk;      
   
   use Glib;
   
   function Initialize(Work : in Work_Access;
		       Work_Id : in Work_Num;		       
		       Process : in Work_Processing_Access;
		       Gm_Interface : in Gm_Interface_Pointer) return Work_Window_Pointer;
   
   use Work_Window_Conversions;
   
   function Cmd_Line (App : access Gtk_Application_Record'Class;
		      Gm_Interface : Gm_Interface_Pointer) return Boolean is
      Source : constant Main_Sources.G_Source_Func := Self'Access;
   begin
      Gm_Interface.Win := Application_Window.Gtk_Application_Window_New(App);      
      Put_Line("Gm interface Window created.");                  
      Application_Window.Set_Default_Size(Gm_Interface.Win, 250, 125);      
      Application_Window.Set_Title(Gm_Interface.Win, GApplication_Id);      
      Application_Window.Show_All(Gm_Interface.Win);
      Hide(Gm_Interface.Win);
      
      
      for Work in Gm_Interface.Works'Range loop
	 if Gm_Interface.Works(Work) /= null then
	    
	    Gm_Interface.Works_Processes(Work) := new Work_Processing_Record;
	    Gm_Interface.Works_Processes(Work).Initialize(Gm_interface.Works(Work), Gm_Interface.Instruments'access);
	    
	    Gm_Interface.Works_Win(Work) :=
	      Initialize(Gm_Interface.Works(Work),
			 Work_Num(Work),
			 Gm_Interface.Works_Processes(Work),
			 Gm_Interface => Gm_Interface
			);
		  	    	       
	    Gtk.Application.Add_Window(App, Gm_Interface.Works_Win(Work).Win);	       
	    Gm_Interface.Work_Last := Gm_Interface.Work_Last + 1;	    
	    
	 end if;
      end loop;
      
      if Gm_Interface.Auto_Play then
	 Gm_Interface.Main_Automation := Main_Sources.Timeout_Add (Interval => 1500,
								   Data     => Gm_Interface,
								   Func     => Source);
      end if;
      
      return True;      
   end Cmd_line;
   
   procedure Not_Activate (App : access Gtk_Application_Record'Class;
		       Gm_Interface : Gm_Interface_Pointer) is
   begin
      null;
   end Not_Activate;
   

   
   package App_User_Callback is new Handlers.User_Callback (Gtk_Application_Record, Gm_Interface_Pointer);
   package App_User_Return_Callback is new Handlers.User_Return_Callback (Gtk_Application_Record, Boolean, Gm_Interface_Pointer);
   
   
   procedure Not_Open(App : access Gtk_Application_Record'Class;
		      Gm_Interface : in Gm_Interface_Pointer) is
   begin
      null;
   end Not_Open;      
   
   procedure Initialize(Gm_Interface : in out Gm_Interface_Pointer;
			State : out Glib.Gint;
			Works : access Work_Array;
			Verbose, Auto_Play, In_Loop, Help, Ignore : in Boolean) is
            
      Argc : constant Gint := 0;
      Argv : GNAT.Strings.String_List(1..0);-- := (others => new String ' (""));
   begin      
      
      Put("Freeing Gm_Interface...");
      Free(Gm_Interface);      
      Put_Line(" Done.");            
      Gm_Interface := new Gm_Interface_Record;      
      
      Gm_Interface.Auto_Play := Auto_Play;
      Gm_Interface.In_Loop := In_Loop;
      Gm_Interface.Verbose := Verbose;
      Gm_Interface.Help := Help;
      Gm_Interface.Ignore := Ignore;
      Gm_Interface.Instruments.Initialize(Ignore);      
      
      
      
      Gm_Interface.Works := Works.all;--'Unrestricted_Access;      
      Put_Line("Gm_Interface created.");            
      Gm_Interface.App := 
	Gtkada.Application.Gtk_Application_New
	(
	 Locale_To_Utf8(GApplication_Id),         
	 G_Application_Handles_Command_Line,
	 Gtkada_Application_Handles_Open
	);      
      --  App_User_Callback.Connect
      --    (Gm_Interface.App, "activate",
      --  	 App_User_Callback.To_Marshaller(Not_Activate'Access),
      --  	 Gm_Interface);      
      --  App_User_Callback.Connect
      --    (Gm_Interface.App, "open",
      --  	 App_User_Callback.To_Marshaller(not_open'Access),
      --  	 Gm_Interface);      
      App_User_Return_Callback.Connect
        (Gm_Interface.App, "command-line",
	 App_User_Return_Callback.To_Marshaller(Cmd_line'Access),
	 Gm_Interface);                
      State := 0;
      State := Run(Gm_Interface.App, Argc, Argv);   
   exception
      when others =>
         State := 1;
         raise;
   end Initialize;
   
   ---------------------------------------------------------------
   --                Application menu Action(s)                 --
   ---------------------------------------------------------------
   procedure New_Action (Action, Application : in System.Address);
   pragma Convention (C, New_Action);
   --  Called when new actions has been selected
   
   procedure Quit_Action (Action, Application : in System.Address);
   pragma Convention (C, Quit_Action);
   --  Called when Quit actions has been selected
   
   
   function Close_Window(Window : access Gtk_Window_Record'Class;
		  App    : Gm_Interface_Pointer) return Boolean;
   --  Called when delete-event signal is sended
   
   function Close_window(Window : access Gtk_Window_Record'Class;
		  App    : Gm_Interface_Pointer) return Boolean is
      
      Only_One : Natural := 0;
      
   begin
      for Id in 1..Work_Num(App.Work_Last) loop
	 if App.Works_Win(Id) /= null and then 
	   App.Works_Win(Id).Win /= null then	    	    
	    if App.Works_Win(Id).Win = Window then
	       
	       
	       
	       App.Works_Win(Id).Process.Process.Stop;
	       Put_Line("Processes stopped");	       
	       App.Works_Win(Id).Process.Process.Halt;
	       App.Works_Win(Id).Process.Box.Halt;
	       Put_Line("Processes halted");	  
	       
	       if App.Works_Win(Id).Flow_Control /= Glib.Main.No_Source_Id then

	       	  Glib.Main.Remove(App.Works_Win(Id).Flow_Control);
	       	  App.Works_Win(Id).Flow_Control := Glib.Main.No_Source_Id;
	       end if;
	       if App.Works_Win(Id).State_Control /= Glib.Main.No_Source_Id then

	       	  Glib.Main.Remove(App.Works_Win(Id).State_Control);
	       	  App.Works_Win(Id).State_Control := Glib.Main.No_Source_Id;
	       end if;
	       Free(App.Works_Win(Id));
	       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.Works_win(Work) := App.Works_win(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;
	 
	 Libsens.Arch.Finalize;
	 Inputs_Finalization(App.all'access);
      
	 Destroy(App.Win);

	 
	 return True;	 
      end if;      
      return False;      
   end Close_Window;
   
   
   
   procedure New_Action (Action, Application : in System.Address) is
      pragma Unreferenced(Action);
      App : constant Gm_Interface_Pointer :=
	Gm_Interface_Conversions.To_Pointer(Application);
      
      Name : constant String_Access := new String ' ("");
      
   begin
      for Id in App.Works'Range loop
	 if App.Works(Id) = null and
	   App.Works_Win(Id) = null then
	    App.Works(Id) := new Work_Record;
	    App.Works(Id).Initialize(Id, Name.all);
	    App.Works_Processes(Id) := new Work_Processing_Record;
	    App.Works_Processes(Id).Initialize(App.Works(Id), App.Instruments'access);
	    
	    App.Works_Win(Id) := Initialize(App.Works(Id), Id, App.Works_Processes(Id), App);
	    App.Work_Last := App.Work_Last + 1;
	    exit;
	    
	 end if;
      end loop;
   end New_Action;
   
   
   
   procedure Quit_Action (Action, Application : in System.Address) is
      
      pragma Unreferenced(Action);
      
      Only_One : Natural := 0;
      
      App : constant Gm_Interface_Pointer :=
	Gm_Interface_Conversions.To_Pointer(Application);
      
      
      End_Of_Application : Boolean := False;
      
   begin
      
      if App.Work_Last > 0 then	 	 	 
	 --  -- Halting all process
	 Put_Line("Halting all process...");
	 	 
	 for Work in 1..Work_Num(App.Work_Last) loop	    
	    End_Of_Application := Close_Window(App.Works_Win(Work).win, App);
	 end loop;
	 
      end if;
      
      if End_Of_Application then	 	       
	 
	 Put_Line("End of Program.");	       	       
	 Glib.Application.Quit(Gapplication(App.App));
      end if;
	       
      
      
   end Quit_Action;         
   
   
   procedure Inputs_Finalization(Int : in Gm_Interface_Pointer) is

   begin
      --Put_Line("CUCU 0.0.0");
      for Device_Id in Int.Instruments.Orchester'Range loop
      	 if Int.Instruments.Orchester(Device_Id) /= null then
	    --Put_Line("CUCU 0.1.0");
	    if Int.Instruments.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...", Gtk_Window(Int.Win), 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.Instruments.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.Instruments.Orchester(Device_Id).Input_Device_Driver.Device_Info.Id /= -1 then
			   if Int.Instruments.Orchester(Device_Id).Input_Device_Driver /= null then
			      --Put_Line("CUCU 0.1.2.1");
			      Put_Line("Stopping input driver...");
			      Int.Instruments.Orchester(Device_Id).Input_Device_Driver.Input_Driver.Halt;
			      --Put_Line("CUCU 0.1.2.2");
			      Put_Line("Stopping tempo sync...");
			      int.Instruments.Orchester(Device_Id).Tempo_Sync.Halt;
			      --Put_Line("CUCU 0.1.2.3");
			      Put_Line("Stopping mod sequencer...");
			      Int.Instruments.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;





   package Window_User_Return_Callback is 
      new Handlers.User_Return_Callback
     (Gtk_Window_Record, Boolean, Gm_Interface_Pointer);
   
   package Window_User_Callback is 
      new Handlers.User_Callback
     (Gtk_Window_Record, Gm_Interface_Pointer);
   
   
   ---------------------------------------------------
   --             Main menu aplication              --
   ---------------------------------------------------
   App_Main_Entries : constant Action_Entry_Array :=
     (1 => Create (Name => "MainMenu",        Label => "_Main"),            
      2 => Create (Name => "New",
      		   Stock_Id    => Stock_New,
      		   Label       => "_New",
      		   Accelerator => "<control>N",
      		   Tooltip     => "New",
      		   Callback    => New_action'Access),
      3 => Create (Name => "Quit",
      		   Stock_Id    => Stock_Quit,
      		   Label       => "_Quit",
      		   Accelerator => "<control>Q",
      		   Tooltip     => "Quit",
      		   Callback    => Quit_Action'Access)
     );
   
   
   App_Main_UI_Info : constant String :=
     "<ui>"
     & "  <menubar name='MenuBar'>"
     & "    <menu action='MainMenu'>"     
     & "      <menuitem action='New'/>"
     & "      <menuitem action='Quit'/>"
     & "    </menu>"
     & "  </menubar>"
     & "</ui>";
   --                                                  --
   ------------------------------------------------------         
   
   
   --  ------------------------------------------------------
   --  --            Window menu actions                   --
   --  ------------------------------------------------------
   procedure Open_Action (Action, Main_Window : in System.Address);
   pragma Convention (C, Open_Action);
   --  Called when Open actions has been selected   
   
   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


   procedure About_Action (Action, Main_Window : System.Address);
   pragma Convention (C, About_Action);

   procedure Options_Action (Action, Main_Window : System.Address);
   pragma Convention (C, Options_Action);

     
   
   --  ---------------------------------------------------
   --  --               Window(s) menu                  --
   --  ---------------------------------------------------
   Win_Main_Entries : constant Action_Entry_Array :=
     (1 => Create (Name => "FileMenu",        Label => "_File"),
      2 => Create (Name => "Open",
      		   Stock_Id    => Stock_Open,
      		   Label       => "_Open",
      		   Accelerator => "<control>O",
      		   Tooltip     => "Open",
      		   Callback    => Open_Action'Access),
      3 => Create (Name => "Save",
      		   Stock_Id    => Stock_Save,
      		   Label       => "_Save",
      		   Accelerator => "<control>S",
      		   Tooltip     => "Save",
      		   Callback    => Save_Action'Access),      
      
      4 => Create (Name => "TransportMenu",        Label => "_Transport"),
      5 => Create (Name => "Start",
   		    Stock_Id    => Stock_Media_Play,
      		    Label       => "Start",
      		    Accelerator => "<alt>P",
      		    Tooltip     => "Start",
      		    Callback    => Start_Action'Access),
      6 => Create (Name => "Stop",
      		    Stock_Id    => Stock_media_Stop,
      		    Label       => "Stop",
      		    Accelerator => "<Control>P",
      		    Tooltip     => "Stop",
      		    Callback    => Stop_Action'Access),
      7 => Create (Name => "Rec_on",
      		    Stock_Id    => Stock_Media_Record,
      		    Label       => "Rec on",
      		    Accelerator => "<alt>C",
      		    Tooltip     => "Rec_on",
      		    Callback    => Rec_On_Action'Access),
      8 => Create (Name => "Play_on",
      		    Stock_Id    => Stock_Media_Play,
      		    Label       => "Play on",
      		    Accelerator => "<alt>P",
      		    Tooltip     => "Play_on",
      		    Callback    => Play_On_Action'Access),
      9 => Create (Name => "Rec_off",
      		    Stock_Id    => Stock_Media_stop,
      		    Label       => "Rec off",
      		    Tooltip     => "Rec_off",
		   Callback    => Rec_Off_Action'Access),
      10 => Create (Name => "Play_off",
      		    Stock_Id    => Stock_Media_Play,
      		    Label       => "Play off",
      		    Tooltip     => "Play_off",
      		    Callback    => Play_Off_Action'Access),
      11 => Create (Name => "OptionsMenu",        Label => "_Options"),
      12 => Create (Name => "Preferences",
   		    Stock_Id    => Stock_Preferences,
      		    Label       => "Preferences",
      		    Tooltip     => "Preferences",
      		    Callback    => Options_Action'Access),

      13 => Create (Name => "HelpMenu",        Label => "_Help"),
      14 => Create (Name => "About",
   		    Stock_Id    => Stock_about,
      		    Label       => "About",
      		    Tooltip     => "About",
      		    Callback    => About_action'Access));
   

   Win_Main_UI_Info : constant String :=
     "<ui>"
     & "  <menubar name='MenuBar'>"
     & "    <menu action='FileMenu'>"
     & "      <menuitem action='Open'/>"
     & "      <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>"
     & "    <menu action='OptionsMenu'>"
     & "      <menuitem action='Preferences'/>"
     & "    </menu>"
     & "    <menu action='HelpMenu'>"
     & "      <menuitem action='About'/>"
     & "    </menu>"
     & "  </menubar>"
     & "</ui>";

   
   
   procedure Load_Window (Work_Window : in Work_Window_Pointer);
   
   function Initialize(Work : in Work_Access;
		       Work_Id : in Work_Num;		       		       
		       Process : in Work_Processing_Access;
		       Gm_Interface : in Gm_Interface_Pointer) return Work_Window_Pointer is
      
      Work_Window : constant Work_Window_Pointer := new Work_Window_Record(Work,
									   Work_id,
									   Gm_Interface.all'Unrestricted_access);
      
      Error : aliased Gerror;
   begin
      
      Work_Window.Process := Process;
      Work_Window.Process.Process.Initialize;      
		
      
		
      Work_Window.Title := new String ' ("Ultrason [ " & Work_Window.Work.Filename.all & " ]");      
      Window.Gtk_New(Work_Window.Win);
      Window.Set_Default_Size(Work_Window.Win, 1024, 768);      
      Window.Set_Title(Work_Window.Win, Work_Window.Title.all);
      Window.Set_Position(Work_window.Win, Win_Pos_Center_always);
      
      --Put_Line("TITI 0.1");
      Gtk_New (Work_Window.Master_Frame, "Band Master");
      --Put_Line("TITI 0.2");
      Gtk_New_hbox(Work_Window.Main_Hbox);

      Gtk_New(Work_Window.Plugins_Frame, "Plugins");



      --Put_Line("TITI 0.4");
      Gtk_New (Work_Window.Flow_Frame, "Flow");
      Gtk_New (Work_Window.Devices_Frame, "Devices");
      --Put_Line("TITI 0.5");
      Gtk_New_Vpaned (Work_Window.Main_paned);
      Gtk_New_Hpaned (Work_Window.Flow_Paned);
      Pack1 (Work_Window.Flow_Paned, Work_Window.Flow_Frame);
      Add2 (Work_Window.flow_Paned, Work_Window.Devices_Frame);
      Set_Position (Work_Window.Flow_Paned, 600);
      --Put_Line("TITI 0.6");
      Gtk_New (Work_Window.State_Frame, "State");
      --Put_Line("TITI 0.7");
      Gtk_New_Vpaned (Work_Window.Main_Paned);
      Pack1 (Work_Window.Main_Paned, Work_Window.Plugins_Frame);
      Add2 (Work_Window.Main_Paned, Work_Window.Flow_Paned);
      Set_Position (Work_Window.Main_Paned, 350);
      
      ---------------------------------------------------
      --             Main menu application             --
      ---------------------------------------------------
      Gtk_New (Work_Window.App_Action_Group, "Actions");
      Add_Actions (Work_Window.App_Action_Group, App_Main_Entries, Gm_Interface_Conversions.To_Address (Gm_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.Win, 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);
      
      --  --------------------------------------------------
      --  --             Window(s) menu                   --
      --  --------------------------------------------------
      
      Gtk_New (Work_Window.Win_Action_Group, "Actions");
      Add_Actions (Work_Window.Win_Action_Group, Win_Main_Entries, 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.Win, 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.                     --
      -------------------------------------------------------
      
      
      
                  
      Gtk_New_Vbox(Work_Window.Main_Vbox, False, 0);
      
      Pack_Start(Work_Window.Main_Vbox, Work_Window.Menus_Hbox, false);
      
            
      Pack_Start (Work_Window.Main_Hbox, Work_Window.Master_Frame, False, False, 0);
      Pack_Start (Work_Window.Main_Vbox, Work_Window.Main_Hbox, False, False, 0);
      Pack_Start (Work_Window.Main_Vbox, Work_Window.Main_Paned, True, True, 0);
      Pack_Start (Work_Window.Main_Vbox, Work_Window.State_Frame, False, False, 0);

      --Put_Line("TITI 1.0");
      Add (Work_Window.Win, Work_Window.Main_Vbox);
      --Put_Line("TITI 0.0");


      --Put_Line("TITI 2.0");
      True_Table_Initialize(Work_Window.Work.Options.True_Table);
      --Put_Line("TYTY 3.0");
      Load_Window (Work_Window);
      

      
      Window.Show_All(Work_Window.Win);
      
      Window_User_Return_Callback.Connect
	(Work_Window.Win, "delete-event",
	 Window_User_Return_Callback.To_Marshaller(Close_Window'Access),
	 Gm_Interface);
      
      
      
      return Work_Window;
   end Initialize;         
   
   procedure Save_Action (Action, Main_Window : in System.Address) is
      
      Dialog : Gtk_File_Chooser_Dialog;
      
      Name : String_access;
      
      Widget : Gtk_Widget;
   begin
      
      Gtk.File_Chooser_Dialog.Gtk_New(Dialog => Dialog, Title => "Save file to",
				      Parent => Work_Window_Conversions.To_Pointer(Main_Window).Win,
				      Action => Action_Save
				      );
      
      Gtk.File_Chooser_Dialog.Set_Current_Name(Dialog, Work_Window_Conversions.To_Pointer(Main_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
	       Work_Window_Conversions.To_Pointer(Main_Window).Work.Filename := new String ' (Name.all);
	       
	       Save(Work_Window_Conversions.To_Pointer(Main_Window).Work.all, Name.all);
	       
	       Set_Title (Work_Window_Conversions.To_Pointer(Main_Window).Win,
			  "Ultrason [" & Work_Window_Conversions.To_Pointer(Main_Window).Work.Filename.all & ']');
	       
	    end if;
	    
	    Destroy(Dialog);
	 when others =>
	    Destroy(Dialog);
      end case;
	    
	    

   end Save_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, Work_window_Conversions.To_Pointer(Main_Window).Win);
      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("Virtual MIDI Composer"));
      Set_Copyright(About_Help, Glib.Convert.Locale_To_UTF8("Copyleft (L) 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("Ultrason"));
      --Set_translator_credits(About_Help,
      Set_Version(About_Help, Glib.Convert.Locale_To_UTF8(Libsens.Version));

      if Run (About_Help) /= Gtk_Response_Close then
         null;
      end if;
      Destroy (About_Help);
   end About_Action;
   
   
   ----------
   -- Play --
   ----------
   procedure Play (Widget : access Gtk_Widget_Record'class;
                   Main_Window : in Work_Window_Pointer);

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

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

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

   
   procedure Options_Action (Action, Main_Window : System.Address) is
      pragma Unreferenced (Action);
   begin
      Reshow_With_Initial_Size(Gm_Interface_Conversions.To_Pointer(Main_Window).win);
   end Options_Action;

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

      pragma Unreferenced (Action);
   begin

      Play_On(null, Work_Window_Conversions.To_Pointer(Main_Window));
   end Play_On_Action;

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

      pragma Unreferenced (Action);
   begin

      Rec_on(null, Work_Window_Conversions.To_Pointer(Main_Window));
   end Rec_On_Action;

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

      pragma Unreferenced (Action);
   begin

      Play_off(null, Work_Window_Conversions.To_Pointer(Main_Window));
   end Play_off_Action;

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

      pragma Unreferenced (Action);
   begin

      Rec_off(null, Work_Window_Conversions.To_Pointer(Main_Window));
   end Rec_off_Action;


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

      pragma Unreferenced (Action);
   begin

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

      pragma Unreferenced (Action);
   begin

      Stop(null, Work_Window_Conversions.To_Pointer(Main_Window));
   end Stop_Action;
   
   
   
   package Return_Window_Cb is new Gtk.Handlers.User_Return_Callback
     (Gtk.Widget.Gtk_Widget_Record,
      Boolean,
      Work_Window_Pointer);

   package Window_Cb is new Gtk.Handlers.User_Callback
     (Gtk.Widget.Gtk_Widget_Record,
      Work_Window_Pointer);

   
   -- For master...

   procedure Set_Tempo_Callback
     (Model  : access Gtk_Widget_Record'Class;
      User_Data : Work_Window_Pointer);

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

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


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



   procedure Load_Master (Work_Window : in Work_Window_Pointer;
			  Options  : in Work_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(Work_Window.work.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 (Work_Window.work.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.5");
      --Pack_Start (Work_Window.State_Box, Work_Window.Tools_Box, Expand => False);
      --Put_Line("TOTO 1.10.6");
      --Gtk_New_Hbox (Work_Window.Tools_Box);
      --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(Work_Window.work.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 .. Work_Window.work.Options.Forms_Names'Length-1 loop
      	 Gtk.Combo_Box_text.Insert_Text
	   (Work_Window.Played_Form, Glib.Gint(I),
	    Glib.Convert.Locale_To_UTF8(Work_Window.work.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(Work_Window.Work.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 Device_Properties
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
     User_Data : Work_Window_Pointer);

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

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

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


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

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




   -----------------
   -- 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;


   package Object_Callback is new Gtk.Handlers.User_Callback (GObject_Record, Work_Window_Pointer);
           
   
   procedure Load_Devices (Work_Window : in Work_Window_Pointer;
   			   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);


      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 (Edit_Toggle_Render);
      --  Gtk_New (Col);
      --  Set_Sort_Column_Id (Col, -1);  --  unsortable
      --  Num := Append_Column (Work_Window.Devices_Tree, Col);
      --  Set_Title (Col, "Edit");
      --  Pack_Start (Col, Edit_Toggle_Render, False);
      --  Add_Attribute (Col, Edit_Toggle_Render, "active", Active_Column);


      --  Object_Callback.Object_Connect
      --    (Edit_Toggle_Render, "toggled", Device_Edited_Callback'Access,
      --     Slot_Object => Work_Window.Devices_Model,
      --  	 User_Data => Work_Window);

      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);

      Object_Callback.Object_Connect
        (Toggle_Render, "toggled", Device_Printed_Callback'Access,
         Slot_Object => Work_Window.Devices_Model,
   	 User_Data => Work_Window);



      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);

      Object_Callback.Object_Connect
        (Toggle_Render, "toggled", Device_Mutted_Callback'Access,
         Slot_Object => Work_Window.Devices_Model,
   	 User_Data => Work_Window);


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


      Parent := Null_Iter;
      for Count in Work_Window.Int.Instruments.Orchester'Range loop
         Iter := Add_Line
           (Work_Window.Devices_Model, "", Positive'image (Positive(Count)), "Unused",
            Editable => True, Muttable => False, Active => False, Parent => parent);
      end loop;
      --Put_Line("TETE : inst_last ::= "& Integer'Image(Work_Window.Int.instruments.Inst_Last));
      for Id in 1..Work_Window.Int.instruments.Inst_Last loop
	 
	 declare
	    Values          : Gvalues;
	    Id_Value        : Gvalue;
	    Pos_Value       : Gvalue;
	    Values_Tab      : aliased Gvalue_Array(0..1);
	    
	    C_Values_Tab     : C_Gvalues;
	 begin
	    
	    Init(Id_Value, Gtype_String);
	    Init(Pos_Value, Gtype_String);
      
	    
	    Set_String(Id_Value, Integer'Image(Integer(Id)));
	    Set_String(Pos_Value, Integer'Image(Integer(Id-1)));
	    
	    Values_tab(0) := Pos_Value;
	    Values_tab(1) := Id_Value;
	    	    
	 
	    C_Values_tab := C_GValues(values_tab'Address);
	    Values := Make_Values(2, C_Values_Tab);
	    
	    
	    Device_Edited_callback (Work_Window.Devices_Model, Values, Work_Window);
	    
	 end;
      end loop;


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

   end Load_Devices;



   procedure Load_Flow (Work_Window : in Work_Window_Pointer) 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;

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

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

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

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


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

   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;




   procedure Load_Plugins (Work_Window : in Work_Window_Pointer;
			   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);

      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);


      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,
	 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,
	 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
	    --    Create_Plugin_Page (Work_Window, Plugins (Plugin_Id), Plugin_id);

	    --elsif Plugins (Plugin_Id) /= null and then
	    -- not Plugins (Plugin_Id).Opened then
	    --  Iter := Add_Line
	    --    (Work_Window.Plugins_Model, "", Plugin_Num'image (Plugin_Id), "Unused",
	    --     Editable => False, Muttable => Plugins (Plugin_Id).Mutted, Active => Plugins (Plugin_Id).Printed, Parent => parent);
	    --end if;
	    Iter := Add_Line
	   (Work_Window.Plugins_Model, "", Plugin_Num'image (Plugin_Id), "NULL_PLUGIN",
	    Editable => True, Muttable => False, Active => False, Parent => parent);
	 end if;
      end loop;


   end Load_Plugins;

   procedure Set_In_Loop
     (Model  : access Gtk_Widget_Record'Class;
      User_Data : Work_Window_Pointer) is

      Verax : Boolean := Get_Active (Gtk_Check_Button (Model));

   begin
      Put_Line("Set in_loop");
      User_Data.Work.Options.In_Loop := Verax;
      Put_Line("Set in_loop to value :" & Boolean'Image(Verax));
      User_Data.Int.In_Loop := not Verax;
   exception
      when others =>
	 null;
   end Set_In_Loop;


   procedure Load_State (Work_Window : in Work_Window_Pointer) 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.all'access);

      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.all'access);



      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 (Work_Window.Work.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;
      
   procedure Load_Window (Work_Window : in Work_Window_Pointer) is

   begin

      --Put_Line("TOTO 1.10");
      Load_Master (Work_Window, Work_Window.Work.Options);
      --Put_Line("TOTO 1.12");
      Load_Devices (Work_Window, Work_Window.Int.Instruments);
      --Put_Line("TOTO 1.13");
      Load_Plugins (Work_Window, 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;
   
   procedure ReLoad_Window (Work_Window : in Work_Window_Pointer) is

   begin

      --Put_Line("TOTO 1.10");
      Load_Master (Work_Window, Work_Window.Work.Options);
      --Put_Line("TOTO 1.12");
      --Load_Devices (Work_Window, Work_Window.Int.Instruments);
      --Put_Line("TOTO 1.13");
      Load_Plugins (Work_Window, 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

      Name : String_access;

      Widget : Gtk_Widget;
   begin
      
      

	 
      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(Work_Window_Conversions.To_Pointer(Main_Window).Master_Frame));
	 Destroy(Get_Child(Work_Window_Conversions.To_Pointer(Main_Window).Flow_Frame));
	 
	 Destroy(Get_Child(Work_Window_Conversions.To_Pointer(Main_Window).Plugins_Frame));
	 Destroy(Get_Child(Work_Window_Conversions.To_Pointer(Main_Window).State_Frame));


	 Work_Window_Conversions.To_Pointer(Main_Window).Work.Filename := new String ' (Name.all);
	 Work_Window_Conversions.To_Pointer(Main_Window).Work.Initialize
	   (Work_Window_Conversions.To_Pointer(Main_Window).Work.Id,
	    Name.all);

	 Work_Window_Conversions.To_Pointer(Main_Window).Int.Works(Work_Window_Conversions.To_Pointer(Main_Window).Work.id) := Work_Window_Conversions.To_Pointer(Main_Window).Work;
	 
	 Work_Window_Conversions.To_Pointer(Main_Window).Int.Works_Processes(Work_Window_Conversions.To_Pointer(Main_Window).Work.id).Initialize(Work_Window_Conversions.To_Pointer(Main_Window).Int.Works(Work_Window_Conversions.To_Pointer(Main_Window).Work.id),
																     Work_Window_Conversions.To_Pointer(Main_Window).Int.Instruments'access);

	 Put_Line("Open Action :: copy process...");
	 Work_Window_Conversions.To_Pointer(Main_Window).Process := Work_Window_Conversions.To_Pointer(Main_Window).Int.Works_Processes(Work_Window_Conversions.To_Pointer(Main_Window).Work.id);
	 Put_Line("Open Action :: initialize process...");
	 Work_Window_Conversions.To_Pointer(Main_Window).Process.Process.Initialize;
	 
	 ReLoad_Window(Work_Window_Conversions.To_Pointer(Main_Window));
	 Show_All(Work_Window_Conversions.To_Pointer(Main_Window).Win);

	 Free(name);

	 Set_Title (Work_Window_Conversions.To_Pointer(Main_Window).Win,
		    "Ultrason [" & Work_Window_Conversions.To_Pointer(Main_Window).Work.Filename.all & ']');
	 
	 
	    
      end if;
   end Open_Action;

   
   Initialized : Boolean := False;

   function Self (Main : in Gm_Interface_Pointer) return Boolean is
      Running : Boolean := False;
      Focus : Boolean := False;
   begin
      if Main.Verbose then
	 Put_Line("auto start : control if not alredy running");
      end if;
      for I in Main.Works_Win'range loop
	 if not (Work_Window_Conversions."="(Main.Works_Win(I), null)) and then
	   Main.Works_Win(I).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, Main.Works_Win(Main.Last));
	       Main.Works_Win(Main.Last).Work.Started := False;
	       Put_Line("auto start");
	       Play(null, Main.Works_Win(Main.Win_Cur));
	       Main.Works_Win(Main.Win_Cur).Work.Started := True;
	       Put_Line("auto start done.");
	       present(Main.Works_Win(Main.Win_Cur).win);
	       Initialized := True;

	    else


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

	       Put_Line("auto start");
	       Play(null, Main.Works_Win(Main.Win_Cur));
	       Main.Works_Win(Main.Win_Cur).Work.Started := True;
	       present(Main.Works_Win(Main.Win_Cur).win);
	       Put_Line("auto start done.");
	    end if;

	 end if;
      end if;

      return running;
   end Self;

   
   procedure Set_Tempo_Callback
     (Model  : access Gtk_Widget_Record'Class;

      User_Data : Work_Window_Pointer) is
   begin
      User_Data.Work.Options.Tempo := Tempo_Type(Get_Value(Gtk_Spin_Button(Model)));
      --Ultrason_Composer.Start;
      Set_Focus (User_Data.Win, 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 : Work_Window_Pointer) 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));
      	 User_Data.Work.Options.Signature := (Number, Unit);
	 --Ultrason_Composer.Start;
      	 Set_Focus (User_Data.Win, 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 : Work_Window_Pointer) is
   begin
      Put_Line("Track length set...");
      User_Data.Work.Options.Track_Length := Integer(Get_Value(Gtk_Spin_Button(Widget)));
      Put_Line("Track length set to vale " & Positive'Image(User_Data.Work.Options.Track_Length));
      Set_Focus (User_Data.Win, 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 : Work_Window_Pointer) is
   begin

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


   -------------------------------------------------------
   -- Modulation Sequencer :                            --
   -------------
   -- Play On --
   -------------
   procedure Play_On (Widget : access Gtk_Widget_Record'class;
		      Main_Window : in Work_Window_Pointer) is
   begin

      Main_Window.Int.Works_Win(Main_Window.Work_Id).Process.Process.Mod_Play(True);
   end Play_On;

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

      Main_Window.Int.Works_Win(Main_Window.Work_Id).Process.Process.Mod_Play(False);
   end Play_Off;

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

      Main_Window.Int.Works_Win(Main_Window.Work_Id).Process.Process.Mod_Rec(True);
   end Rec_On;

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

      Main_Window.Int.Works_Win(Main_Window.Work_Id).Process.Process.Mod_Rec(False);
   end Rec_Off;


   -----------
   -- Reset --
   -----------
   procedure Reset (Widget : access Gtk_Widget_Record'class;
		    Main_Window : in Work_Window_Pointer) is
   begin
      Main_Window.Int.Works_Win(Main_Window.Work_Id).Process.Process.Mod_Reset;
   end Reset;



   -- 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 : Work_Window_Pointer)

   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
      if Get_Int(Text_Value) > 0 and Get_Int(Text_Value) <= 127 then
	 Set_Value (M, Iter, Text_Column, Text_Value);
      end if;
   end Text_Edited_Callback;



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

      Id : Natural := 0;
      
   begin
      --Put_Line("TETE 0.1.x");
      Old_Value := Get_Boolean (M, Iter, Active_Column);
      Set (M, Iter, Active_Column, not Old_Value);

      Id := Integer'Value(Get_String (Nth (Params, 0)));

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

      --Put_Line("TETE 0.1.y");
      Text_Io.Put_Line ("Editting device N° " & Integer'Image (Id));
      --Put_Line("TETE 0.1.z");
      Device_properties (Model, Params, User_Data);
      Text_Io.Put_Line ("Done.");
      Set (M, Iter, Active_Column, Old_Value);
   end Device_Edited_Callback;

   ---------------------
   -- Edited_Callback --
   ---------------------

   procedure Device_Printed_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Work_Window_Pointer
     )
   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 : Natural := 0;

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

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

      if User_Data.Int.Instruments.Orchester (Instrument_id(Id)) /= null then
      	 if not Old_Value then
      	    Text_Io.Put_Line ("Printing device N° " & Integer'Image (Id));
      	    Set (M, Iter, Printable_Column, not Old_Value);
      	    User_Data.Int.Instruments.Orchester (Instrument_id(Id)).Printed := True;
      	    Text_Io.Put_Line ("Done.");
      	 else
      	    Text_Io.Put_Line ("Unprinting device N° " & Integer'Image (Id));
      	    Set (M, Iter, Printable_Column, not Old_Value);
      	    User_Data.Int.Instruments.Orchester (Instrument_id(Id)).Printed := False;
      	    Text_Io.Put_Line ("Done.");
      	 end if;
      end if;


   end Device_Printed_Callback;


   procedure Device_Mutted_Callback
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Work_Window_Pointer
     )
   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 : Natural := 0;

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

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

      if User_Data.Int.Instruments.Orchester (Instrument_id(Id)) /= null then
      	 if not Old_Value then
      	    Text_Io.Put_Line ("Mutting device N° " & Integer'Image (Id));
      	    Set (M, Iter, Muttable_Column, not Old_Value);
      	    User_Data.Int.Instruments.Orchester (Instrument_Id(Id)).Mutted := True;
      	    Text_Io.Put_Line ("Done.");
      	 else
      	    Text_Io.Put_Line ("Unmutting device N° " & Integer'Image (Id));
      	    Set (M, Iter, Muttable_Column, not Old_Value);
      	    User_Data.Int.Instruments.Orchester (Instrument_Id(Id)).Mutted := False;
      	    Text_Io.Put_Line ("Done.");
      	 end if;
      end if;


   end Device_Mutted_Callback;



   -- procedure Set_input (Widget : access Gtk_Widget_Record'class; User_Data : Work_Window_Pointer);

   -- procedure Set_Output (Widget : access Gtk_Widget_Record'class; User_Data : Work_Window_Pointer);


   procedure Device_Properties
     (Model  : access GObject_Record'Class;
      Params : Glib.Values.GValues;
      User_Data : Work_Window_Pointer
      )
   is
      M           : constant Gtk_Tree_Store := Gtk_Tree_Store (Model);

      Path_String : constant String := Get_String (Nth (Params, 0));

      Iter        : constant Gtk_Tree_Iter :=
	Get_Iter_From_String (M, Path_String);

      Value : Gvalue;


      Id : Natural := 0;

      Input_Device           : Gtk.Combo_Box_Text.Gtk_Combo_Box_Text;
      Output_Device          : Gtk.Combo_Box_Text.Gtk_Combo_Box_Text;


      Vbox : Gtk_Box;
      Dialog : Gtk_Dialog;
      Widget : Gtk_Widget;


      Hbox                   : Gtk.Box.Gtk_Box;

      MSB_Bank_Max           : Gtk.Combo_Box_Text.Gtk_Combo_Box_Text;
      LSB_Bank_Max           : Gtk.Combo_Box_Text.Gtk_Combo_Box_Text;
      Bank_Label             : Gtk.Label.Gtk_Label;


      Num_Timbre_By_Prgm     : Gtk_Combo_Box_text;
      Num_Label              : Gtk_Label;

      Map_Geometry           : Map_Geometry_Type;
      Have_Drums_Kit         : Gtk_Check_Button;
      Kit_Label              : Gtk_Label;



      Ok    : Gtk.Widget.Gtk_Widget;
      Label  : Gtk_Label;

      Devices_Names : String_Access := new String ' ("");
   begin
      --Put_Line("TETE 0.1.0");
      Init(Value, Gtype_String);

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

      Gtk_New(Dialog);
      Set_Title(Gtk_Window(Dialog), "Devices properties ? ");
      Widget := Add_Button(Dialog, "OK", Gtk_Response_Ok);
      Widget := Add_Button(Dialog, "Cancel", Gtk_Response_Cancel);

      Vbox := Get_Content_Area(Dialog);

      --Put_Line("TETE 0.1.1 instrument id ::= " & Integer'Image(Id));
      if User_Data.Int.instruments.Orchester(Instrument_Id(Id)) /= null then







      	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);

      	 Gtk.Label.Gtk_New(Bank_Label, "MSB Bank max :");
      	 Gtk.Combo_Box_Text.Gtk_New(MSB_Bank_Max);
      	 for I in 0..127 loop
      	    Gtk.Combo_Box_Text.insert_Text(MSB_Bank_Max, Glib.Gint(I), Natural'Image(i));
      	 end loop;

      	 Gtk.Box.Pack_Start(Hbox, Bank_label, False, False, 3);
      	 Gtk.Box.Pack_Start(Hbox, MSB_Bank_Max, False, False, 2);
      	 Gtk.Box.Pack_Start(Vbox, hbox, False, False, 0);

      	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);

      	 Gtk.Label.Gtk_New(Bank_Label, "LSB Bank max  :");
      	 Gtk.Combo_Box_Text.Gtk_New(LSB_Bank_Max);
      	 for I in 0..127 loop
      	    Gtk.Combo_Box_Text.insert_Text(LSB_Bank_Max, Glib.Gint(I), Natural'Image(I));
      	 end loop;


      	 Gtk.Box.Pack_Start(Hbox, Bank_label, False, False, 3);
      	 Gtk.Box.Pack_Start(Hbox, LSB_Bank_Max, False, False, 2);
      	 Gtk.Box.Pack_Start(Vbox, hbox, False, False, 0);

      	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);

      	 Gtk.Combo_Box_Text.Gtk_New(Num_Timbre_By_Prgm);
      	 for I in 0..15 loop
      	    Gtk.Combo_Box_Text.insert_Text(Num_Timbre_By_Prgm, Glib.Gint(I), Natural'Image(I) & "  ");
      	 end loop;


      	 Gtk.Label.Gtk_New(Num_Label, " Num timbres    : ");

      	 Gtk.Box.Pack_Start(Hbox, Num_Label, False, False, 0);
      	 Gtk.Box.Pack_Start(Hbox, Num_Timbre_By_Prgm, False, False, 0);

      	 Gtk.Box.Pack_Start(vbox, Hbox, False, False, 0);


      	 Gtk.Combo_Box_text.Set_Active
      	   (MSB_Bank_Max,
      	    Gint(User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Map_Geometry.Bank_Geometry.MSB_Bank_Max));

      	 Gtk.Combo_Box_text.Set_Active
      	   (LSB_Bank_Max,
      	    Gint(User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Map_Geometry.Bank_Geometry.LSB_Bank_Max));


      	 Gtk.Combo_Box_text.Set_Active(Num_Timbre_By_Prgm, Gint(User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Map_Geometry.Num_Timbre));

      	 Gtk_New(Have_Drums_Kit);
      	 Set_Active(Have_Drums_Kit, User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Have_Drums_Kit);
      	 Gtk.Label.Gtk_New(Kit_Label, "Have drums kit : ");
      	 Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
      	 Gtk.Box.Pack_Start(Hbox, Kit_Label, False, False, 0);
      	 Gtk.Box.Pack_Start(Hbox, Have_Drums_Kit, False, False, 0);

      	 Gtk.Box.Pack_Start(vbox, Hbox, False, False, 0);


      	 Gtk.Combo_Box_Text.Gtk_New(Input_Device);
      	 Set_Title(Input_Device, Integer'Image(Id));
      	 Gtk.Combo_Box_text.Insert_Text(Input_Device, 0, "Unused Input");

      	 for I in 1..Instrument_Id(User_Data.Int.instruments.Inst_Last) loop
      	    Gtk.Combo_Box_Text.Insert_Text(Input_Device, Glib.Gint(I+1), User_Data.Int.instruments.Orchester(I).Input_Device_Driver.Device_Info.Name.all);
      	 end loop;
      	 --Gtk.Combo_Box.Set_Active(Input_Device, Gint(User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input_Id+1));
	 Gtk.Combo_Box_text.Set_Active(Input_Device, -1);


      	 --  Window_Cb.Connect
      	 --    (Input_device,
      	 --     "changed",
      	 --     Window_Cb.To_Marshaller(Set_Input'access),
      	 --     User_Data,
      	 --     True);



      	 Gtk.Combo_Box_text.Gtk_New(Output_Device);
      	 Set_Title(Output_Device, Integer'Image(Id));
      	 Gtk.Combo_Box_Text.Insert_Text(Output_Device, 0, "Unused Output");



      	 for I in 1..Instrument_Id(User_Data.Int.instruments.Inst_Last) loop
      	    Gtk.Combo_Box_Text.Insert_Text(Output_Device, Glib.Gint(I+1), User_Data.Int.instruments.Orchester(I).Output_Device_Driver.Device_Info.Name.all);
      	 end loop;
      	 --Gtk.Combo_Box.Set_Active(Output_Device, Gint(User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output_Id+1));
	 Gtk.Combo_Box_Text.Set_Active(Output_Device, -1);

	 --  Window_Cb.Connect
      	 --    (Output_device,
      	 --     "changed",
      	 --     Window_Cb.To_Marshaller(Set_Output'access),
      	 --     User_Data,
      	 --     True);





      	 Pack_Start(Vbox, Output_Device, False, False, 0);
      	 Pack_Start(Vbox, Input_Device, False, False, 0);



      	 Gtk.Box.Show_All(Vbox);

      	 --case Run(Dialog) is
      	 --   when Gtk_Response_Ok =>


      	       Map_Geometry.Bank_Geometry := (Bank_Type(Gtk.Combo_Box_Text.Get_Active(MSB_Bank_Max)),
      					      Bank_Type(Gtk.Combo_Box_Text.Get_Active(LSB_Bank_Max)));

      	       Map_Geometry.Num_timbre := Natural(Gtk.Combo_Box_Text.Get_Active(Num_Timbre_By_Prgm));




      	       User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Map_Geometry := Map_Geometry;
      	       User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Have_Drums_Kit := Get_Active(Have_Drums_Kit);

      	       --if User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output_Device_Driver.Device_Info.Id = -1 then
      	       --	  User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output_Device_Driver.Output_Driver := null;
      	       --else

		  --  for I in 1..Instrument_Id(User_Data.Int.instruments.Last) loop
		  --     if User_Data.Int.instruments.Orchester(I).Output_Device_Driver.Device_Info.Name.all =
		  --       User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output.Name.all then

		  --  	User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output_Driver := User_Data.Int.instruments.Orchester(I).Output_Device_Driver;
		  --  	Text_Io.Put_Line("Output Device N° " & Positive'Image(Id) & " setted for " & User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output.Name.all);
	       Devices_Names := new String ' (Devices_Names.all & "Output : " & User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Output_Device_Driver.Device_info.Name.all & Character'Val(13));
	       --     end if;
	       --  end loop;
	       null;





      	       --end if;

      	       --if User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input_Device_Driver.Device_Info.Id = -1 then

      	       --	  User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input_Device_Driver.Input_Driver := null;

      	      -- else


		  --  for I in 1..Instrument_Id(User_Data.Int.instruments.Last) loop
		  --     if User_Data.Int.instruments.Orchester(I).Input_Device_Driver.Device_Info.Name.all =
		  --       User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input.Name.all then

		  --  	User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input_Driver := User_Data.Int.instruments.Orchester(I).Input_Device_Driver;
		  --  	Text_Io.Put_Line("Input Device N° " & Positive'Image(Id) & " setted for " & User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input.Name.all);
	       Devices_Names := new String ' (Devices_Names.all & "Input : " & User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Input_Device_Driver.Device_Info.Name.all & Character'Val(13));
	       --     end if;
	       --  end loop;
      	       null;

	       -- end if;

      	       Set_String(Value, Devices_Names.all);
      	       Set_Value (M, Iter, Type_Column, Value);
      	 --   when others =>



      	       null;
      	 --end case;
	 --User_Data.Int.instruments.Orchester(Instrument_Id(Id)).Device_Num := Id;


	 --Destroy(Dialog);



      end if;

   end Device_Properties;


   --  procedure Set_Device_Id (Widget : access Gtk_Widget_Record'class;
   --  			    Plugin : Abstract_Plugin_access);

   --  procedure Set_Channel (Widget : access Gtk_Widget_Record'class;
   --  			  Plugin : Abstract_Plugin_access);

   --  procedure Set_Form (Widget : access Gtk_Widget_Record'class;
   --  		       Plugin : Abstract_Plugin_access);

   --  procedure Set_category (Widget : access Gtk_Widget_Record'class;
   --  			   Plugin : Abstract_Plugin_access);

   --  procedure Set_Algo (Widget : access Gtk_Widget_Record'Class;
   --  		       Plugin : Abstract_Plugin_Access);

   procedure True_Table_Changed (Widget : access Gtk_Widget_Record'class;
				 Ultrason : Work_Window_Pointer);

   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 (Ultrason : in Work_Window_Pointer;
			      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 => Ultrason.Work.Options.True_Table(Plugin.Cat_Id, Prev_Id, Null_Break),

	       Down_Break => Ultrason.Work.Options.True_Table(Plugin.Cat_Id, Prev_Id, Down_break),

	       Up_Break => Ultrason.Work.Options.True_Table(Plugin.Cat_Id, Prev_Id, Up_break),

	       Full_Break => Ultrason.Work.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 => Ultrason.Work.Options.True_Table(1, Prev_Id, Null_Break),

	       Down_Break => Ultrason.Work.Options.True_Table(1, Prev_Id, Down_break),

	       Up_Break => Ultrason.Work.Options.True_Table(1, Prev_Id, Up_break),

	       Full_Break => Ultrason.Work.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;


   procedure True_Table_Changed (Widget : access Gtk_Widget_Record'class;
				 Ultrason : Work_Window_Pointer) is
   begin
      for I in Ultrason.Plugins_Pages'range loop
	 if Ultrason.Plugins_Pages(I).Opened then
	    Clear(Ultrason.Plugins_Pages(I).True_Table_Model);
	    Destroy(Get_Child(Ultrason.Plugins_Pages(I).True_Table_Frame));
	    Load_True_Table (Ultrason, Ultrason.Plugins_Pages(I).all, Ultrason.Work.Plugins(I));
	    Show_All(Ultrason.Plugins_Pages(I).True_Table_Frame);
	 end if;
      end loop;

   end True_Table_Changed;



   package Plugin_CB is new Gtk.Handlers.User_Callback
     (Gtk_Widget_Record,
      Abstract_Plugin_Access);



   --  procedure Load_Options (Ultrason : in Work_Window_Pointer;
   --  			   Page : in out Plugin_Page_Type;
   --  			   Plugin : in Abstract_Plugin_Access;
   --  			   Id : in Plugin_Num) is
   --     Hbox : Gtk_Box;
   --     Timbre_Category_Label : Gtk_Label;
   --     Channel_Label         : Gtk_Label;
   --     Form_Label            : Gtk_Label;
   --     Device_Label          : Gtk_Label;
   --  begin

   --     Gtk_New_Vbox(Page.Details_Box);

   --     Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
   --     Gtk.Combo_Box_Text.Gtk_New(Page.Device_Id);
   --     Put_Line("Plug 2.2.0");
   --     for I in 0..Device_num'Last-1 loop
   --  	 Gtk.Combo_Box_Text.insert_Text(Page.Device_Id, Glib.Gint(I), Natural'Image(Natural(I+1)));
   --     end loop;
   --     Put_Line("Plug 2.2.0.1");
   --     if Plugin /= null then
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.Device_Id, Gint(Plugin.Device_id-1));
   --     else
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.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, Page.Device_Id, False, False, 0);
   --     Put_Line("Plug 2.2.0.3");
   --     Gtk.Box.Pack_Start(Page.Details_Box, Hbox, False, False, 0);
   --     Put_Line("Plug 2.2.0.4");
   --     Plugin_Cb.Connect(Page.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(Page.Timbre_Channel);
   --     for I in 0..15 loop
   --  	 Gtk.Combo_Box_Text.insert_Text(Page.Timbre_Channel, Glib.Gint(I), Natural'Image(I+1));
   --     end loop;
   --     if Plugin /= null then
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.Timbre_Channel, Gint(Plugin.Ch_Id-1));
   --     else
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.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, Page.Timbre_Channel, False, False, 0);
   --     Gtk.Box.Pack_Start(Page.Details_Box, Hbox, False, False, 0);
   --     Plugin_Cb.Connect(Page.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(Page.Timbre_Category);
   --     for I in 0 .. Ultrason.Work.Options.Categories.Last - 1 loop
   --  	 Gtk.Combo_Box_Text.insert_Text(Page.Timbre_Category, Glib.Gint(I), Ultrason.work.Options.Categories.category(I + 1).all);
   --     end loop;
   --     if Plugin /= null then
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.Timbre_Category, Gint(Plugin.Cat_id-1));
   --     else
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.Timbre_Category, Gint(0));
   --     end if;
   --     Gtk.Box.Pack_Start(Hbox, Timbre_Category_label, False, False);
   --     Gtk.Box.Pack_Start(Hbox, Page.Timbre_Category, False, False);
   --     Gtk.Box.Pack_Start(Page.Details_Box, hbox, False, False);
   --     Plugin_Cb.Connect(Page.Timbre_Category, "changed",
   --  			Plugin_Cb.To_Marshaller(Set_Category'Access),
   --  			Plugin);
   --     Window_Cb.Connect(Page.Timbre_Category, "changed",
   --  			Window_Cb.To_Marshaller(True_Table_Changed'Access),
   --  			Ultrason);
   --     Put_Line("Plug 2.2.3");
   --     Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
   --     Gtk.Combo_Box_Text.Gtk_New(Page.Played_Form);
   --     for I in 0 .. Ultrason.work.Options.Forms_Names'Length-1 loop
   --     	 Gtk.Combo_Box_Text.insert_Text(Page.Played_Form, Glib.Gint(I), Glib.Convert.Locale_To_UTF8(Ultrason.work.Options.Forms_names(Form_Index_Type(I+1)).all));
   --     end loop;
   --     if Plugin /= null then
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.Played_Form, Gint(Plugin.Form_id-1));
   --     else
   --  	 Gtk.Combo_Box_Text.Set_Active(Page.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, Page.Played_Form, False, False, 0);
   --     Gtk.Box.Pack_Start(Page.Details_Box, Hbox, False, False, 0);
   --     Plugin_Cb.Connect(Page.Played_Form, "changed",
   --  			Plugin_Cb.To_Marshaller(Set_Form'Access),
   --  			Plugin);
   --     Window_Cb.Connect(Page.Played_Form, "changed",
   --  			Window_Cb.To_Marshaller(True_Table_Changed'Access),
   --  			Ultrason);
   --     Put_Line("Plug 2.2.4");
   --     --Gtk.Box.Gtk_New_Hbox(Hbox, Homogeneous => false);
   --     --  Gtk.Combo_Box_Text.Gtk_New(Page.Algo_Combo_Box);
   --     --  for I in Algo_Type'Range loop
   --     --  	 Gtk.Combo_Box_Text.insert_Text(Page.Algo_Combo_box, Glib.Gint(Algo_Type'Pos(I)), Algo_Type'Image(I));
   --     --  end loop;
   --     --  Gtk.Combo_Box_Text.Set_Active(Page.Algo_Combo_Box, Gint(Algo_Type'Pos(Plugin.Algo)));
   --     --  Gtk.Label.Gtk_New(Form_label, "Algo :");

   --     --Gtk.Box.Pack_Start(Hbox, Page.Algo_Combo_Box, False, False, 0);

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

   --     Put_Line("Plug 2.2.5");
   --     Add(Page.Details_Frame, Page.Details_Box);
   --     Put_Line("Plug 2.2.6");
   --  end Load_Options;

   --  procedure Set_Device_Id (Widget : access Gtk_Widget_Record'Class;
   --  			    Plugin : Abstract_Plugin_Access) is
   --  begin
   --     if Plugin /= null then
   --  	 Plugin.Device_Id := Device_num(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box(widget))+1);
   --     end if;
   --  end Set_Device_Id;

   --  procedure Set_Algo (Widget : access Gtk_Widget_Record'Class;
   --  		       Plugin : Abstract_Plugin_Access) is
   --  begin
   --     Plugin.Algo := Algo_Type'Val(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box(widget)));
   --  end Set_Algo;


   --  procedure Set_Channel (Widget : access Gtk_Widget_Record'class;
   --  			  Plugin : Abstract_Plugin_access) is
   --  begin
   --     if Plugin /= null then
   --  	 Plugin.Ch_Id := Channel_Num(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box(widget)));
   --     end if;
   --  end Set_Channel;

   procedure Set_Form (Widget : access Gtk_Widget_Record'class;
		       plugin : Abstract_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 : Abstract_Plugin_access) is
   --  begin
   --     if Plugin /= null then
   --  	 Plugin.Cat_Id := Category_Index_Type(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box(widget))+1);
   --     end if;
   --  end Set_Category;


   procedure Load_Plugin_Page (Work_Window : in Work_Window_Pointer;
			       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
	 --     when Null_Plugin =>
	 --        null;
	 --     when Step_Seq =>
	 --        --Gtk_Step_Sequencer.Initialize(Step_Seq_Specifications(Page.Plugin_Spec.all), Step_Seq_Plugin_Record(Plugin.all));
	 --        Gtk_Step_Sequencer.Load_Specifications(Page, Plugin, Id);
	 --     when others =>
	 --        null;
	 --  end case;
      end if;

      --Load_Sequencer (Work_Window, Page, Plugin, Id);
      --Put_Line("Plug 2.2");
      --Load_Options (Work_Window, Page, Plugin, Id);
      --Put_Line("Plug 2.3");
      Load_True_Table (Work_Window, Page, Plugin);
      --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 Work_Window_Pointer;
				 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 class selection for Plugin id" & Plugin_Num'Image(Id), Work_Window.Win, 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) 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), Work_Window.Win, 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 .. Work_Window.Work.Options.Categories.Last - 1 loop
	    Gtk.Combo_Box_Text.insert_Text(Work_Window.Plugins_Pages(Id).Timbre_Category, Glib.Gint(I), Work_Window.work.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),
	 --  			Plugin);
	 --  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 .. Work_Window.work.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(Work_Window.work.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),
	 --  			Plugin);
	 --  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 : Work_Window_Pointer
     )
   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 : Work_Window_Pointer
     )
   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 : Work_Window_Pointer
     )
   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;



   --------------
   -- 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 : Work_Window_Pointer) 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 : Work_Window_Pointer) return Boolean;

   function Work_State_Update (Work_Window : Work_Window_Pointer) 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(Work_Window.Work.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 (Work_Window.Work.States.Bar_Beat));

      return True;
   end Work_State_Update;

   package Ultrason_G_Source is new Glib.Main.Generic_Sources(Work_Window_Pointer);

   procedure Play (Widget : access Gtk_Widget_Record'class;
                   Main_Window : in Work_Window_Pointer) is

      pragma Unreferenced (Widget);
   begin

      if Main_Window.Flow_Control = Glib.Main.No_Source_Id then
	 Main_Window.Flow_Control :=
	   Ultrason_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 :=
	   Ultrason_G_Source.Timeout_Add
	   (100,
	    Work_State_Update'Access,
	    Main_Window);
      end if;
      Main_Window.Int.Works_Win(Main_Window.Work_Id).Process.Process.Start;
   end Play;

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

      pragma Unreferenced (Widget);

   begin
      if Main_Window /= null then
	 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...");
	 
	 Main_Window.Int.Works_Win(Main_Window.Int.Win_Cur).Process.Process.Stop;

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

   
end Libsens.Applications.Gm_Interface;