-------- SIMTEL20 Ada Software Repository Prologue ------------
--                                                           -*
-- Unit name    : General Management
-- Version      : 1.0
-- Contact      : Lt. Colonel Falgiano
--              : ESD/SCW
--              : Hanscom AFB, MA  01731
-- Author       : GTE Sylvania Systems Group
--              : Western Division
--              : PO Box 7188
--              : San Diego, Ca 94039
-- DDN Address  :
-- Copyright    : (c) 1985 GTE, Inc.
-- Date created : Dec. 1984
-- Release date : May  1985
-- Last update  :
--                                                           -*
---------------------------------------------------------------
--                                                           -*
-- Keywords     :
----------------:
--
-- Abstract     : The TRACKR program tracks the progress within projects and
----------------: generates reports, estimates time to complete a project,
----------------: and estimates project requirements.  INPREP builds the data
----------------: file for TRACKR interactively and outputs error messages for
----------------: invalid data.  The MANPOWER program based on the Simple Boehm
----------------: Model produces manpower loading curves for several calculated
----------------: schedules based on the number of lines of code and type of
----------------: system.
----------------:
----------------:
----------------:
----------------: This tool was developed as a precursor for
----------------: the WMCCS Information System (WIS).  An
----------------: executable version of the tool has been
----------------: demonstrated.  This source code has sub-
----------------: sequently been recompiled but has not under-
----------------: gone extensive testing.
----------------:
--                                                           -*
------------------ Revision history ---------------------------
--                                                           -*
-- DATE         VERSION AUTHOR                  HISTORY
-- 5/84            1.0                          Initial Release
--                                                           -*
------------------ Distribution and Copyright -----------------
--                                                           -*
-- This prologue must be included in all copies of this software.
--
-- This software is copyright by the author.
--
-- This software is released to the Ada community.
-- This software is released to the Public Domain (note:
--   software released to the Public Domain is not subject
--   to copyright protection).
-- Restrictions on use or distribution:  NONE
--                                                           -*
----------------- Disclaimer ----------------------------------
--                                                           -*
-- This software and its documentation are provided "AS IS" and
-- without any expressed or implied warranties whatsoever.
--
-- No warranties as to performance, merchantability, or fitness
-- for a particular purpose exist.
--
-- Because of the diversity of conditions and hardware under
-- which this software may be used, no warranty of fitness for
-- a particular purpose is offered.  The user is advised to
-- test the software thoroughly before relying on it.  The user
-- must assume the entire risk and liability of using this
-- software.
--
-- In no event shall any person or organization of people be
-- held responsible for any direct, indirect, consequential
-- or inconsequential damages or lost profits.
--                                                          -*
----------------- END-PROLOGUE -------------------------------

with Text_Io;
use Text_Io;
with Float_Io;
use Float_Io;
with Integer_Io;
use Integer_Io;
with Io_Exceptions;
use Io_Exceptions;
with Core_Functions;
use Core_Functions;

procedure Manpower is
    ----------------------------------------------------------------------
    --| NAME : MANPOWER
    --|
    --| OVERVIEW:
    --|   This program uses Barry Boehm's COCOMO equations and Tom DeMarco's
    --|   PNR cost model to estimate the staffing requirements for a typical
    --|   software project.  Some of the basic man-month estimate equations
    --|   can be modified to reflect the project more accurately.
    --|
    --| HISTORY:
    --|  written by Bonnie Burkhardt     March 1985
    --|
    --| EXCEPTIONS HANDLED:
    --|   others   an error message is printed and execution terminates
    --|
    --| NOTES:
    --|   The abbreviations MM and TDEV are used in the variable names so
    --|   the equations will more closely correspond to the ones used by Barry
    --|   Boehm.
    ----------------------------------------------------------------------

    type Profile_Type is (Nominal, Compressed);
    type Mode_Type is (Organic, Semidetached, Embedded);
    subtype Accurate_Float is Float digits 15;
    subtype Month_Type is Integer range 1 .. 100;

    Tdev : Accurate_Float;
    Accel_Rate : Accurate_Float;
    Staffing : array (Month_Type'First - 1 .. Month_Type'Last) of
                  Accurate_Float;
    Month : Month_Type;
    Td_Nominal : Accurate_Float;
    Imp_Region : Accurate_Float;
    Man_Months : Accurate_Float;
    Report : File_Type;
    File_Name : constant String := "MANPOWER_RPT";

    Finished : Boolean := False;
    Ksloc : Accurate_Float;
    Mode : Mode_Type;
    Param : Accurate_Float;
    Choice : Integer range 1 .. 3;
    Valid_Entry : Boolean := False;
    Yes_Or_No : Character := 'N';

    -- parameters of the equations that may be varied
    Coeff_Mm_Org : Accurate_Float := 2.4;
    Coeff_Mm_Semi : Accurate_Float := 3.0;
    Coeff_Mm_Embed : Accurate_Float := 3.6;
    Exp_Mm_Org : Accurate_Float := 1.05;
    Exp_Mm_Semi : Accurate_Float := 1.12;
    Exp_Mm_Embed : Accurate_Float := 1.20;
    Coeff_Tdev_Org : Accurate_Float := 2.5;
    Coeff_Tdev_Semi : Accurate_Float := 2.5;
    Coeff_Tdev_Embed : Accurate_Float := 2.5;
    Exp_Tdev_Org : Accurate_Float := 0.38;
    Exp_Tdev_Semi : Accurate_Float := 0.35;
    Exp_Tdev_Embed : Accurate_Float := 0.32;

    procedure Change_Parameters (Name : in String;
                                 Coeff_Mm : in out Accurate_Float;
                                 Exp_Mm : in out Accurate_Float;
                                 Coeff_Tdev : in out Accurate_Float;
                                 Exp_Tdev : in out Accurate_Float) is separate;
    procedure Print_Banner_Page is separate;
    procedure Graph_It (Title : in String) is separate;
    procedure Get_Staff_Profile
                 (Profile : in Profile_Type;
                  Accel_Increment : in Accurate_Float) is separate;

