with Text_Io;
with Work_Calendar;
with List_Pkg;
use Text_Io;

package Data_Pkg is
    --------------------------------------------------------------------------------
    --|  NAME:  DATA_PKG
    --|
    --|  OVERVIEW:
    --|    This package defines the five basic data types used in tracker:
    --|    activity, element, milestone, personnel, and subsystem.
    --|    Each one is a record with a pointer pointing to that record.
    --|    The values for the fields are obtained by prompt/response sessions
    --|    with the user.  Milestone, personnel, and subsystem data each have
    --|    as a field of their record, a pointer to the element list.  This
    --|    field is the list of elements to which that data belongs.  The
    --|    List_Pkg instantiations for each data type is also in this package.
    --|
    --|    In addition to the data types, this package contains the global
    --|    variables used in the Global_Package and the counters for each data
    --|    type.
    --|
    --|    Since most of the other packages with this package, instantiation of
    --|    the Calendar_Package and other frequently needed packages is done
    --|    in the data package to reduce the number of instantiations throughout
    --|    the TRACKER modules.
    --|
    --|  EXCEPTIONS HANDLED:
    --|    none
    --|
    --|  HISTORY:
    --|    written by   May Lee            February 1985
    --|    written by   Bonnie Burkhardt   March 1985
    --|
    --|  NOTES:
    --|    The function CONVERT, which is contained in this package, is only
    --|    there to correct a quirk in Ada when dealing with enumeration
    --|    types that are single characters.  We have declared an enumeration
    --|    type act_phase_char_set, which is a subset of the ascii character
    --|    set.  This enumeration type must appear with quotes around it when
    --|    getting it from a file or a user, and will be printed with quotes
    --|    when put to the screen.  We want to be able to declare 1 as a member
    --|    of act_phase_char_set, but it is handled literally as '1' (including
    --|    the quotes).
    --------------------------------------------------------------------------------

    -- data constants
    Act_Name_Max_Len : constant Natural := 10;
    El_Key_Max_Len : constant Natural := 6;
    Max_Num_Activities : constant Natural := 10;
    Pr_Name_Max_Len : constant Natural := 20;
    Pr_Init_Max_Len : constant Natural := 2;
    Sub_Name_Max_Len : constant Natural := 10;

    package Integer_Text_Io is new Integer_Io (Integer);
    use Integer_Text_Io;
    package Float_Text_Io is new Float_Io (Float);
    use Float_Text_Io;
    package Boolean_Text_Io is new Enumeration_Io (Boolean);
    use Boolean_Text_Io;

    -- instantiate generic work calendar package
    Days_In_Work_Week : constant Integer := 5;
    Hours_In_Work_Day : constant Float := 8.0;
    Work_Days_Off_In_Year : constant Integer := 10;
    package Calendar is new Work_Calendar (Days_In_Work_Week, Hours_In_Work_Day,
                                           Work_Days_Off_In_Year);
    use Calendar;

    subtype Ms_Num_Type is Integer range 1 .. 99;
    subtype Pr_Init_Type is String (1 .. Pr_Init_Max_Len);
    subtype Ss_Name_Type is String (1 .. Sub_Name_Max_Len);
    type Act_Phase_Char_Set is ('0', '1', '2', '3', '4', '5', '6',
                                '7', '8', '9', ' ', 'd', 'D');
    type Activity_Phase_Percent is array (1 .. 10) of Act_Phase_Char_Set;
    Ac_Pct_Value : constant array (Act_Phase_Char_Set) of Float :=
       (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0,
        70.0, 80.0, 90.0, 0.0, 100.0, 100.0);

    --  element data type
    subtype El_Key_Type is String (1 .. El_Key_Max_Len);
    type Dates_Done_Type is array (1 .. Max_Num_Activities) of Date_Type;
    type Hours_Left_Type is array (1 .. Max_Num_Activities) of Float;
    type People_Initials_Type is
       array (1 .. Max_Num_Activities) of Pr_Init_Type;
    type Element_Type (Two_Or_More_People : Boolean := False);
    type Element_Pointer is access Element_Type;

    type Element_Type (Two_Or_More_People : Boolean := False) is
        record
            Description : String (1 .. 35) := (others => ' ');
            Desc_Key : El_Key_Type := (others => ' ');
            Subsystem_Name : Ss_Name_Type := (others => ' ');
            Milestone_Num : Ms_Num_Type := 1;
            Priority : Ms_Num_Type := 1;
            Original_Size : Integer range 0 .. 99_999 := 0;
            Size_Done_At_Start : Integer range 0 .. 99_999 := 0;
            Current_Size : Integer range 0 .. 99_999 := 0;
            Complexity : Float range 0.1 .. 9.9 := 1.0;
            Activity_Completeness : Activity_Phase_Percent := (others => ' ');
            Hours_To_Complete : Float := 0.0;
            Date_Done : Date_Type := Null_Date;
            Prev_Date_Done : Date_Type := Null_Date;
            Date_Size_Verified : Date_Type := Null_Date;
            More_Than_One_Person : Boolean := Two_Or_More_People;
            case Two_Or_More_People is
                when False =>
                    Person_Initials : Pr_Init_Type := "  ";
                when True =>
                    Dates_Done : Dates_Done_Type := (others => Null_Date);
                    Hours_Left : Hours_Left_Type := (others => 0.0);
                    People_Initials : People_Initials_Type := (others => "  ");
            end case;
        end record;

    -------------

    -- instantiate generic element list handler
    package El_List_Pkg is new List_Pkg
                                  (Key => El_Key_Type, Data => Element_Pointer);

    -------------

    --  activity phase data
    subtype Ac_Name_Type is String (1 .. Act_Name_Max_Len);
    type Activity_Type;
    type Activity_Pointer is access Activity_Type;

    type Activity_Type is
        record
            Name : Ac_Name_Type := (others => ' ');
            Percent_Tot_Proj : Float range 0.0 .. 100.0 := 0.0;
            Priority : Integer range 1 .. 10 := 1;
            Consider_In_Calc : Boolean := True;
            Percent_At_Start : Float range 0.0 .. 100.0 := 0.0;
        end record;

    ------------

    -- instantiate generic activity list handler
    package Ac_List_Pkg is new List_Pkg (Key => Ac_Name_Type,
                                         Data => Activity_Pointer);

    ------------

    --  milestone data type
    type Milestone_Type;
    type Milestone_Pointer is access Milestone_Type;

    type Milestone_Type is
        record
            Number : Ms_Num_Type := 1;
            Completion_Number : Ms_Num_Type := 1;
            Due_Date : Date_Type := Null_Date;
            Description : String (1 .. 50) := (others => ' ');
            Element_List : El_List_Pkg.List_Type;
        end record;

    ------------

    -- instantiate generic milestone list handler
    package Ms_List_Pkg is new List_Pkg (Key => Ms_Num_Type,
                                         Data => Milestone_Pointer);

    ------------

    --  personnel data type
    type Dates_List is array (1 .. 3) of Date_Type;
    type Personnel_Type;
    type Personnel_Pointer is access Personnel_Type;

    type Personnel_Type is
        record
            Name : String (1 .. Pr_Name_Max_Len) := (others => ' ');
            Initials : Pr_Init_Type := "  ";
            Production_Rate : Float range 0.01 .. 99.99 := 1.0;
            Hours_Per_Week : Integer range 1 .. 84 := 40;
            Start_Dates : Dates_List := (others => Null_Date);
            Stop_Dates : Dates_List := (others => Null_Date);
            Element_List : El_List_Pkg.List_Type;
        end record;

    ------------

    -- instantiate generic personnel list handler
    package Pr_List_Pkg is new List_Pkg (Key => Pr_Init_Type,
                                         Data => Personnel_Pointer);

    ------------

    --  subsystem data type
    type Task_Numbers_Type is
       array (1 .. Max_Num_Activities) of Integer range 0 .. 9999;
    type Subsystem_Type;
    type Subsystem_Pointer is access Subsystem_Type;

    type Subsystem_Type is
        record
            Name : Ss_Name_Type := (others => ' ');
            Percent_At_Start : Float range 0.0 .. 100.0 := 0.0;
            Task_Numbers : Task_Numbers_Type := (others => 0);
            Element_List : El_List_Pkg.List_Type;
        end record;

    ------------

    -- instantiate generic subsystem list handler
    package Ss_List_Pkg is new List_Pkg (Key => Ss_Name_Type,
                                         Data => Subsystem_Pointer);

    -----------

    -- make data lists visible to the report generator
    Ac_List : Ac_List_Pkg.List_Type;
    El_List : El_List_Pkg.List_Type;
    Ms_List : Ms_List_Pkg.List_Type;
    Pr_List : Pr_List_Pkg.List_Type;
    Ss_List : Ss_List_Pkg.List_Type;

    -----------

    Project_Name : String (1 .. 30) := (others => ' ');
    Project_Number : Integer range 0 .. 999 := 0;
    Manager_Name : String (1 .. 30) := (others => ' ');
    Date : Date_Type := (Month => 1, Day => 1, Year => 1980);
    Num_Of_Activities : Integer := 0;
    Num_Of_Elements : Integer := 0;
    Num_Of_Milestones : Integer := 0;
    Num_Of_People : Integer := 0;
    Num_Of_Subsystems : Integer := 0;

    -----------

    function Convert (Char : Character) return Act_Phase_Char_Set;
    function Convert (Quote_Char : Act_Phase_Char_Set) return Character;

end Data_Pkg;
