------------------------------------------------------------------------------
--                                  G P S                                   --
--                                                                          --
--                     Copyright (C) 2002-2016, AdaCore                     --
--                                                                          --
-- This is free software;  you can redistribute it  and/or modify it  under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  This software is distributed in the hope  that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY 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  distributed  with  this  software;   see  file --
-- COPYING3.  If not, go to http://www.gnu.org/licenses for a complete copy --
-- of the license.                                                          --
------------------------------------------------------------------------------

with GNAT.OS_Lib;                      use GNAT.OS_Lib;

with Gtk.Box;                          use Gtk.Box;
with Gtk.Combo_Box_Text;               use Gtk.Combo_Box_Text;
with Gtk.Enums;                        use Gtk.Enums;
with Gtk.Frame;                        use Gtk.Frame;
with Gtk.GEntry;                       use Gtk.GEntry;
with Gtk.Label;                        use Gtk.Label;
with Gtk.Size_Group;                   use Gtk.Size_Group;
with Gtk.Widget;                       use Gtk.Widget;

with GPS.Intl;                         use GPS.Intl;
with GPS.Kernel.Project;               use GPS.Kernel.Project;

with Naming_Exceptions;                use Naming_Exceptions;

package body Foreign_Naming_Editors is

   ---------------------------
   -- Naming_Editor_Factory --
   ---------------------------

   function Naming_Editor_Factory
     (Kernel : not null access Kernel_Handle_Record'Class;
      Lang   : String) return not null access Project_Editor_Page_Record'Class
   is
      pragma Unreferenced (Kernel);
      Result : Foreign_Naming_Editor;
   begin
      Result := new Foreign_Naming_Editor_Record;
      Result.Language := new String'(Lang);
      return Result;
   end Naming_Editor_Factory;

   ----------------
   -- Initialize --
   ----------------

   overriding procedure Initialize
     (Self         : not null access Foreign_Naming_Editor_Record;
      Kernel       : not null access Kernel_Handle_Record'Class;
      Read_Only    : Boolean;
      Project      : Project_Type := No_Project)
   is
      Display_Exceptions : constant Boolean := True;
      P : Project_Type := Project;
      Frame     : Gtk_Frame;
      Box, Vbox : Gtk_Box;
      Label     : Gtk_Label;
      Group     : Gtk_Size_Group;
   begin
      Initialize_Vbox (Self, Homogeneous => False);

      Gtk_New (Group);

      Gtk_New (Frame, -"Details");
      Self.Pack_Start (Frame, Expand => False);

      Gtk_New_Vbox (Vbox, Homogeneous => True);
      Frame.Add (Vbox);

      Gtk_New_Hbox (Box, Homogeneous => False);
      Vbox.Pack_Start (Box, Expand => False);

      Gtk_New (Label, -"Header files:");
      Label.Set_Alignment (0.0, 0.5);
      Group.Add_Widget (Label);
      Box.Pack_Start (Label);

      Gtk_New_With_Entry (Self.Spec_Ext);
      Self.Spec_Ext.Set_Sensitive (not Read_Only);
      Self.Spec_Ext.Set_Entry_Text_Column (0);
      Box.Pack_Start (Self.Spec_Ext);
      Self.Spec_Ext.Append_Text (".h");
      Self.Spec_Ext.Append_Text (".hh");
      Self.Spec_Ext.Append_Text (".H");
      Self.Spec_Ext.Append_Text (".hpp");

      Gtk_New_Hbox (Box, Homogeneous => False);
      Vbox.Pack_Start (Box, Expand => False);

      Gtk_New (Label, -"Implementation:");
      Label.Set_Alignment (0.0, 0.5);
      Group.Add_Widget (Label);
      Box.Pack_Start (Label);

      Gtk_New_With_Entry (Self.Body_Ext);
      Self.Body_Ext.Set_Sensitive (not Read_Only);
      Self.Body_Ext.Set_Entry_Text_Column (0);
      Box.Pack_Start (Self.Body_Ext);
      Self.Body_Ext.Append_Text (".c");
      Self.Body_Ext.Append_Text (".cc");
      Self.Body_Ext.Append_Text (".C");
      Self.Body_Ext.Append_Text (".cpp");

      Gtk_New (Frame, -"Exceptions");
      Self.Pack_Start (Frame, Expand => True, Fill => True);
      Gtk_New (Self.Exceptions, Self.Language.all);
      Self.Exceptions.Set_Border_Width (3);
      Frame.Add (Self.Exceptions);

      --  Now show the project's settings

      --  If the project is null, we get the default values from the current
      --  top-level project. It will automatically have the default extensions
      --  set when a project was registered, unless overridden by the user

      if Project = No_Project then
         P := Get_Project (Kernel);
      end if;

      Set_Text
        (Gtk_Entry (Get_Child (Self.Spec_Ext)),
         P.Attribute_Value
           (Spec_Suffix_Attribute, Index => Self.Language.all));
      Set_Text
        (Gtk_Entry (Get_Child (Self.Body_Ext)),
         P.Attribute_Value
           (Impl_Suffix_Attribute, Index => Self.Language.all));

      if Display_Exceptions then
         Show_Project_Settings (Self.Exceptions, Project);
      end if;
   end Initialize;

   -------------
   -- Destroy --
   -------------

   overriding procedure Destroy (Self : in out Foreign_Naming_Editor_Record) is
   begin
      Free (Self.Language);
   end Destroy;

   ----------------
   -- Is_Visible --
   ----------------

   overriding function Is_Visible
     (Self         : not null access Foreign_Naming_Editor_Record;
      Languages    : GNAT.Strings.String_List) return Boolean
   is
   begin
      return In_List (Self.Language.all, Languages);
   end Is_Visible;

   ------------------
   -- Edit_Project --
   ------------------

   overriding function Edit_Project
     (Self               : not null access Foreign_Naming_Editor_Record;
      Project            : Project_Type;
      Kernel             : not null access Kernel_Handle_Record'Class;
      Languages          : GNAT.Strings.String_List;
      Scenario_Variables : Scenario_Variable_Array) return Boolean
   is
      pragma Unreferenced (Languages, Kernel);
      Changed  : Boolean;
   begin
      Changed := Create_Project_Entry
        (Self.Exceptions, Project, Scenario_Variables);

      if Project = No_Project
        or else Project.Attribute_Value
          (Attribute => Spec_Suffix_Attribute,
           Index     => Self.Language.all) /= Get_Active_Text (Self.Spec_Ext)
      then
         Project.Set_Attribute
           (Scenario  => Scenario_Variables,
            Attribute => Spec_Suffix_Attribute,
            Value     => Get_Active_Text (Self.Spec_Ext),
            Index     => Self.Language.all);
         Changed := True;
      end if;

      if Project = No_Project
        or else Project.Attribute_Value
          (Attribute => Impl_Suffix_Attribute,
           Index     => Self.Language.all) /= Get_Active_Text (Self.Body_Ext)
      then
         Project.Set_Attribute
           (Scenario  => Scenario_Variables,
            Attribute => Impl_Suffix_Attribute,
            Value     => Get_Active_Text (Self.Body_Ext),
            Index     => Self.Language.all);
         Changed := True;
      end if;

      return Changed;
   end Edit_Project;

end Foreign_Naming_Editors;
