---------------------------------------------------------------
--                                                           
--  RAPID - Rapid Ada Portable Interface Designer
--                                                           
--  GUI-WIDGET-TEXT.ADB
--  Description : GUI Widget Text box
--                       
--  By: Martin Carlisle 
--                                         
-- RAPID is free software; you can redistribute it and/or 
-- modify it without restriction.  However, we ask that you
-- please retain the original author information, and clearly  
-- indicate if it has been modified.
--
-- RAPID 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.  
--
---------------------------------------------------------------
with Gui_Enum;
with File_Helpers;
with TextEntry_Dialog_Window;
with Mcc.Common_Dialogs;
with Generate_Helpers;
with Mcc.Gui.Widget;
use type Mcc.Gui.Widget.Widget_Pointer;
with Mcc.Text_Entry_Types;
with State;

package body Gui.Widget.Text is
   -- reads information from file into Text_Entry,
   -- assumes keyword already read.
   procedure Read_Widget(Widget : in out Text_Entry;
         File : in Ada.Text_IO.File_Type) is
      package base_type_io is new ada.text_io.enumeration_io(
         mcc.text_entry_types.base_type);
      Word : Word_Type;
      Last : Natural;
   begin -- Read_Widget
      Read_Widget(GUI_Widget(Widget),File);
      File_Helpers.Get_String(File,Word,Last);
      Widget.Data_Item  := new String'(Word(1..Last));
      File_Helpers.Get_String(File,Word,Last);
      Widget.Data_Type := new String'(Word(1..Last));
      -- test for EOL for backward compatibility
      if not Ada.Text_IO.End_Of_Line(File) then
         Base_Type_IO.Get(File,Widget.Base_Type); 
      end if;      
   end Read_Widget;

   -- Writes information to file from Text_Entry
   procedure Write_Widget(Widget : in Text_Entry;
         File : in Ada.Text_IO.File_Type) is

   begin -- Write_Widget
      Gui_Enum.IO.Put(File,Gui_Enum.TextEntry);
      Ada.Text_IO.Put(File," ");
      Write_Widget(GUI_Widget(Widget),File);
      Ada.Text_Io.Put(File," """);
      if Widget.Data_Item /= null then
         File_Helpers.Put_String(File,Widget.Data_Item.All);
      end if;
      Ada.Text_Io.Put(File,""" """);
      if Widget.Data_Type /= null then
         File_Helpers.Put_String(File,Widget.Data_Type.All);
      end if;
      Ada.Text_IO.Put(File,""" " & Mcc.Text_Entry_Types.Base_Type'Image(
         Widget.Base_Type));
      Ada.Text_IO.New_Line(File);
   end Write_Widget;

   -- wbw 6/6/99
   procedure Generate_Widget_Context_Clause(Widget : in Text_Entry;
      File : in Ada.Text_IO.File_Type) is
   begin
      Ada.Text_IO.Put_Line(File => File,
         Item => "with Mcc.Gui.Widget.Text_Entry;");
   end Generate_Widget_Context_Clause;

   -- wbw 6/6/99
   procedure Generate_Widget_Declaration(Widget : in Text_Entry;
      File : in Ada.Text_IO.File_Type) is
   begin
      Ada.Text_IO.Put_Line(File => File,
         Item => "   " & Widget.Name.all &
                 " : aliased Mcc.Gui.Widget.Text_Entry.Text_Entry;");
   end Generate_Widget_Declaration;

   -- wbw 5/10/99      
   procedure Generate_Widget_Creation(Widget : in Text_Entry;
      File        : in Ada.Text_IO.File_Type;
      Window_Name : in String) is
   begin
      Ada.Text_IO.Put_Line(File => File,
         Item => "      Mcc.Gui.Widget.Text_Entry.Create(");
      Ada.Text_IO.Put_Line(File => File,
         Item => "         Obj    => " & Widget.Name.all & ",");
      Ada.Text_IO.Put_Line(File => File,
         Item => "         Parent => " & Window_Name & ",");
      Ada.Text_IO.Put_Line(File => File,
         Item => "         X      =>" & Integer'Image(Widget.X) & ",");
      Ada.Text_IO.Put_Line(File => File,
         Item => "         Y      =>" & Integer'Image(Widget.Y) & ",");
      Ada.Text_IO.Put_Line(File => File,
         Item => "         Width  =>" & Integer'Image(Widget.Width) & ",");
      Ada.Text_IO.Put_Line(File => File,
         Item => "         Height =>" & Integer'Image(Widget.Height) & ");");           
   end Generate_Widget_Creation;


   -- display the widget to a window
   procedure Display_Widget(Widget : in out Text_Entry;
      Container : in out Mcc.Gui.Container.Container'Class) is
   begin
      if Widget.The_Widget = null then
         Widget.The_Widget := new 
            Mcc.Gui.Widget.Text_Entry.Text_Entry;
      end if;

      Mcc.Gui.Widget.Text_Entry.Create(
         Obj    => Mcc.Gui.Widget.Text_Entry.Text_Entry(
            Widget.The_Widget.all),
         Parent => Container,
         X      => Widget.X,
         Y      => Widget.Y,
         Width  => Widget.Width,
         Height => Widget.Height);
      Display_Widget(Gui_Widget(Widget),Container);
   exception when others =>
      Mcc.Common_Dialogs.OK_Box("Can't display: " &
         Widget.Name.all);
   end Display_Widget;

   procedure Set_Properties(Widget : in out Text_Entry) is
   begin
      -- fill in by copying to global
      Mcc.Text_Entry_Types.Temporary := Widget.Base_Type;
      
      TextEntry_Dialog_Window.Generate_and_Fill_Window;
      
      -- where are the entries?
      Widget.Properties    := 
         Textentry_Dialog_Window.Textentry_Dialog_Window'access;
      Widget.Name_Entry    := TextEntry_Dialog_Window.Entry1'access;
      Widget.X_Entry       := TextEntry_Dialog_Window.Entry2'access;
      Widget.Y_Entry       := TextEntry_Dialog_Window.Entry3'access;
      Widget.Width_Entry   := TextEntry_Dialog_Window.Entry4'access;
      Widget.Height_Entry  := TextEntry_Dialog_Window.Entry5'access;
      Widget.Data_Item_Entry := TextEntry_Dialog_Window.Entry6'access;
      Widget.Base_Type_Dropdown := TextEntry_Dialog_Window.Base_Dropdown'access;
      Widget.Data_Type_Entry := TextEntry_Dialog_Window.Entry7'access;
      Set_Properties(Gui_Widget(Widget));

      if State.Get_Current_Window.Novice_Mode then
         Mcc.Gui.Widget.Text_Entry.Set_Text(
            Obj  => Widget.Data_Item_Entry.all,
            Text => "disabled for novice");
         Mcc.Gui.Widget.Text_Entry.Disable(Widget.Data_Item_Entry.All);
         Mcc.Gui.Widget.Text_Entry.Set_Text(
            Obj  => Widget.Data_Type_Entry.all,
            Text => "disabled for novice");
         Mcc.Gui.Widget.Text_Entry.Disable(Widget.Data_Type_Entry.All);
      else
         if Widget.Data_Item /= null then
            Mcc.Gui.Widget.Text_Entry.Set_Text(
               Obj  => Widget.Data_Item_Entry.all,
               Text => Widget.Data_Item.all);
         end if;

         if Widget.Data_Type /= null then
            Mcc.Gui.Widget.Text_Entry.Set_Text(
               Obj  => Widget.Data_Type_Entry.all,
               Text => Widget.Data_Type.all);
         end if;
      end if;
   end Set_Properties;

   procedure Apply_Properties(Widget : in out Text_Entry) is
      Ok : Boolean;
   begin
      Apply_Properties(Gui_Widget(Widget));
      declare
         Data_Item : String := Mcc.Gui.Widget.Text_Entry.Get_Text(
            Widget.Data_Item_Entry.all);
      begin
         if Data_Item /= "disabled for novice" then
            Widget.Data_Item := new String'(Data_Item);
         end if;
      end;
      declare
         Data_Type : String := Mcc.Gui.Widget.Text_Entry.Get_Text(
            Widget.Data_Type_Entry.all);
      begin
         if Data_Type /= "disabled for novice" then
            Widget.Data_Type := new String'(Data_Type);
         end if;
      end;

      -- copy out of global into record      
      Textentry_Dialog_Window.Read_Window(
         Success         => Ok,
         Highlight_Error => False,
         Beep_On_Error   => False);
      Widget.Base_Type := Mcc.Text_Entry_Types.Temporary;
   end Apply_Properties;

   procedure Check_Properties(Widget : in out Text_Entry;
      Ok : out Boolean) is
   begin
      Check_Properties(GUI_Widget(Widget),Ok);

      if Ok then
         Textentry_Dialog_Window.Read_Window(
            Success         => Ok,
            Highlight_Error => True,
            Beep_On_Error   => True);
      else
         Mcc.Gui.Bell;
      end if;
   end Check_Properties;

   procedure Generate_Action_Context_Clause(Widget : in Text_Entry;
      File : in Ada.Text_IO.File_Type) is
      use type Mcc.Text_Entry_Types.Base_Type;
   begin
      if Widget.Data_Item /= null and then
         Widget.Data_Item.all /= "" then
         Generate_Helpers.Generate_With(File,Widget.Data_Item.all);
      end if;
      if Widget.Data_Type /= null and then
         Widget.Data_Type.all /= "" then
         Generate_Helpers.Generate_With(File,Widget.Data_Type.all);
      end if;
      if Widget.Base_Type in Mcc.Text_Entry_Types.Float_Types then
         Ada.Text_IO.Put_Line(File => File,
            Item => "with Mcc.Text_Entry_Types;");
      elsif Widget.Base_Type = Mcc.Text_Entry_Types.Unbounded_String and then
         Widget.Data_Item /= null and then
         Widget.Data_Item.all /= "" then
         Ada.Text_IO.Put_Line(File => File,
            Item => "with Ada.Strings.Unbounded;");
      end if;
   end Generate_Action_Context_Clause;
      
   procedure Generate_Fill_Action(Widget : in Text_Entry;
      File        : in Ada.Text_IO.File_Type) is
   begin
      -- don't bother if there's no data item
      if Widget.Data_Item = null or else
         Widget.Data_Item.all = "" then
         return;
      end if;
      
      case Widget.Base_Type is
         when Mcc.Text_Entry_Types.Unbounded_String =>
            Ada.Text_IO.Put_Line(File => File,
               Item => "      Mcc.Gui.Widget.Text_Entry.Set_Text(");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         Obj      => " & Widget.Name.all & ",");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         Text   => Ada.Strings.Unbounded.To_String(" & 
                  Widget.Data_Item.all & "));");
         when Mcc.Text_Entry_Types.Integer =>
            Ada.Text_IO.Put_Line(File => File,
               Item => "      Mcc.Gui.Widget.Text_Entry.Set_Text(");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         Obj      => " & Widget.Name.all & ",");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         Text   => Integer(" & 
                  Widget.Data_Item.all & "));");
         when Mcc.Text_Entry_Types.Float_1|
              Mcc.Text_Entry_Types.Float_2|
              Mcc.Text_Entry_Types.Float_3|
              Mcc.Text_Entry_Types.Float_E =>
            Ada.Text_IO.Put_Line(File => File,
               Item => "      Mcc.Gui.Widget.Text_Entry.Set_Text(");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         Obj      => " & Widget.Name.all & ",");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         Text   => " & 
                  "Mcc.Text_Entry_Types.Image(Float(" &
                  Widget.Data_Item.all & "), Mcc.Text_Entry_Types." &
                  Mcc.Text_Entry_Types.Base_Type'Image(
                     Widget.Base_Type) & "));");
         when Mcc.Text_Entry_Types.Enumeration =>
            if Widget.Data_Type /= null and then
               Widget.Data_Type.all /= "" then
               Ada.Text_IO.Put_Line(File => File,
                  Item => "      Mcc.Gui.Widget.Text_Entry.Set_Text(");
               Ada.Text_IO.Put_Line(File => File,
                  Item => "         Obj      => " & Widget.Name.all & ",");
               Ada.Text_IO.Put_Line(File => File,
                  Item => "         Text   => " & 
                     Widget.Data_Type.all & "'Image(" &
                     Widget.Data_Item.all & "));");
            end if;
      end case;
   end Generate_Fill_Action;

   procedure Generate_Read_Action(Widget : in Text_Entry;
      File        : in Ada.Text_IO.File_Type) is
      procedure Print_Declare_Block is
      begin
         Ada.Text_IO.Put_Line(File => File,
            Item => "      declare");
         Ada.Text_IO.Put_Line(File => File,
            Item => "         X : String := " &
               "Mcc.Gui.Widget.Text_Entry.Get_Text(");
         Ada.Text_IO.Put_Line(File => File,
            Item => "            Obj => " & Widget.Name.all & ");");
         Ada.Text_IO.Put_Line(File => File,
            Item => "      begin");
      end Print_Declare_Block;
      
      procedure Print_Exception_Block is
      begin
         Ada.Text_IO.Put_Line(File => File,
            Item => "      exception when Constraint_Error =>");
         Ada.Text_IO.Put_Line(File => File,
            Item => "         if Highlight_Error then");
         Ada.Text_IO.Put_Line(File => File,
            Item => "            Mcc.Gui.Widget.Text_Entry.Highlight(" &
               Widget.Name.all & ");");
         Ada.Text_IO.Put_Line(File => File,
            Item => "         end if;");
         Ada.Text_IO.Put_Line(File => File,
            Item => "         raise;");
         Ada.Text_IO.Put_Line(File => File,
            Item => "      end;");
      end Print_Exception_Block;
   begin
      -- don't bother if there's no data item
      if Widget.Data_Item = null or else
         Widget.Data_Item.all = "" then
         return;
      end if;
      
      case Widget.Base_Type is
         when Mcc.Text_Entry_Types.Unbounded_String =>
            Print_Declare_Block;
            Ada.Text_IO.Put_Line(File => File,
               Item => "         " & Widget.Data_Item.all & " := " &
                  "Ada.Strings.Unbounded.To_Unbounded_String(X);");
            Ada.Text_IO.Put_Line(File => File,
               Item => "      end;");
         when Mcc.Text_Entry_Types.Integer =>
            Ada.Text_IO.Put_Line(File => File,
               Item => "      declare");
            Ada.Text_IO.Put_Line(File => File,
               Item => "         X : Integer := " &
                  "Mcc.Gui.Widget.Text_Entry.Get_Text(");
            Ada.Text_IO.Put_Line(File => File,
               Item => "            Obj => " & Widget.Name.all & ");");
            Ada.Text_IO.Put_Line(File => File,
               Item => "      begin");
            Ada.Text_IO.Put(File => File,
               Item => "         " & Widget.Data_Item.all & " := ");
            -- only add a cast if we need to
            if Widget.Data_Type /= null and then
               Widget.Data_Type.all /= "" then
               Ada.Text_IO.Put_Line(File => File, Item =>
                  Widget.Data_Type.all & "(X);");
            else
               Ada.Text_IO.Put_Line(File => File, 
                  Item => "X;");
            end if;
            Print_Exception_Block;
         when Mcc.Text_Entry_Types.Float_1|
              Mcc.Text_Entry_Types.Float_2|
              Mcc.Text_Entry_Types.Float_3|
              Mcc.Text_Entry_Types.Float_E =>
            Print_Declare_Block;
            Ada.Text_IO.Put(File => File,
               Item => "         " & Widget.Data_Item.all & " := ");
            -- if data type is blank, use standard.float
            if Widget.Data_Type /= null and then
               Widget.Data_Type.all /= "" then
               Ada.Text_IO.Put_Line(File => File, Item =>
                  Widget.Data_Type.all & "'Value(X);");
            else
               Ada.Text_IO.Put_Line(File => File, 
                  Item => "Float'Value(X);");
            end if;
            Print_Exception_Block;
         when Mcc.Text_Entry_Types.Enumeration =>
            if Widget.Data_Type /= null and then
               Widget.Data_Type.all /= "" then
               Print_Declare_Block;
               Ada.Text_IO.Put(File => File,
                  Item => "         " & Widget.Data_Item.all & " := ");
               Ada.Text_IO.Put_Line(File => File, Item =>
                  Widget.Data_Type.all & "'Value(X);");
               Print_Exception_Block;
            end if;
      end case;
   end Generate_Read_Action;


end Gui.Widget.Text;