with Closure;
with Io;
with Ada;  
with Common;
with Compilation;
with Directory_Tools;
package body Replace_Id is

    package Sio renames Io;
    package Object renames Directory_Tools.Object;
    package Traversal renames Directory_Tools.Traversal;
    package Naming renames Directory_Tools.Naming;
    package Ada_Object renames Directory_Tools.Ada_Object;

    procedure Replace_Id (In_Units : in out Object.Iterator;
                          Old_Id : String;
                          New_Id : String) is
        Obj : Object.Handle;
    begin
        while not Object.Done (In_Units) loop
            Obj := Object.Value (In_Units);

            Io.Put_Line ("Unit: " & Naming.Unique_Full_Name (Obj));

            if Ada_Object."=" (Ada_Object.State (Obj), Ada_Object.Source) then
                Common.Edit (Naming.Unique_Full_Name (Obj));

                Common.Object.Parent (4);
                Ada.Replace_Id (Old_Id, New_Id);

                Common.Format;
                Common.Commit;
                Common.Abandon;
                Io.Put_Line ("has been scanned for id replacement.");
            else
                Io.Put_Line ("is in the " & Ada_Object.Unit_State'Image
                                               (Ada_Object.State (Obj)) &
                             " state.  Replacement abandoned");
            end if;

            Io.New_Line;

            Object.Next (In_Units);
        end loop;
    end Replace_Id;

    procedure In_Dependency_Closure (Of_Unit : in String := "<SELECTION>";
                                     Old_Id : in String := "";
                                     New_Id : in String := "") is

        Main : Object.Handle := Naming.Resolution (Of_Unit);
        The_Closure : Object.Iterator;
        Status : Object.Error_Code;
    begin
        if Object.Is_Bad (Main) then
            Io.Put_Line (Io.Standard_Error, "Bad unit name");
        else
            The_Closure := Closure.Dependency_Closure (Main);
            Compilation.Demote (Unit => Of_Unit,
                                Goal => Compilation.Source,
                                Limit => "<WORLDS>",
                                Effort_Only => False,
                                Response => "<PROFILE>");
            Object.Reset (The_Closure);
            Replace_Id (The_Closure, Old_Id, New_Id);
        end if;
    end In_Dependency_Closure;

    procedure In_Set_Of_Units (Units : in String := "<REGION>";
                               Old_Id : in String := "";
                               New_Id : in String := "") is
        Iter : Object.Iterator := Naming.Resolution (Units);
    begin
        Replace_Id (Iter, Old_Id, New_Id);
    end In_Set_Of_Units;
end Replace_Id;