-- This program is the last attempt of artificial intelligency with Ada.
-- Elhoim is Copyright (C) 2023 Manuel ; 
--
--   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-05-19 23:32:47"
-- Version := "0.3.5b"
with Text_Io;
use Text_Io;
with Ada.Unchecked_Deallocation;
with Ada.Numerics.Discrete_Random;
use Ada.Numerics;
with Ada.Strings.Fixed;
use Ada.Strings.Fixed;
with Ada.Command_Line;
use Ada.Command_Line;

package body Lib.Naming is
   
   
   
   type String_Access is access all String;
   
   procedure String_Free is new Ada.Unchecked_Deallocation(String, String_Access);
   
   Ada_Space : constant Character := '_';
   
   Voyelles : constant String := "aeiouy";
   Consonnes : constant String := "bcdfghjklmnpqrstvwxz";
   
   type Voyelle_Enum is ('a', 'e', 'i', 'o', 'u', 'y');
   type Consonne_Enum is ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z');
   
   package Voyelles_Rand is new Discrete_Random (Voyelle_Enum);
   package Consonnes_Rand is new Discrete_Random (Consonne_Enum);
   
   subtype Voyelle_Range is Natural range 0..6;
   subtype Consonne_Range is Natural range 0..20;
   
   package Bool_Rand is new Discrete_Random(Boolean);
   
   Voyelle_Gen : Voyelles_Rand.Generator;
   Consonne_Gen : Consonnes_Rand.Generator;
   
   generic
      Nb_Of_Char : Positive;      
   package Word_Rand is 
      subtype Word_Type is String(1..Nb_Of_Char);
      subtype Word_Range is Positive range 1..Nb_Of_Char;
      package Pos_Rand is new Discrete_Random (Word_Range);
      
      Pos_Gen : Pos_Rand.Generator;
      function Word_Random return String;
   end Word_Rand;
   package body Word_Rand is 
      function Word_Random return String is
	 Bool_Gen : Bool_Rand.Generator;
	 Word : Word_Type := (others => ' ');
      begin
	 Pos_Rand.Reset(Pos_Gen);
	 while Index (Word, " ") /= 0 loop
	    if Bool_Rand.Random(Bool_Gen) then
	       Consonnes_Rand.Reset(Consonne_Gen);
	    end if;
	    if Bool_Rand.Random(Bool_Gen) then
	       Voyelles_Rand.Reset(Voyelle_Gen);
	    end if;
	    
	    if Bool_Rand.Random(Bool_Gen) then
	       Word(Pos_Rand.Random(Pos_Gen)) := Character'value(Voyelle_Enum'Image(Voyelles_Rand.Random(Voyelle_Gen)));
	    else
	       Word(Pos_Rand.Random(Pos_Gen)) := Character'Value(Consonne_Enum'Image(Consonnes_Rand.Random(Consonne_Gen)));
	    end if;
	 end loop;
	 return Word;
      end Word_Random;
   end Word_Rand;
   
   
   function Main (Nb_Of_Char : in Positive) return String is
      
      String_Ptr : String_Access := new String ' ("");
      String_Buf : String_Access;
   begin
   
      for I in 1..1 loop
	 declare
	    package words is new Word_Rand (Nb_Of_Char);
	 begin
	    String_Buf := new String ' (String_Ptr.all & Words.Word_Random);
	    String_Free(String_Ptr);
	    String_Ptr := new String ' (String_Buf.all & Ada_space);
	    String_Free(String_Buf);
	 end;
      end loop;
      return String_Ptr(1..String_Ptr'Length-1);
   end Main;

   
   procedure Name (Num_Char : in Word_Range; Word : out String) is
   begin
      Move(Main(Num_char), Word);
   end Name;
   
   function Name (Num_Char : in Word_Range) return String is
      
      Word : String(1..Num_Char);
      
   begin
      Move(Main(Word'Length), Word);
      return Word;
   end Name;
      
      
      
end Lib.Naming ;