begin
    -- open report file
    Create (Report, Name => File_Name);

    -- change the parameters of the equations, if desired
    New_Line (6);
    Put
       ("Would you like to change any of the parameters in the COCOMO equations?");
    New_Line;
    Put (" (Y or N -- def=N) : ");

    begin
        if not End_Of_Line then
            Get (Yes_Or_No);
            Skip_Line;
            New_Line (3);

            if Yes_Or_No = 'Y' or Yes_Or_No = 'y' then
                Put_Line ("Enter the value of the parameter (X.X)");
                Put_Line ("(Press <ret> to assume the default value)");

                Change_Parameters ("Organic", Coeff_Mm_Org, Exp_Mm_Org,
                                   Coeff_Tdev_Org, Exp_Tdev_Org);
                Change_Parameters ("Semidetached", Coeff_Mm_Semi, Exp_Mm_Semi,
                                   Coeff_Tdev_Semi, Exp_Tdev_Semi);
                Change_Parameters ("Embedded", Coeff_Mm_Embed, Exp_Mm_Embed,
                                   Coeff_Tdev_Embed, Exp_Tdev_Embed);
            end if;
        end if;
    exception
        when others =>
            Skip_Line;
    end;

    -- repeat until user specifies to quit
    while not Finished loop
        -- get lines of code estimate
        Valid_Entry := False;
        New_Line (6);
        Put (" Enter # of lines of source code in thousands (XX.X) : ");

        loop
            begin
                Get (Ksloc);
                exit;
            exception
                when others =>
                    Skip_Line;
                    New_Line;
                    Put ("Invalid input, try again (e.g., 0.2 or 2.0) : ");
            end;
        end loop;

        -- get the MODE type
        New_Line (4);
        Put_Line (" Basic Cocomo Effort and Schedule Equations:");
        Set_Col (10);
        Put_Line ("1. Organic");
        Set_Col (10);
        Put_Line ("2. Semidetached");
        Set_Col (10);
        Put_Line ("3. Embedded");
        New_Line (3);
        Put (" Enter number corresponding to MODE type desired: ");

        loop
            begin
                Get (Choice);
                Skip_Line;
                exit;
            exception
                when others =>
                    Skip_Line;
                    New_Line;
                    Put ("Invalid input, try again :");
            end;
        end loop;

        -- Calculate the MAN_MONTHS of effort and the month estimate for project
        -- final delivery using the user specified effort equation.  These
        -- equations are Boehm's equations and can be slightly modified to reflect
        -- closer estimations, if desired.
        case Choice is
            when 1 =>
                Mode := Organic;
                Man_Months := Coeff_Mm_Org * Exp (Exp_Mm_Org * Log (Ksloc));
                Td_Nominal := Coeff_Tdev_Org *
                                 Exp (Exp_Tdev_Org * Log (Man_Months));
            when 2 =>
                Mode := Semidetached;
                Man_Months := Coeff_Mm_Semi * Exp (Exp_Mm_Semi * Log (Ksloc));
                Td_Nominal := Coeff_Tdev_Semi *
                                 Exp (Exp_Tdev_Semi * Log (Man_Months));
            when 3 =>
                Mode := Embedded;
                Man_Months := Coeff_Mm_Embed * Exp (Exp_Mm_Embed * Log (Ksloc));
                Td_Nominal := Coeff_Tdev_Embed *
                                 Exp (Exp_Tdev_Embed * Log (Man_Months));
        end case;

        -- calculate the impossible region.
        Imp_Region := 1.9 * Exp (0.3333333333333 * Log (Man_Months));

        Print_Banner_Page;

        -- find the nominal staffing profile
        Get_Staff_Profile (Nominal, 0.001);

        -- find the compressed and expanded staffing profiles
        Get_Staff_Profile (Compressed, 0.01);

        -- determine if user wishes to continue
        New_Line (2);
        Put (" Do you want to write another report (Y or N -- def=N): ");

        begin
            if End_Of_Line then
                Finished := True;
            else
                Get (Yes_Or_No);

                if Yes_Or_No /= 'Y' and Yes_Or_No /= 'y' then
                    Finished := True;
                end if;
            end if;
        exception
            -- default is 'N'
            when others =>
                Skip_Line;
        end;
    end loop;

    Close (Report);

exception
    when others =>
        Put_Line ("exception raised in MANPOWER");
end Manpower;
