-- Employee example: Using pointers
-- Each procedure only has one parameter
-- Uses a record type to join the array and a count of the number of employees
-- Uses an access type

with ada.text_io; use ada.text_io; 
with ada.float_text_io; use ada.float_text_io; 
 
procedure employ5  is 
    type Employee is record
        name: string(1 .. 20);
        id: string(1 .. 6);
        salary: float;
    end record;

    type Emp_Access is access Employee;

    type Emp_array is array(natural range <>) of Emp_Access;

    type Emp_list is record 
        emps: Emp_array(1 .. 100);
        count: Natural;
    end record;


    -- Input all employees
    procedure get(emp_l: out Emp_list) is
        e: Emp_Access;   -- Can't use access Employee
    begin
        skip_line;

        emp_l.count := 0;
        while not end_of_file loop
            emp_l.count := emp_l.count + 1;

            e := new Employee;

            get(e.all.name);
            get(e.all.id);
            get(e.salary);    -- .all is optional

            emp_l.emps(emp_l.count) := e;
        end loop;
    end get;


    -- Give all a raise, accessing the record directly
    procedure give_all_raise_v1(raise_amt: Float; emp_l: Emp_list) is
        e: access Employee;
    begin
        for i in reverse 1 .. emp_l.count loop
            e := emp_l.emps(i);  -- Pointer to object
            e.salary := e.salary + raise_amt;
        end loop;
    end give_all_raise_v1;


    -- Give all a raise, using the entire record
    procedure give_all_raise_v2(raise_amt: Float; emp_l: Emp_list) is
        e: Employee;
    begin
        for i in reverse 1 .. emp_l.count loop
            e := emp_l.emps(i).all;  -- An actual employee
            e.salary := e.salary + raise_amt;
            emp_l.emps(i).all := e;
            -- Or use emp_l.emps(i).all.salary := emps.emps(i).all.salary + raise_amt;
        end loop;
    end give_all_raise_v2;


    -- Print all high salary employees
    procedure put(emp_l: Emp_list) is
        e: access Employee;
    begin
        for i in reverse 1 .. emp_l.count loop
            e := emp_l.emps(i);  -- Make a copy of the employee
            if e.salary > 50_000.00 then 
                put(e.name);
                put(e.id);
                put(e.salary, 9, 2, 0);
                new_line;
            end if;
        end loop;
    end put;

    the_emp_l: Emp_list;
begin
    get(the_emp_l);

    give_all_raise_v1(1000.0, the_emp_l);
    give_all_raise_v2(1000.0, the_emp_l);

    put(the_emp_l);
end employ5;