-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset 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 distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

--------------------------------------------------------------------------------
--Synopsis:                                                                   --
--                                                                            --
--Package providing a structure in which to store file details, in the form   --
--of a full pathname (without extension) and a type, either PlainFile or      --
--directory.                                                                  --
--                                                                            --
--To be used in tandem with the Heap data structure, hence the use of         --
--Heap.Atom as the array range                                                --
--------------------------------------------------------------------------------
with OSFiling;
package body FileDetails is

   ---------------------------------------------------------------------------
   procedure Add
     (Details  : in out DataType;
      Index    :    out HeapIndex.IndexType;
      Success  :    out Boolean;
      Name     : in     E_Strings.T;
      FileType : in     FileTypes)
   is
   begin
      if Details.HighMark < HeapIndex.IndexType'Last then
         Success                            := True;
         Details.HighMark                   := Details.HighMark + 1;
         Index                              := Details.HighMark;
         Details.Details (Details.HighMark) := DetailsElement'(Name, FileType, False);
      else
         Success := False;
         Index   := 0;
      end if;
   end Add;

   --------------------------------------------------------------------------
   procedure Initialize (Details : out DataType) is
   begin
      --# accept F, 23, Details.Details, "Element-by-element array initialization" &
      --#        F, 602, Details, Details.Details, "Element-by-element array initialization";
      Details.HighMark := 0;
      for I in HeapIndex.IndexType loop
         Details.Details (I) := NullDetailsElement;
      end loop;
   end Initialize;

   -------------------------------------------------------------------------
   procedure MarkDirectoryResolved (Details : in out DataType;
                                    Index   : in     HeapIndex.IndexType) is
   begin
      Details.Details (Index).DirectoryIsResolved := True;
   end MarkDirectoryResolved;

   -------------------------------------------------------------------------
   procedure Order
     (FirstName  : in     E_Strings.T;
      FirstType  : in     FileTypes;
      SecondName : in     E_Strings.T;
      SecondType : in     FileTypes;
      Success    :    out Boolean;
      Result     :    out E_Strings.Order_Types)
   is
      NameOrder : E_Strings.Order_Types;

   begin -- Order

      -- check which name comes first
      NameOrder := OSFiling.Order (FirstName, SecondName);

      if FirstType = Invalid or SecondType = Invalid then
         Success := False;
         Result  := E_Strings.Neither_First;
      else
         Success := True;

         -- if one comes first then return it
         if NameOrder /= E_Strings.Neither_First then
            Result := NameOrder;
         else
            -- otherwise if one is a file and the other is a directory,
            -- the file comes first
            if (FirstType = PlainFile and SecondType = Directory) then
               Result := E_Strings.First_One_First;
            elsif (FirstType = Directory and SecondType = PlainFile) then
               Result := E_Strings.Second_One_First;
            else
               -- otherwise neither comes first
               Result := E_Strings.Neither_First;
            end if;
         end if;
      end if;
   end Order;

   --------------------------------------------------------------------------
   procedure Retrieve
     (Details             : in     DataType;
      Index               : in     HeapIndex.IndexType;
      Success             :    out Boolean;
      Name                :    out E_Strings.T;
      FileType            :    out FileTypes;
      DirectoryIsResolved :    out Boolean)
   is
   begin
      if Index <= Details.HighMark and Index /= 0 then
         Success             := True;
         Name                := Details.Details (Index).Name;
         FileType            := Details.Details (Index).FileType;
         DirectoryIsResolved := Details.Details (Index).DirectoryIsResolved;
      else
         Name                := E_Strings.Empty_String;
         FileType            := Invalid;
         DirectoryIsResolved := False;
         Success             := False;
      end if;
   end Retrieve;

end FileDetails;
