-- Skywalker is another attempt of A. i. written with Ada.
-- Skywalker is Copyright (C) 2024 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 := "2024-11-12 09:45:23"
-- Version := "0.0.8r"

-- Code page of this file : Windows west Europe
-- Tabulation : 3
-- Contact : les-ziboux@rasama.org

with Sky.ANSI.Console;
use Sky.ANSI.Console;
generic

   Term_Lines_Max : Positive := 24;
   Term_Columns_Max : Positive := 80;

package Sky.Ansi.Windows is
   -- Les procédures ce programme d'exemple supposent un mode d'écran de
   -- 25 lignes sur Term_Columns_Max colonnes (c'est le mode d'écran standard, mais
   -- mais il est tout de même fixé par la procédure d'initialisation).

   subtype Line_Type   is Natural range 1..Term_Lines_Max;
   subtype Column_Type is Natural range 1..Term_Columns_Max;
   subtype Height_Type is Natural range 0..Term_Lines_Max;
   subtype Width_Type  is Natural range 0..Term_Columns_Max;

   -- On défini un type fenêtre très basique, qui correspond simplement
   -- au spécification d'un rectangle. Les fenêtre sont un cadre, avec
   -- une pseudo case ferme en haut à droite. La manière de dessiner le cadre
   -- d'une fenêtre impose des restriction sur leurs dimensions possibles. La
   -- largeur d'une fenêtre est de 5 au minimum, et la hauteur minimum est 2.

   subtype Window_Line_Type   is Line_Type;
   subtype Window_Column_Type is Column_Type;
   subtype Window_Height_Type is Height_Type range 2..Term_Lines_Max;
   subtype Window_Width_Type  is Width_Type  range 5..Term_Columns_Max;

   -- La zone cliente d'une fenêtre, la zone qui est à l'intérieur, à
   -- des dimensions bien sûre inférieur à celle de la fenêtre elle-même.
   -- La largeur de la zone cliente fait 2 de moins que la largeur de la
   -- fenêtre, idem pour la hauteur.

   subtype Client_Line_Type   is Window_Line_Type   range 1..Term_Lines_Max - 2;
   subtype Client_Column_Type is Window_Column_Type range 1..Term_Columns_Max - 2;
   subtype Client_Height_Type is Height_Type range 0..Term_Lines_Max - 2;
   subtype Client_Width_Type  is Width_Type  range 0..Term_Columns_Max - 2;

   -- On défini maintenant un type fenêtre.
   -- En plus de ces coordonnées et dimensions, une fenêtre spécifie la
   -- couleur du cadre, et la couleur de la case ferme. On pourra
   -- également spécifier le type de cadre.

   type Frame_Type_Enum is (Single_Line_Frame, Double_Line_Frame);

   type Window_Type is
      record
	 L : Window_Line_Type;
	 C : Window_Column_Type;
	 H : Window_Height_Type;
	 W : Window_Width_Type;
	 Frame_Type      : Frame_Type_Enum;
	 Frame_Color     : Color_Type;
	 Close_Box_Color : Color_Type;
      end record; -- Window_Type

   -- Un type zone cliente n'a pas besoin de coordonné, car elle sont
   -- toujours (1,1). Il n'y aura donc que des dimensions.

   type Client_Type is
      record
	 H : Client_Height_Type;
	 W : Client_Width_Type;
      end record; -- Window_Type

   Metric_Error : exception; -- Positionnement ou dimensionnement incorrect.
   
   function Real_Length (Line : in Wide_String) return Natural;
   -- Just to count escape colored Chars and tabulations.
   
   
   procedure Initialize;         
   
   procedure Clear_Screen;
   
   procedure Leave_And_Restore_Defaults;
   
   
   -- Dessine un fond d'espace de travail. Le rectangle défini par
   -- les coordonnées et les dimensions, est rempli avec un caractère
   -- spécial.   
   procedure Draw_Desktop_Background (
				      L      : in Line_Type;
				      C      : in Column_Type;
				      H      : in Height_Type;
				      W      : in Width_Type;
				      Color  : in Color_Type);  
   
   -- Dessine un fenêtre, c'est-à-dire un cadre, un fond rempli d'espace,
   -- et un bouton « ferme » en haut à droite du cadre.
   procedure Draw_Window (W : in Window_Type);
   
   
   -- Dessine un fenêtre highlight, c'est-à-dire un cadre, un fond rempli d'espace,
   -- et un bouton « ferme » en haut à droite du cadre.
   procedure Enlight_Window (W : in Window_Type);
   
   
   -- Dessine un caractère dans la zone cliente d'une fenêtre, aux coordonnées
   -- spécifiées avec la couleur indiquée.
   procedure Draw (
		   W      : in Window_Type;
		   L      : in Client_Line_Type;
		   C      : in Client_Column_Type;
		   Color  : in Color_Type;
		   Ch     : in Wide_Character);
   
   -- Dessine du texte dans la zone cliente d'une fenêtre, aux coordonnées
   -- spécifiées avec la couleur indiquée.
   procedure Draw (
		   W      : in Window_Type;
		   L      : in Client_Line_Type;
		   C      : in Client_Column_Type;
		   Color  : in Color_Type;
		   Text   : in Wide_String);
   
   -- Enlighted text
   procedure Enlight_Draw (
		   W      : in Window_Type;
		   L      : in Client_Line_Type;
		   C      : in Client_Column_Type;
		   Color  : in Color_Type;
		   Text   : in Wide_String);
   
   
   -- Dessine du texte centré. Comme c'est le centrage qui donne la coordonnée
   -- horizontal, on ne spécifie bien sûre que la coordonnée vertical.
   procedure Draw_Centered (
			    W      : in Window_Type;
			    L      : in Client_Line_Type;
			    Color  : in Color_Type;
			    Text   : in Wide_String);
   
   procedure Move_Cursor_To (
			     W : in Window_Type;
			     L : in Client_Line_Type;
			     C : in Client_Column_Type);
   
   function Is_Printable (C : in Wide_Character)
			 return Boolean;
   
   
   function Fit_In_Screen (
			   L : in Line_Type;
			   C : in Column_Type;
			   H : in Height_Type;
			   W : in Width_Type)
			  return Boolean;
   
   function Fit_In_Window (
			   Window : in Window_Type;
			   L : in Line_Type;
			   C : in Column_Type;
			   H : in Height_Type;
			   W : in Width_Type)
			  return Boolean;
   
   function Fit_In_Client (
			   Window : in Window_Type;
			   L : in Line_Type;
			   C : in Column_Type;
			   H : in Height_Type;
			   W : in Width_Type)
			  return Boolean;
   
   subtype Key_Title_Type is String (1..9);
   
   Key_Title : constant array (Key_Type) of Key_Title_Type := 
     (Key_F1                => "F1       ",
      Key_F2                => "F2       ",
      Key_F3                => "F3       ",
      Key_F4                => "F4       ",
      Key_F5                => "F5       ",
      Key_F6                => "F6       ",
      Key_F7                => "F7       ",
      Key_F8                => "F8       ",
      Key_F9                => "F9       ",
      Key_F10               => "F10      ",
      Key_F11               => "F11      ",
      Key_F12               => "F12      ",
      Keypad_Home           => "KP-Home  ",
      Keypad_Up_Arrow       => "KP-Up    ",
      Keypad_Page_Up        => "KP-PgUp  ",
      Keypad_Left_Arrow     => "KP-Left  ",
      Keypad_Right_Arrow    => "KP-Right ",
      Keypad_End            => "KP-End   ",
      Keypad_Down_Arrow     => "KP-Down  ",
      Keypad_Page_Down      => "KP-PgDn  ",
      Keypad_Insert         => "KP-Insert",
      Keypad_Delete         => "KP-Delete",
      Key_Home              => "Home     ",
      Key_Up_Arrow          => "Up       ",
      Key_Page_Up           => "Page-Up  ",
      Key_Left_Arrow        => "Left     ",
      Key_Right_Arrow       => "Right    ",
      Key_End               => "End      ",
      Key_Down_Arrow        => "Down     ",
      Key_Page_Down         => "Page-Down",
      Key_Insert            => "Insert   ",
      Key_Delete            => "Delete   ",
      Key_Print_Screen      => "PrnScreen",
      Key_Pause_Break       => "Pause    ",
      Key_Escape            => "Escape   ",
      Key_Backspace         => "Backspace",
      Key_Enter             => "Enter    ",
      Key_Tab               => "Tab      ",
      Key_Null              => "Null     ",
      Key_A                 => "<A>      ",
      Key_B                 => "<B>      ",
      Key_C                 => "<C>      ",
      Key_D                 => "<D>      ",
      Key_E                 => "<E>      ",
      Key_F                 => "<F>      ",
      Key_G                 => "<G>      ",
      Key_H                 => "<H>      ",
      Key_I                 => "<I>      ",
      Key_J                 => "<J>      ",
      Key_K                 => "<K>      ",
      Key_L                 => "<L>      ",
      Key_M                 => "<M>      ",
      Key_N                 => "<N>      ",
      Key_O                 => "<O>      ",
      Key_P                 => "<P>      ",
      Key_Q                 => "<Q>      ",
      Key_R                 => "<R>      ",
      Key_S                 => "<S>      ",
      Key_T                 => "<T>      ",
      Key_U                 => "<U>      ",
      Key_V                 => "<V>      ",
      Key_W                 => "<W>      ",
      Key_X                 => "<X>      ",
      Key_Y                 => "<Y>      ",
      Key_Z                 => "<Z>      ",
      Key_0                 => "<0>      ",
      Key_1                 => "<1>      ",
      Key_2                 => "<2>      ",
      Key_3                 => "<3>      ",
      Key_4                 => "<4>      ",
      Key_5                 => "<5>      ",
      Key_6                 => "<6>      ",
      Key_7                 => "<7>      ",
      Key_8                 => "<8>      ",
      Key_9                 => "<9>      ",
      Key_Minus             => "<->      ",
      Key_Equal             => "<=>      ",
      Key_Left_Square       => "<[>      ",
      Key_Right_Square      => "<]>      ",
      Key_Space             => "< >      ",
      Key_Semicolon         => "<;>      ",
      Key_Single_Quote      => "<'>      ",
      Key_Comma             => "<,>      ",
      Key_Dot               => "<.>      ",
      Key_Slash             => "</>      ",
      Key_Left_Single_Quote => "<`>      ",
      Keypad_Enter          => "KP-< >   ",
      Keypad_Slash          => "KP-</>   ",
      Keypad_Star           => "KP-<*>   ",
      Keypad_Minus          => "KP-<->   ",
      Keypad_Plus           => "KP-<+>   ",
      Keypad_Middle         => "KP-Middle");
   
   subtype Modifier_Key_Title_Type is String (1..5);
   
   Modifier_Key_Title : constant array (Modifier_Key_Type) of
     Modifier_Key_Title_Type := (
				 No_Modifier_Key  => "     ",
				 Alt_Key          => "  Alt",
				 Ctrl_Key         => " Ctrl",
				 Shift_Key        => "Shift");
   
   Draw_Buffer : Wide_String (Column_Type);

end Sky.Ansi.Windows ;