separate (Tracker.Report_Generator)
procedure List_By_Milestone is
    ----------------------------------------------------------------------
    --|  NAME:  LIST_BY_MILESTONE
    --|
    --|  OVERVIEW:
    --|    One report is produced for each milestone which lists all the
    --|    elements belonging to that milestone.  The element data includes
    --|    the remaining man-hours of work to complete each entity, the total
    --|    original size, the total current size, the average complexity,
    --|    and the total remaining man-hours of work to complete each
    --|    milestone.
    --|
    --|  EXCEPTIONS HANDLED:
    --|    others   an error message is printed and execution continues
    --|
    --|  HISTORY:
    --|    written by   Bonnie Burkhardt   March 1985
    ----------------------------------------------------------------------

    use Ac_List_Pkg;
    use El_List_Pkg;
    use Ms_List_Pkg;
    use Calendar;

    Header1 : String (1 .. 132) := (others => ' ');
    Header2 : String (1 .. 132) := (others => ' ');
    Header_Lines : String (1 .. 132) := (others => ' ');

    Ac_Index : Integer := 0;
    Ac_Ptr : Activity_Pointer;
    Date_String : String (1 .. 8) := "  /  /  ";
    End_List : Boolean := False;
    Ele_Count : Integer := 0;
    Ele_In_Ms : Integer := 0;
    Ele_Ptr : Element_Pointer;
    Line_Count : Integer := 0;
    Ms_Index : Integer := 0;
    Ms_Ptr : Milestone_Pointer;
    Ms_String : String (1 .. 2) := "  ";
    Title : constant String := "LIST BY MILESTONE REPORT";
    Tot_Currnt : Integer range 0 .. 9_999_999 := 0;
    Tot_Eq_New : Integer range 0 .. 9_999_999 := 0;
    Tot_Orig : Integer range 0 .. 9_999_999 := 0;
    Tot_Cpxy : Float := 0.0;
    Tot_Hours : Float := 0.0;

    procedure Init_Headers is separate;
    procedure Print_An_Element is separate;
    procedure Print_Ms_Total is separate;

begin
    Init_Headers;

    Start_Walk (Ms_List);

    loop
        Walk (Ms_List, Ms_Ptr, End_List);
        exit when End_List;
        Line_Count := 0;

        -- create the subtitle string
        Put (Ms_String, Ms_Ptr.Number);

        if Ms_Ptr.Due_Date = Null_Date then
            Start_Page
               (Title, "Milestone # " & Ms_String & " is due on a null date" &
                          " -- " & Ms_Ptr.Description,
                Header1, Header2, Header_Lines);
        else
            Put (Date_String (1 .. 2), Ms_Ptr.Due_Date.Month);
            Put (Date_String (4 .. 5), Ms_Ptr.Due_Date.Day);
            Put (Date_String (7 .. 8), Ms_Ptr.Due_Date.Year mod 100);
            Start_Page (Title, "Milestone # " & Ms_String & " is due " &
                                  Date_String & " -- " & Ms_Ptr.Description,
                        Header1, Header2, Header_Lines);
        end if;

        Start_Walk (Ms_Ptr.Element_List);
        Ele_In_Ms := 0;

        loop
            Walk (Ms_Ptr.Element_List, Ele_Ptr, End_List);

            -- if end of list, print out totals
            if End_List then
                if (Ele_In_Ms > 0) then
                    Print_Ms_Total;
                end if;

                exit;
            end if;

            -- update running totals
            Ele_Count := Ele_Count + 1;
            Tot_Currnt := Tot_Currnt + Ele_Ptr.Current_Size;
            Tot_Eq_New := Tot_Eq_New - Ele_Ptr.Size_Done_At_Start +
                             Ele_Ptr.Current_Size;
            Tot_Orig := Tot_Orig + Ele_Ptr.Original_Size;
            Tot_Cpxy := Tot_Cpxy + Ele_Ptr.Complexity;
            Tot_Hours := Tot_Hours + Ele_Ptr.Hours_To_Complete;

            Print_An_Element;

            Ele_In_Ms := Ele_In_Ms + 1;
            Line_Count := Line_Count + 1;

            if Line_Count >= Max_Data_Lines - 2 then
                if Ms_Ptr.Due_Date = Null_Date then
                    Start_Page (Title, "Milestone # " & Ms_String &
                                          " is due on a null date" &
                                          " -- " & Ms_Ptr.Description,
                                Header1, Header2, Header_Lines);
                else
                    Start_Page
                       (Title, "Milestone # " & Ms_String & " is due " &
                                  Date_String & " -- " & Ms_Ptr.Description,
                        Header1, Header2, Header_Lines);
                end if;

                Line_Count := 0;
            end if;
        end loop;
    end loop;
exception
    when others =>
        Put_Line ("exception raised in LIST BY MILESTONE REPORT");
end List_By_Milestone;
