with Glib;                              use Glib;
with Glib.Object;                       use Glib.Object;

with Gtk.Handlers;                      use Gtk.Handlers;
pragma Elaborate_All (Gtk.Handlers);
with Gtk.Widget;                        use Gtk.Widget;
with Gtk.Enums;                         use Gtk.Enums;
with Gtk.Frame;                         use Gtk.Frame;
with Gtk.Box;                           use Gtk.Box;
with Gtk.Label;                         use Gtk.Label;


with Libsens.Virtual.nn_plugin;         use Libsens.Virtual.NN_Plugin;

with PragmARC.REM_NN_Wrapper;
use PragmARC.REM_NN_Wrapper;


with Text_Io;                           use Text_Io;


package body Libsens.Gtk_Neural is
   
   ----------------------
   -- Neural generator --
   ----------------------   
   
  
   package Plugin_Cb is new Gtk.Handlers.User_Callback 
     (Gtk.Widget.Gtk_Widget_Record, 
      Abstract_Plugin_Access);
   
   
   procedure Name_Mono_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Mono_Plugin_Record(Plugin.all).name := new String ' (Gtk.Gentry.Get_text(Gtk_entry(Widget)));
   exception
      when others =>
	 null;
   end Name_Mono_Callback;
   
   procedure Reuse_Mono_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Mono_Plugin_Record(Plugin.all).Reuse := Boolean'Val(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box_Text(Widget)));
   exception
      when others =>
	 null;
   end Reuse_Mono_Callback;

   
   procedure Width_Mono_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Mono_Plugin_Record(Plugin.all).width := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Width_Mono_Callback;
   
   procedure Sample_Max_Mono_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Mono_Plugin_Record(Plugin.all).Sample_Max := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Sample_Max_Mono_Callback;
   
   
   procedure Converged_Mono_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Mono_Plugin_Record(Plugin.all).Converged := real(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Converged_Mono_Callback;
   
   procedure Max_Epoch_Mono_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Mono_Plugin_Record(Plugin.all).Max_Epoch := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Max_Epoch_Mono_Callback;

   
            
   procedure Initialize (Spec : in out Neural_Mono_Specifications;
     			 Plugin : in Abstract_Plugin_access) is            
      
      
      
      Vbox : Gtk_Vbox;
      Label : Gtk_Label;
      Hbox : Gtk_Hbox;
   begin      
      
      
      Gtk_New(Spec.Specifications_Frame, "Neural mono : ");
      
      Gtk_New_Vbox(Vbox, Homogeneous => False);
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Weight filename : ");
      Gtk_New(Spec.Network.Name);
      Set_text(Spec.Network.Name, NN_Mono_Plugin_Record(Plugin.all).Network_Name.all);
      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Name, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Name, "activate", Plugin_Cb.To_Marshaller(Name_Mono_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      Gtk_New(Spec.Network.Width, 4.0, 16.0, 1.0);
      Set_Value(Spec.Network.Width, Gdouble(NN_Mono_Plugin_Record(Plugin.all).Width));
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Network width   : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.width, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
            
      Plugin_Cb.Connect
        (Spec.Network.Width, "value_changed", Plugin_Cb.To_Marshaller(Width_Mono_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Sample_Max, 64.0, 1024.0, 16.0);
      Set_Value(Spec.Network.Sample_max, Gdouble(NN_Mono_Plugin_Record(Plugin.all).Sample_Max));
      
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Sample max      : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Sample_Max, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Sample_Max, "value_changed", Plugin_Cb.To_Marshaller(Sample_Max_Mono_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      
      
      Gtk_New(Spec.Network.Reuse);
      Insert_Text(Spec.Network.Reuse, 0, Boolean'Image(False));
      Insert_Text(Spec.Network.Reuse, 1, Boolean'Image(True));                  
      Set_Active(Spec.Network.Reuse, Boolean'Pos(NN_Mono_Plugin_Record(Plugin.all).Reuse));
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Reuse network   : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Reuse, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Reuse, "changed", Plugin_Cb.To_Marshaller(Reuse_Mono_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Converged, 0.0001, 1.0, 0.0001);
      Set_Value(Spec.Network.Converged, Gdouble(NN_Mono_Plugin_Record(Plugin.all).Converged));
           
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Converged       :");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Converged, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      
      Plugin_Cb.Connect
        (Spec.Network.Converged, "value_changed", Plugin_Cb.To_Marshaller(Converged_Mono_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Max_Epoch, 1.0, 65537.0, 128.0);
      Set_Value(Spec.Network.Max_Epoch, Gdouble(NN_Mono_Plugin_Record(Plugin.all).Max_Epoch));

      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Max epoch       : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Max_epoch, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      
      Plugin_Cb.Connect
        (Spec.Network.Max_Epoch, "value_changed", Plugin_Cb.To_Marshaller(Max_Epoch_Mono_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      
      Add (Spec.Specifications_Frame, Vbox);      
      
      --Put_Line("Load seq 0.1.8.1");
      
   end Initialize;
   
   
   procedure Name_Poly_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Poly_Plugin_Record(Plugin.all).name := new String ' (Gtk.Gentry.Get_text(Gtk_entry(Widget)));
   exception
      when others =>
	 null;
   end Name_Poly_Callback;
   
   procedure Reuse_Poly_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Poly_Plugin_Record(Plugin.all).Reuse := Boolean'Val(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box_Text(Widget)));
   exception
      when others =>
	 null;
   end Reuse_Poly_Callback;

   
   procedure Width_Poly_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Poly_Plugin_Record(Plugin.all).width := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Width_Poly_Callback;
   
   procedure Sample_Max_Poly_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Poly_Plugin_Record(Plugin.all).Sample_Max := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Sample_Max_Poly_Callback;
   
   
   procedure Converged_Poly_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Poly_Plugin_Record(Plugin.all).Converged := real(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Converged_Poly_Callback;
   
   procedure Max_Epoch_Poly_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Poly_Plugin_Record(Plugin.all).Max_Epoch := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Max_Epoch_Poly_Callback;

   
   procedure Initialize (Spec : in out Neural_Poly_Specifications;
     			 Plugin : in Abstract_Plugin_access) is
      

      
      
      
      Vbox : Gtk_Vbox;
      Label : Gtk_Label;
      Hbox : Gtk_Hbox;
   begin
      
      
      
      Gtk_New(Spec.Specifications_Frame, "Neural poly : ");
      
      Gtk_New_Vbox(Vbox, Homogeneous => False);
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Weight filename : ");
      Gtk_New(Spec.Network.Name);
      Set_text(Spec.Network.Name, NN_Poly_Plugin_Record(Plugin.all).Network_Name.all);
      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Name, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Name, "activate", Plugin_Cb.To_Marshaller(Name_Poly_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      Gtk_New(Spec.Network.Width, 4.0, 16.0, 1.0);
      Set_Value(Spec.Network.Width, Gdouble(NN_Poly_Plugin_Record(Plugin.all).Width));
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Network width   : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.width, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
            
      Plugin_Cb.Connect
        (Spec.Network.Width, "value_changed", Plugin_Cb.To_Marshaller(Width_Poly_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Sample_Max, 64.0, 1024.0, 16.0);
      Set_Value(Spec.Network.Sample_max, Gdouble(NN_Poly_Plugin_Record(Plugin.all).Sample_Max));
      
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Sample max      : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Sample_Max, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Sample_Max, "value_changed", Plugin_Cb.To_Marshaller(Sample_Max_Poly_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      
      
      Gtk_New(Spec.Network.Reuse);
      Insert_Text(Spec.Network.Reuse, 0, Boolean'Image(False));
      Insert_Text(Spec.Network.Reuse, 1, Boolean'Image(True));                  
      Set_Active(Spec.Network.Reuse, Boolean'Pos(NN_Poly_Plugin_Record(Plugin.all).Reuse));
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Reuse network   : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Reuse, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Reuse, "changed", Plugin_Cb.To_Marshaller(Reuse_Poly_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Converged, 0.0001, 1.0, 0.0001);
      Set_Value(Spec.Network.Converged, Gdouble(NN_Poly_Plugin_Record(Plugin.all).Converged));
           
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Converged       :");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Converged, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      
      Plugin_Cb.Connect
        (Spec.Network.Converged, "value_changed", Plugin_Cb.To_Marshaller(Converged_Poly_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Max_Epoch, 1.0, 65537.0, 128.0);
      Set_Value(Spec.Network.Max_Epoch, Gdouble(NN_Poly_Plugin_Record(Plugin.all).Max_Epoch));

      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Max epoch       : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Max_epoch, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      
      Plugin_Cb.Connect
        (Spec.Network.Max_Epoch, "value_changed", Plugin_Cb.To_Marshaller(Max_Epoch_Poly_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      
      Add (Spec.Specifications_Frame, Vbox);      
      

      
      
      --Put_Line("Load seq 0.1.8.1");
      
   end Initialize;
   
   
   procedure Name_Rythm_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Rythm_Plugin_Record(Plugin.all).name := new String ' (Gtk.Gentry.Get_text(Gtk_entry(Widget)));
   exception
      when others =>
	 null;
   end Name_Rythm_Callback;
   
   procedure Reuse_Rythm_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Rythm_Plugin_Record(Plugin.all).Reuse := Boolean'Val(Gtk.Combo_Box_Text.Get_Active(Gtk_Combo_Box_Text(Widget)));
   exception
      when others =>
	 null;
   end Reuse_Rythm_Callback;

   
   procedure Width_Rythm_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Rythm_Plugin_Record(Plugin.all).width := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Width_Rythm_Callback;
   
   procedure Sample_Max_Rythm_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Rythm_Plugin_Record(Plugin.all).Sample_Max := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Sample_Max_Rythm_Callback;
   
   
   procedure Converged_Rythm_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Rythm_Plugin_Record(Plugin.all).Converged := real(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Converged_Rythm_Callback;
   
   procedure Max_Epoch_Rythm_Callback
     (Widget  : access Gtk_Widget_Record'Class;      
      Plugin : Abstract_Plugin_Access) is
   begin      
      NN_Rythm_Plugin_Record(Plugin.all).Max_Epoch := Integer(Gtk.Spin_Button.Get_Value(Gtk_Spin_Button(Widget)));
   exception
      when others =>
	 null;
   end Max_Epoch_Rythm_Callback;

   
   procedure Initialize (Spec : in out Neural_Rythm_Specifications;
     			 Plugin : in Abstract_Plugin_access) is
      

      
      
      
      Vbox : Gtk_Vbox;
      Label : Gtk_Label;
      Hbox : Gtk_Hbox;
   begin
      
      
      
      Gtk_New(Spec.Specifications_Frame, "Neural rythm : ");
      
      Gtk_New_Vbox(Vbox, Homogeneous => False);
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Weight filename : ");
      Gtk_New(Spec.Network.Name);
      Set_text(Spec.Network.Name, NN_Rythm_Plugin_Record(Plugin.all).Network_Name.all);
      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Name, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Name, "activate", Plugin_Cb.To_Marshaller(Name_Rythm_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      Gtk_New(Spec.Network.Width, 4.0, 16.0, 1.0);
      Set_Value(Spec.Network.Width, Gdouble(NN_Rythm_Plugin_Record(Plugin.all).Width));
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Network width   : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.width, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
            
      Plugin_Cb.Connect
        (Spec.Network.Width, "value_changed", Plugin_Cb.To_Marshaller(Width_Rythm_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Sample_Max, 64.0, 1024.0, 16.0);
      Set_Value(Spec.Network.Sample_max, Gdouble(NN_Rythm_Plugin_Record(Plugin.all).Sample_Max));
      
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Sample max      : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Sample_Max, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Sample_Max, "value_changed", Plugin_Cb.To_Marshaller(Sample_Max_Rythm_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      
      
      Gtk_New(Spec.Network.Reuse);
      Insert_Text(Spec.Network.Reuse, 0, Boolean'Image(False));
      Insert_Text(Spec.Network.Reuse, 1, Boolean'Image(True));                  
      Set_Active(Spec.Network.Reuse, Boolean'Pos(NN_Rythm_Plugin_Record(Plugin.all).Reuse));
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Reuse network   : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Reuse, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      Plugin_Cb.Connect
        (Spec.Network.Reuse, "changed", Plugin_Cb.To_Marshaller(Reuse_Rythm_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Converged, 0.0001, 1.0, 0.0001);
      Set_Value(Spec.Network.Converged, Gdouble(NN_Rythm_Plugin_Record(Plugin.all).Converged));
           
      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Converged       :");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Converged, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      
      Plugin_Cb.Connect
        (Spec.Network.Converged, "value_changed", Plugin_Cb.To_Marshaller(Converged_Rythm_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      Gtk_New(Spec.Network.Max_Epoch, 1.0, 65537.0, 128.0);
      Set_Value(Spec.Network.Max_Epoch, Gdouble(NN_Rythm_Plugin_Record(Plugin.all).Max_Epoch));

      Gtk_New_Hbox(Hbox);
      Gtk_New(Label, "Max epoch       : ");      
      Pack_Start(Hbox, Label, False, False, 2);
      Pack_Start(Hbox, Spec.Network.Max_epoch, False, False, 2);
      Pack_Start(Vbox, Hbox, False, False, 2);
      
      
      Plugin_Cb.Connect
        (Spec.Network.Max_Epoch, "value_changed", Plugin_Cb.To_Marshaller(Max_Epoch_Rythm_Callback'Access),
	 User_Data => Plugin);
      
      
      
      
      
      
      Add (Spec.Specifications_Frame, Vbox);      
      

      --Put_Line("Load seq 0.1.8.1");
      
   end Initialize;
      
end Libsens.Gtk_Neural;