with Io;
with Lines;
with Files;
with Pathnames;
with String_Utilities;
with Low_Level_File_Operations;
package body Defaults is

    Catalog_Position : constant Natural := 1;
    Version_Position : constant Natural := 2;

    function Defaults_For (This_User : in User_Name) return Lines.Iterator is
    begin  
        return (Files.Create (From_File =>
                                 Pathnames.Defaults_File_For (This_User)));
    end Defaults_For;

    function Catalog (For_User : in User_Name) return Default is
    begin  
        return (Lines.Line_At (Catalog_Position, Defaults_For (For_User)));
        --
    exception
        when others =>
            raise Io_Failure;
            --
    end Catalog;

    function Catalog (For_User : in User_Name) return Simple_Name is
    begin  
        return (String_Utilities.Upper_Case (Lines.Image (Catalog (For_User))));
        --
    exception
        when others =>
            raise Io_Failure;
            --
    end Catalog;

    function Full_Catalog (For_User : in User_Name) return Full_Name is
    begin
        return (Pathnames.Full_Catalog_Name (Catalog (For_User)));
    end Full_Catalog;

    function Version (For_User : in User_Name) return Default is
    begin  
        return (Lines.Line_At (Version_Position, Defaults_For (For_User)));
        --
    exception
        when others =>
            raise Io_Failure;
            --
    end Version;

    function Version (For_User : in User_Name) return Simple_Name is
    begin  
        return (String_Utilities.Upper_Case (Lines.Image (Version (For_User))));
        --
    exception
        when others =>
            raise Io_Failure;
            --
    end Version;

    function Full_Version (For_User : in User_Name) return Full_Name is
        --
        -- This one looks different because by "breaking" the abstraction,
        -- it is faster (only one access to the underlying file representation
        -- instead of two).
        --
    begin  
        declare
            The_Defaults : Lines.Iterator := Defaults_For (For_User);
            The_Catalog : constant Simple_Name :=
               Lines.Image (Lines.Line_At (Catalog_Position, The_Defaults));
            The_Version : constant Simple_Name :=
               Lines.Image (Lines.Line_At (Version_Position, The_Defaults));
        begin
            return (Pathnames.Full_Version_Name
                       (This_Catalog =>
                           Pathnames.Full_Catalog_Name (The_Catalog),
                        This_Version => The_Version));
        end;
        --
    exception
        when others =>
            raise Io_Failure;
            --
    end Full_Version;

    procedure Set (For_User : in User_Name;
                   Catalog : in Simple_Name;
                   Version : in Simple_Name) is
        --
        The_File : Io.File_Type;
        --
    begin
        The_File := Low_Level_File_Operations.Open_To_Write
                       (Pathnames.Defaults_File_For (For_User));
        Io.Put_Line (The_File, Catalog);
        Io.Put_Line (The_File, Version);
        Low_Level_File_Operations.Close (The_File);
        --
    exception
        when others =>
            Low_Level_File_Operations.Close (The_File);
            raise Io_Failure;
            --
    end Set;

end Defaults;