--------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Gnostic is Ada Generic Neural Object System Engineering.                                                                                                --
-- Gnostic (C) Copyright 2016 Manuel De Girardi.                                                                                                           --
--------------------------------------------------------------------------------------------------------------------------------------------------------------
  
--------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Date        := 2016-11-30 21:43:38 ; 
-- Description : Ada Generic Neural Object System Engineering.                                                                                              --
-- Version     := 2016.26.1a ; 
-- Authors     : Manuel De Girardi.                                                                                                                         --
--------------------------------------------------------------------------------------------------------------------------------------------------------------

with Gnos.Versions.Environment;
with Gnos.Parameters;
use Gnos.Parameters;

with Gnos.Gnose;
with Gtk.Paned;
with Gtk.Frame;
with Gtk.Box;
with Gtk.Scrolled_Window;
with Gtk.Notebook;
with Gtk.Text_View;
with Gtk.Text_Buffer;
--with Gtk.Text;
with Gtkada.Canvas;
with Gdk;
with Gdk.Color;
with Cairo;
with Glib;
with Glib.Main;

use Gtk.Paned;
use Gtk.Frame;
use Gtk.Box;
use Gtk.Scrolled_Window;
use Gtk.Notebook;
use Gtk.Text_View;
use Gtk.Text_Buffer;
--use Gtk.Text;
use Gtkada.Canvas;
use Gdk;
use Gdk.Color;
use Cairo;
use Glib;
use Glib.Main;
with Pango.Layout;        use Pango.Layout;
with Gdk.Event;           use Gdk.Event;

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

with Gtk.Window;
use Gtk.Window;
with Gtk.UI_Manager;                    use Gtk.UI_Manager;
with Gtk.Action_Group;                  use Gtk.Action_Group;

with System.Address_To_Access_Conversions;
use System;
with Ada.Calendar;
use Ada.Calendar;

with Gnat.OS_Lib;
use Gnat.Os_Lib;

with Gnos.Results;
use Gnos.Results;

