-- Workstation is attempt of A. i. written with Ada.
-- Workstation is Copyright (C) 2023 Manuel De Girardi ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2023-08-14 07:53:20"
-- Version := "4.0.0r"
with Work.Classes.Note_class;
with Work.Classes.Profile_class;
with Work.Classes.Car_class;
with Work.Classes.Contact_class;
with Work.Classes.Content_class;
with Work.Classes.Event_class;
with Work.Classes.Planning_class;
with Work.Classes.Job_class;
with Work.Classes.Machine_class;
with Work.Classes.Activity_class;
with Work.Classes.Universe_class;
with Work.Classes.Compta_Line_class;
with Work.Classes.Account_class;
with Work.Classes.Account_Line_class;
with Work.Classes.Component_class;
with Work.Classes.house_class;
with Work.Classes.Planning_class;

package body Work.Classes.Main is
   
   function Fit (Object : in Object_Class'class) return Float is
   begin
      return 1.0;
   end Fit;
   
   procedure Mutate(Object : in out Object_Class'class) is
      O : Object_Access;
   begin
      null;
   end Mutate;
   
   function Mute(Left : in Object_Class'class; 
		 Right : in Object_Class'class) return Object_Class'Class is
      O : Object_Access;
   begin
      return O.all;
   end Mute;
   
   
   function Successor (O : in Object_Access) return Object_Array is
      
   begin
      case O.Class_Name is
	 when Universe =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       --T(1) := new Universe_Class.Universe_Class;
	       T(1) := Copy(O);
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Profile =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := Copy(O);
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Planning =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class ' (Planning_Class.Planning_Class(O.all));
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Job =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := Copy(O);
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Event =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := Copy(O);
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Machine =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := Copy(O);
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Account =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := Copy(O);
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Account_Line =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := Copy(O);
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Activity =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := Copy(O);
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Compta_Line =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := Copy(O);
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Note =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := Copy(O);
	       return T.all;
	    end;
	 when Component =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Contact =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := Copy(O);
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Content =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := Copy(O);
	       
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when House =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := Copy(O);
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := new Car_Class.Car_Class;
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
	 when Car =>
	    declare
	       T : access Object_Array := new Object_Array (1..16);
	    begin
	       T(1) := new Universe_Class.Universe_Class;
	       T(2) := new Profile_Class.Profile_Class;
	       T(3) := new Machine_Class.Machine_Class;
	       T(4) := new Component_Class.Component_Class;
	       T(5) := new Job_Class.Job_Class;
	       T(6) := new House_Class.House_Class;
	       T(7) := new Content_Class.Content_Class;
	       T(8) := new Contact_Class.Contact_Class;
	       T(9) := new Account_Class.Account_Class;
	       T(10) := new Activity_Class.Activity_Class;
	       T(11) := new Account_Line_Class.Account_Line_Class;
	       T(12) := new Compta_Line_Class.Compta_Line_Class;
	       T(13) := new Event_Class.Event_Class;
	       T(14) := new Planning_Class.Planning_Class;
	       T(15) := Copy(O);
	       T(16) := new Note_Class.Note_Class;
	       return T.all;
	    end;
      end case;
      
      
      
      
      

      
      
      
      
   end Successor;
   
   function Copy (Object : Object_Access) return Object_Access is
      Target : Object_Access;
   begin
      --if Object /= null then
	 case Object.Class_Name is
	    when Classes.Universe =>
	       Target := new Universe_Class.Universe_Class ' (Universe_Class.Universe_Class(Object.all));
	    when Classes.Profile =>
	       Target := new Profile_Class.Profile_Class ' (Profile_Class.Profile_Class(Object.all));
	    when Classes.Planning =>
	       Target := new Planning_Class.Planning_Class ' (Planning_Class.Planning_Class(Object.all));
	    when Classes.Job =>
	       Target := new Job_Class.Job_Class ' (Job_Class.Job_Class(Object.all));		  
	    when Classes.Event =>
	       Target := new Event_Class.Event_Class ' (Event_Class.Event_Class(Object.all));
	    when Classes.Machine =>
	       Target := new Machine_Class.Machine_Class ' (Machine_Class.Machine_Class(Object.all));
	    when Classes.Account =>
	       target := new Account_Class.Account_Class ' (Account_Class.Account_Class(Object.all));
	    when Classes.Account_Line =>
	       Target := new Account_Line_Class.Account_Line_Class ' (Account_Line_Class.Account_Line_Class(Object.all));
	    when Classes.Activity =>
	       Target := new Activity_Class.Activity_Class ' (Activity_Class.Activity_Class(Object.all));
	    when Classes.Compta_Line =>
	       Target := new Compta_Line_Class.Compta_Line_Class ' (Compta_Line_Class.Compta_Line_Class(Object.all));
	    when Classes.Note =>
	       target := new Note_Class.Note_Class ' (Note_Class.Note_Class(Object.all));
	    when Classes.Component =>
	       Target := new Component_Class.Component_Class ' (Component_Class.Component_Class(Object.all));
	    when Classes.Contact =>
	       target := new Contact_Class.Contact_Class ' (Contact_Class.Contact_Class(Object.all));
	    when Classes.Content =>
	       Target := new Content_Class.Content_Class ' (Content_Class.Content_Class(Object.all));
	    when Classes.House =>
	       target := new House_Class.House_Class ' (House_Class.House_Class(Object.all));
	    when Classes.Car =>
	       Target := new Car_Class.Car_Class ' (Car_Class.Car_Class(Object.all));
	 end case;
      --else
--	 return new Universe_Class.Universe_Class;
 --     end if;
      return Target;
   end Copy;
   
   use Abstracted_Vectors;
   function "=" (Left, Right : Object_Class'class) return Boolean is
   begin
      if (Left.Class_Name = Right.Class_Name) then
      	 case Left.Class_Name is
	    
      	    when Universe =>
      	       if Left.Universe.X = Right.Universe.X and then
		 Left.Universe.Y = Right.Universe.Y and then
		 Left.Universe.Z = Right.Universe.Z then
      		  return True;
      	       end if;
      	    when Profile =>
      	       if Left.Profile = Right.Profile then
      		  return True;
      	       end if;

      	    when Planning =>
      	       if Left.Planning = Right.Planning then
      		  return True;
      	       end if;

      	    when Job =>
      	       if Left.Job = Right.Job then
      		  return True;
      	       end if;

      	    when Event =>
      	       
	       return True;
      	       

      	    when Machine =>
      	       if Left.Machine = Right.Machine then
      		  return True;
      	       end if;

      	    when Account =>
      	       if Left.Account = Right.Account then
      		  return True;
      	       end if;

      	    when Account_Line =>
      	       if Left.Account_Line = Right.Account_Line then
      		  return True;
      	       end if;

      	    when Activity =>
      	       if Left.Activity = Right.Activity then
      		  return True;
      	       end if;

      	    when Compta_Line =>
      	       if Left.Compta_Line = Right.Compta_Line then
      		  return True;
      	       end if;

      	    when Note =>
      	       if Left.Note = Right.note then
      		  return True;
      	       end if;

      	    when Component =>
      	       if Left.Component = Right.Component then
      		  return True;
      	       end if;

      	    when Contact =>
      	       if Left.Contact = Right.Contact then
      		  return True;
      	       end if;

      	    when Content =>
      	       if Left.Content.Price = Right.Content.Price then
      		  return True;
      	       end if;

      	    when House =>
      	       if Left.House = Right.House then
      		  return True;
      	       end if;

      	    when Car =>
      	       if Left.Car = Right.Car then
      		  return True;
      	       end if;

	    
      	 end case;
      
      end if;
      return False;
   end "=";
   function "<" (Left, Right : Object_Class'class) return Boolean is
   begin
      return Fit (Left) < Fit(Right);
   end "<";
   
   function Uniform (O : in Object_Class'class) return Float is
   begin
      return -0.1;
   end Uniform;
   
   function Heuristic (O : in Object_Class'class) return Float is
   begin
      return 1.0;
   end Heuristic;
         
end Work.Classes.Main ; 