package Gnos.Windows is
   
   Gnose_Params : Gnose_Parameters_Type;
   
   package Agnose is new Gnos.Gnose(Gnose_Params);
   use Agnose;
   use Agnose.Neural;
   use Agnose.Neural.Objects_System;
   use Agnose.Neural.Objects_System.Objects_system;
   use Agnose.Neural.Objects_System.Objects_System.Language;
   use Agnose.Neural.Objects_System.Objects_System.Language.Agnose_Projects;
   
   package Environment is new Gnos.Versions.Environment(Agnose.Neural.Objects_System.Objects_System.Language.Agnose_Projects);
   use Environment;
   
   type Gnose_Record;
   
   task type Gnose_Process(Gnostic : access Gnose_Record) is
      entry Initialize
	(Date : in Time;
	 Self, User : in Duration);
      entry Run(Programming, Executed : in Boolean);
      entry Halt;
      entry Suspend;
      entry Respond;
      entry Train;
      entry Info;
      entry Set_Neural(Human_Lang : in Human_Lang_Enum);      
      entry Get_Language(Language_Unit : out Language_Unit_Access;
			 Machine_Lang : in Machine_Lang_Enum);
      entry Get_Neural(Neural_Unit : out Neural_Unit_Access;
		       Human_Lang : in Human_Lang_Enum);      
      entry Build;
      entry Execute;
   end Gnose_Process;
   
   type Gnose_Access is access all Gnose_Record;
     
   Pro_Path : constant String := ".";
   Ada_Path : constant String := "/usr/lib/gcc/x86_64-linux-gnu/8/adainclude/";
   Gtk_Path : constant String := "/usr/share/ada/adainclude/gtkada/";
   Aws_Path : constant String := "/usr/share/ada/adainclude/aws/";

   function Gnose_Initialize
     (Gnose_Context : access Gnose_Context_Record;
      Gnose_Params : access Gnose_Parameters_Type)
          return Gnose_Access;
   
   
   
   type Common_Paned_Frame_Type is abstract tagged
      record
	 Frame  : Gtk_Frame;
	 Box    : Gtk_Vbox;
	 Scroll : Gtk_Scrolled_Window;
      end record;
   
   type Machine_Language_Frame_Type is new Common_Paned_Frame_Type with null record;
   
   type Machine_Access is access Machine_Language_Frame_Type;
   
   type Machine_Set is array (Machine_Lang_Enum) of Machine_Access;
   
   type Human_Language_Frame_Type is new Common_Paned_Frame_Type with null record;
   
   type Human_Language_Frame_Access is access all Human_Language_Frame_Type;
   
   
   type Parmeters_Frame_Type is new Common_Paned_Frame_Type with null record;
   
   type Image_Canvas_Record is new Interactive_Canvas_Record with null record;
      
   type Image_Canvas is access all Image_Canvas_Record'Class;
   
   type Display_Item_Record is new Canvas_Item_Record with record
      Canvas : Interactive_Canvas;
      Color  : Gdk.Color.Gdk_Color;
      Title  : Gdk.Color.Gdk_Color;
      W, H   : Gint;
      Num    : Positive;
      Name     : Name_type := (others => ' ');
      Filename : Name_Type := (others => ' ');
   end record;
   
   type Display_Item is access all Display_Item_Record'Class;
   
   
   procedure Draw
     (Item   : access Display_Item_Record;
      Cr     : Cairo_Context);
   --  Draw the item to the double-buffer   
   
   function On_Button_click(Item   : access Display_Item_Record;
			    Event  : Gdk.Event.Gdk_Event_Button) return Boolean;
   
   type Item_Array_Type is array (Positive range <>) of Display_Item;         
   
   
   Item_Max : constant Positive := 8192;
   
   type Canvas_Record_Type is
      record
	 Frame      : Gtk_Frame;
	 Box        : Gtk_Vbox;
	 Scroll     : Gtk_Scrolled_Window;
	 Canvas     : Image_Canvas;
	 Item_Array : Item_Array_Type(1..Item_Max);
	 Item_Last  : Natural := 0;	 
	 ----------------------
	 -- The layout.      --
	 ----------------------
	 Layout : Pango_Layout;
	 X_ads : Gint := 400;
	 Y_ads : Gint := 50;
	 
	 X_adb : Gint := 200;
	 Y_adb : Gint := 100;	 
      end record;
   
   type Canvas_Record_Access is access Canvas_Record_Type;
   
   type Canvas_Set is array (Machine_Lang_Enum) of Canvas_Record_Access;
   
   
   
   type Gnose_Interface_Record is new Gtk_Window_Record with
      record
	 UI            : Gtk_UI_Manager;
	 Actions       : Gtk_Action_Group;
	 Gnostic       : Gnose_Access;	 
	 End_Of_Task   : Boolean := False;
	 
	 Main_Vbox     : Gtk_Vbox;
	 
	 Language_Set   : Machine_Set;
	 
	 System_Frame           : Human_Language_Frame_Type;
	 System_Text_view       : Gtk_Text_view;	
	 System_Text_buffer     : Gtk_Text_buffer;	
	 System_Scroll          : Gtk_Scrolled_Window;	 
	 
	 User_Frame           : Human_Language_Frame_Type;	 	 
	 User_Text_View       : Gtk.Text_View.Gtk_Text_View;	 
	 User_Text_Buffer     : Gtk.Text_Buffer.Gtk_Text_Buffer;
	 User_Handler         : Handler_Id;
	 User_Position        : Natural := 0;
	 User_Scroll          : Gtk_Scrolled_Window;
	 
	 Parmeters_Frame : Parmeters_Frame_Type;
	 
	 
	 Main_Pan : Gtk_Vpaned;
	 Bot_Main_Pan : Gtk_Hpaned;
	 Bot_Second_Pan : Gtk_Hpaned;
	 
	 First_Machines_Left_Pan : Gtk_Vpaned;
	 Second_Machines_Left_Pan : Gtk_Vpaned;
	 
	 Human_Pan : Gtk_Vpaned;
	 
	 Project_Pan : Gtk_Vpaned;
	 
	 Graph_Book : Gtk_Notebook;
	 Book_Index : Natural := 0;
	 Graph_Set  : Canvas_Set;	 	 
	 
   end record;      
   
   type Gnose_Interface_Access is access Gnose_Interface_Record;
   
   type System_Step_Enum is (List, Prepare, Computation, Reload, Update, Clean, Arch, Build, Restart, At_Limit, On_Error);
   
   -- Message Timeout Enumeration :
   type Message_Enum is (Automation_Message,
			 On_Error_Message,
			 System_Step_Message,
			 Computation_message);
   
   type Planning_Enum is (Spec, Impl);

   type Gnose_Record is limited
      record
	 Context              : access Agnose.Gnose_Context_Record;
	 System               : Agnose.Neural.Neural_System;
	 Process              : Gnose_Process(Gnose_Record'Access);	 
	 Gnose_Interface      : Gnose_Interface_Access;
	 Id                   : Process_Id;	 
	 Self_Execute_Timeout : Glib.Main.G_Source_Id;
	 Exit_Result          : Results.Spawn_Result_Type;
	 System_Step          : System_Step_Enum := List;
	 System_Error         : System_Step_Enum := List;
	 Plan                 : Planning_Enum := Spec;
      end record;
      
   package Window_Conversions is new Address_To_Access_Conversions(Gnose_Record);
   
   use Window_Conversions;
   
   package Main_Timeout is new Glib.Main.generic_sources(Object_Pointer);
   use Main_Timeout;
   
end Gnos.Windows;