# Contains methods for setting up IHT ModVars

import numpy as np

import AvenirCommon.Util as acu

import SpectrumCommon.Const.GB.GBConst as gbc

import SpectrumCommon.Const.HW.HWConst as hwc
import SpectrumCommon.Const.HW.HWModVarFields as hwmvf
import SpectrumCommon.Util.HW.HWUtil as hwu
import SpectrumCommon.Modvars.HW.HWModVarUtil as hwmvu

#######################################################################################################
#                                                                                                     #
#                                       Staff types                                                   #
#                                                                                                     #
#######################################################################################################

def HW_create_staff_type_rec(ID = str, name = str, string_const = str, active = bool, staff_division_mstID = int, static_staff_type_map_mst_ID = int,
    num_facility_types = int, num_years = int, costing_mode = int):

    if costing_mode == gbc.GB_LIST_COSTING_MODE:
        avg_days_worked_per_year = 240
        hours_in_a_work_day = 6
        annual_real_salary_incr = 3.1

    else:
        avg_days_worked_per_year = 220
        hours_in_a_work_day = 8
        annual_real_salary_incr = 0.0

    return {
        hwmvf.HW_STAFF_ID                                          : ID,
        hwmvf.HW_STAFF_STR_CONSTANT                                : string_const,
        hwmvf.HW_STAFF_NAME                                        : name,
        hwmvf.HW_STAFF_ACTIVE                                      : active,
        hwmvf.HW_STAFF_CUSTOM                                      : False,
        hwmvf.HW_STAFF_DIVISION_MST_ID                             : staff_division_mstID,
        hwmvf.HW_STAFF_STATIC_MAP_MST_ID                           : static_staff_type_map_mst_ID,
        hwmvf.HW_STAFF_BASE_YEAR                                   : np.full((hwc.HW_NUM_STAFFING_LEVELS), 0).tolist(),
        hwmvf.HW_STAFF_ANNUAL_SALARY                               : 0.0, #1000.0,                
        hwmvf.HW_STAFF_ANNUAL_REAL_SALARY_INCR                     : annual_real_salary_incr,
        hwmvf.HW_STAFF_ANNUAL_BENEFITS                             : 0.0,          
        hwmvf.HW_STAFF_ANNUAL_BENEFITS_ADJUST                      : 0,
        hwmvf.HW_STAFF_PERC_TIME_SPENT_NOT_TRAIN_SERV              : 0,
        hwmvf.HW_STAFF_AVG_DAYS_WORKED_PER_YEAR                    : avg_days_worked_per_year,
        hwmvf.HW_STAFF_HOURS_IN_WORK_DAY                           : hours_in_a_work_day,
        hwmvf.HW_STAFF_CURR_ATTRIT_PER_YEAR                        : [],
        hwmvf.HW_STAFF_PERC_REC_ATTRIT_REDUC_INCENTS               : [],
        hwmvf.HW_STAFF_ANNUAL_COST_ATTRIT_REDUC_INCENTS            : [],
        hwmvf.HW_STAFF_PRESERV_NUM_SCHOOLS                         : 0,
        hwmvf.HW_STAFF_PRESERV_YEARS_TRAINING                      : 0,
        hwmvf.HW_STAFF_PRESERV_ANNUAL_COST_PER_STUDENT             : 0.0,
        hwmvf.HW_STAFF_PRESERV_CURR_ENROLLMENT                     : 0,
        hwmvf.HW_STAFF_PRESERV_GRADS_MOST_RECENT_YEAR              : 0,
        hwmvf.HW_STAFF_PRESERV_INST_NAMES                          : np.full((hwc.HW_NUM_PRESERV_TRAIN_INSTITUTIONS), '').tolist(),          
        hwmvf.HW_STAFF_PRESERV_AVG_YEARS_TRAINING_BY_INST          : np.full((hwc.HW_NUM_PRESERV_TRAIN_INSTITUTIONS), 0).tolist(),        
        hwmvf.HW_STAFF_PRESERV_ANNUAL_AVG_COST_PER_STUDENT_BY_INST : np.full((hwc.HW_NUM_PRESERV_TRAIN_INSTITUTIONS), 0.0).tolist(),    
        hwmvf.HW_STAFF_PRESERV_CURR_INTAKE_BY_INST                 : np.full((hwc.HW_NUM_PRESERV_TRAIN_INSTITUTIONS), 0).tolist(),  
        hwmvf.HW_STAFF_PRESERV_GRADS_MOST_RECENT_YEAR_BY_INST      : np.full((hwc.HW_NUM_PRESERV_TRAIN_INSTITUTIONS), 0).tolist(),           
        hwmvf.HW_STAFF_TOTAL_ANNUAL_RECRUITMENT                    : 0,
        hwmvf.HW_STAFF_PERC_NEW_GRADS_PUBLIC_SECTOR                : 0.0,
        hwmvf.HW_STAFF_INSERV_TRAIN_COST_PERC_SALARY               : 0.0,
        hwmvf.HW_STAFF_TARGET_SETTING_METHOD                       : np.full((hwc.HW_NUM_STAFFING_LEVELS), hwc.HW_FAC_STAFF_STANDARDS_MST_ID).tolist(),
        hwmvf.HW_STAFF_TARGET_STAFF_POP_RATIO                      : np.full((hwc.HW_NUM_STAFFING_LEVELS), 0.0).tolist(),
        hwmvf.HW_STAFF_TARGET_STAFF_PER_FACILITY                   : np.full((hwc.HW_NUM_STAFFING_LEVELS, num_facility_types), 0).tolist(),
        hwmvf.HW_STAFF_TARGET_SCALE_UP_EXISTING_PLANS              : np.full((hwc.HW_NUM_STAFFING_LEVELS, num_years), 0).tolist(),
        hwmvf.HW_STAFF_TARGET_ENROLLMENT                           : np.full((num_years), 0).tolist(),          
        hwmvf.HW_STAFF_TARGET_GRADUATION                           : np.full((num_years), 0).tolist(),        
        hwmvf.HW_STAFF_TARGET_RETENT_INCENT_LEVELS                 : [],
    }

def HW_init_staff_type_records(facility_type_records, num_years, costing_mode):
    staff_type_records = []

    num_facility_types = len(facility_type_records)

    # Health service providers
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_GENERAL_MEDICAL_PRACTITIONERS_MST_ID), 
            'General medical practitioners', 
            'GB_stGenMedPractitioners', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_GENERAL_MEDICAL_PRACTITIONERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_SPECIAL_MEDICAL_PRACTITIONERS_MST_ID), 
            'Specialist medical practitioners', 
            'GB_stSpecialistMedPractitioners', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_SPECIAL_MEDICAL_PRACTITIONERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    # Rachel: No longer exist in ISCO list.
    # staff_type_dict_list.append(
    #     HR_create_staff_type_rec(
    #         str(hrc.HR_OB_GYNS_MST_ID), 
    #         'Ob\Gyns', 
    #         'GB_stObGyns',
    #         True, 
    #         hrc.HR_HLTH_SERV_PROVIDER_MST_ID,
    #         hrc.HR_OB_GYNS_MST_ID, 
    #         num_facility_types, 
    #         num_years 
    #     )
    # )
    # staff_type_dict_list.append(
    #     HR_create_staff_type_rec(
    #         str(hrc.HR_PEDIATRICIANS_MST_ID), 
    #         'Pediatricians', 
    #         'GB_stPediatricians', 
    #         True,
    #         hrc.HR_HLTH_SERV_PROVIDER_MST_ID,
    #         hrc.HR_PEDIATRICIANS_MST_ID, 
    #         num_facility_types, 
    #         num_years 
    #     )
    # )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_NURSING_PROFESSIONALS_MST_ID), 
            'Nursing professionals', 
            'GB_stNursingProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_NURSING_PROFESSIONALS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MIDWIFERY_PROFESSIONALS_MST_ID), 
            'Midwifery professionals', 
            'GB_stMidwiferyProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_MIDWIFERY_PROFESSIONALS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_NURSING_ASSOCIATE_PROFESSIONALS_MST_ID), 
            'Nursing associate professionals', 
            'GB_stNursingAssocProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_NURSING_ASSOCIATE_PROFESSIONALS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MIDWIFERY_ASSOCIATE_PROFESSIONALS_MST_ID), 
            'Midwifery associate professionals', 
            'GB_stMidwiferyAssocProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_MIDWIFERY_ASSOCIATE_PROFESSIONALS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_DENTISTS_MST_ID), 
            'Dentists', 
            'GB_stDentists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_DENTISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_DENTAL_ASSIST_THERAPISTS_MST_ID), 
            'Dental assistants and therapists', 
            'GB_stDentalAssistTherapists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_DENTAL_ASSIST_THERAPISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MED_DENTAL_PROSTHETIC_REL_TECHS_MST_ID), 
            'Medical and dental prosthetic and related technicians', 
            'GB_stMedDentalPostheticRelTechs', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_MED_DENTAL_PROSTHETIC_REL_TECHS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PHARMACISTS_MST_ID), 
            'Pharmacists', 
            'GB_stPharmacists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PHARMACISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PHARM_TECHS_ASSIST_MST_ID), 
            'Pharmaceutical technicians and assistants', 
            'GB_stPharmTechsAssistants', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PHARM_TECHS_ASSIST_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        ))
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PARAMED_PRACTITIONERS_MST_ID), 
            'Paramedical practitioners', 
            'GB_stParamedPractitioners', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PARAMED_PRACTITIONERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        ))
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MED_IMAGING_THERA_EQUIP_TECHS_MST_ID), 
            'Medical imaging and therapeutic equipment technicians', 
            'GB_stMedImagingTherapeuticEquipTechs', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_MED_IMAGING_THERA_EQUIP_TECHS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MED_PATH_LAB_TECHS_MST_ID), 
            'Medical and pathology laboratory technicians', 
            'GB_stMedPathLabTechs', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_MED_PATH_LAB_TECHS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_ENVIRON_OCCUPAT_HEALTH_HYGIENE_PROF_MST_ID), 
            'Environmental and occupational health and hygiene professionals', 
            'GB_stEnvironOccupatHealthHygieneProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_ENVIRON_OCCUPAT_HEALTH_HYGIENE_PROF_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_DIETICIANS_NUTRITIONISTS_MST_ID), 
            'Dieticians and nutritionists', 
            'GB_stDieticiansNutritionists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_DIETICIANS_NUTRITIONISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_AUDIOLOGISTS_SPEECH_THERAPISTS_MST_ID), 
            'Audiologists and speech therapists', 
            'GB_stAudiologistsSpeechTherapists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_AUDIOLOGISTS_SPEECH_THERAPISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_OPTOMETRISTS_OPHTHALMIC_OPTICIANS_MST_ID), 
            'Optometrists and ophthalmic opticians', 
            'GB_stOptometristsOpthalmicOpticians', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_OPTOMETRISTS_OPHTHALMIC_OPTICIANS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_DISPENSING_OPTICIANS_MST_ID), 
            'Dispensing opticians', 
            'GB_stDispensingOpticians', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_DISPENSING_OPTICIANS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_HLTH_PROF_NOT_ELSEWHERE_CLASSIFIED_MST_ID), 
            'Health professionals not elsewhere classified', 
            'GB_stHealthProfNotElsewhereClassified', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_HLTH_PROF_NOT_ELSEWHERE_CLASSIFIED_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_ENVIRON_OCCUPAT_HEALTH_INSPEC_ASSO_MST_ID), 
            'Environmental and occupational health inspectors and associates', 
            'GB_stEnvironOccupatHealthInspectorsAssoc', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_ENVIRON_OCCUPAT_HEALTH_INSPEC_ASSO_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_TRAD_COMP_MED_PROF_MST_ID), 
            'Traditional and complementary medicine professionals', 
            'GB_stTradComplementaryMedicineProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_TRAD_COMP_MED_PROF_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_TRAD_COMP_MED_ASSOC_PROF_MST_ID), 
            'Traditional and complementary medicine associate professionals', 
            'GB_stTraditionalCompMedAssocProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_TRAD_COMP_MED_ASSOC_PROF_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_COMM_HLTH_WORKERS_MST_ID), 
            'Community health workers', 
            'GB_stCommHealthWorkersLowercase', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_COMM_HLTH_WORKERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_HEALTH_CARE_ASSISTS_MST_ID), 
            'Health care assistants', 
            'GB_stHealthCareAssists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_HEALTH_CARE_ASSISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_HOME_BASED_PERS_CARE_WORKERS_MST_ID), 
            'Home-based personal care workers', 
            'GB_stHomeBasedPersCareWorkers', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_HOME_BASED_PERS_CARE_WORKERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PERS_CARE_WORKERS_HEALTH_SERV_NOT_CLASS_MST_ID), 
            'Personal care workers in health services not elsewhere classified', 
            'GB_stPersCareWorkersHealthServNotElseClassified', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PERS_CARE_WORKERS_HEALTH_SERV_NOT_CLASS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PHYSIOTHERAPISTS_MST_ID), 
            'Physiotherapists', 
            'GB_stPhysiotherapists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PHYSIOTHERAPISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PHYSIOTHERAPY_TECHS_ASSISTS_MST_ID), 
            'Physiotherapy technicians and assistants', 
            'GB_stPhysiotherapyTechsAssists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PHYSIOTHERAPY_TECHS_ASSISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MED_REC_HEALTH_INFO_TECHS_MST_ID), 
            'Medical records and health information technicians', 
            'GB_stMedRecHealthInfoTechs', 
            True,
            hwc.HW_HLTH_MGMT_SUPP_PERS_MST_ID,
            hwc.HW_MED_REC_HEALTH_INFO_TECHS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_CLINIC_OFF_SURG_TECHS_MST_ID), 
            'Medical assistants', 
            'GB_stMedAssist', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_CLINIC_OFF_SURG_TECHS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_AMBULANCE_WORKERS_MST_ID), 
            'Ambulance workers', 
            'GB_stAmbulanceWorkers', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_AMBULANCE_WORKERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_HEALTH_ASSOC_PROF_NOT_CLASS_MST_ID), 
            'Health associate professionals not elsewhere classified', 
            'GB_stHealthAssocProfNotElseClassified', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_HEALTH_ASSOC_PROF_NOT_CLASS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_PSYCHOLOGISTS_MST_ID), 
            'Psychologists', 
            'GB_stPsychologists', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_PSYCHOLOGISTS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode 
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_SOCIAL_WORK_COUNSELLING_PROF_MST_ID), 
            'Social work and counselling professionals', 
            'GB_stSpecialWorkCounsProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_SOCIAL_WORK_COUNSELLING_PROF_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_SOCIAL_WORK_ASSOC_PROF_MST_ID), 
            'Social work associate professionals', 
            'GB_stSocialWorkAssocProf', 
            True,
            hwc.HW_HLTH_SERV_PROVIDER_MST_ID,
            hwc.HW_SOCIAL_WORK_ASSOC_PROF_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_BIOMED_ENGINEER_MST_ID), 
            'Biomedical engineer', 
            'GB_stBiomedEngineer', 
            True,
            hwc.HW_HLTH_MGMT_SUPP_PERS_MST_ID,
            hwc.HW_BIOMED_ENGINEER_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_MED_SECRETARIES_MST_ID), 
            'Medical secretaries', 
            'GB_stMedicalSecretaries', 
            True,
            hwc.HW_HLTH_MGMT_SUPP_PERS_MST_ID,
            hwc.HW_MED_SECRETARIES_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_HLTH_SERV_MANAGERS_MST_ID), 
            'Health service managers', 
            'GB_stHealthServManagers', 
            True,
            hwc.HW_HLTH_MGMT_SUPP_PERS_MST_ID,
            hwc.HW_HLTH_SERV_MANAGERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )
    staff_type_records.append(
        HW_create_staff_type_rec(
            str(hwc.HW_AGED_CARE_SERVICE_MANAGERS_MST_ID), 
            'Aged care service managers', 
            'GB_stAgedCareServManagers', 
            True,
            hwc.HW_HLTH_MGMT_SUPP_PERS_MST_ID,
            hwc.HW_AGED_CARE_SERVICE_MANAGERS_MST_ID, 
            num_facility_types, 
            num_years,
            costing_mode
        )
    )

    # Defunct
    # staff_type_dict_list.append(
    #     create_staff_type_dict(
    #         str(hrc.HR_NON_HLTH_PROFESSIONALS_MST_ID), 
    #         'Non-health professionals not elsewhere classified', 
    #         'GB_stNonHealthProfessionals', 
    #         True,
    #         hrc.HR_HLTH_MGMT_SUPP_PERS_MST_ID,
    #         hrc.HR_NON_HLTH_PROFESSIONALS_MST_ID, 
            # num_facility_types, 
            # num_years 
    #     )
    # )
    # staff_type_dict_list.append(
    #     create_staff_type_dict(
    #         str(hrc.HR_NON_HLTH_TECHS_ASSOC_PROF_MST_ID), 
    #         'Non-health technicians and associate professionals not elsewhere classified', 
    #         'GB_stNonHealthTechsAssocProf', 
    #         True,
    #         hrc.HR_HLTH_MGMT_SUPP_PERS_MST_ID,
    #         hrc.HR_NON_HLTH_TECHS_ASSOC_PROF_MST_ID, 
            # num_facility_types, 
            # num_years 
    #     )
    # )
    # staff_type_dict_list.append(
    #     create_staff_type_dict(
    #         str(hrc.HR_CLERICAL_SUPP_WORKERS_MST_ID), 
    #         'Clerical support workers', 
    #         'GB_stClericalSuppWorkers', 
    #         True,
    #         hrc.HR_HLTH_MGMT_SUPP_PERS_MST_ID,
    #         hrc.HR_CLERICAL_SUPP_WORKERS_MST_ID, 
            # num_facility_types, 
            # num_years 
    #     )
    # )
    # staff_type_dict_list.append(
    #     create_staff_type_dict(
    #         str(hrc.HR_PLANT_MACH_OPER_ASSEMB_MST_ID), 
    #         'Plant and machine operators and assemblers', 
    #         'GB_stPlantMachOperAssemb', 
    #         True,
    #         hrc.HR_HLTH_MGMT_SUPP_PERS_MST_ID,
    #         hrc.HR_PLANT_MACH_OPER_ASSEMB_MST_ID, 
            # num_facility_types, 
            # num_years 
    #     )
    # )
    # staff_type_dict_list.append(
    #     create_staff_type_dict(
    #         str(hrc.HR_ELEMENTARY_OCCUPATIONS_MST_ID), 
    #         'Elementary occupations', 
    #         'GB_stElementaryOccupations', 
    #         True,
    #         hrc.HR_HLTH_MGMT_SUPP_PERS_MST_ID,
    #         hrc.HR_ELEMENTARY_OCCUPATIONS_MST_ID, 
            # num_facility_types, 
            # num_years 
    #     )
    # )
    
    return staff_type_records

def HW_init_staff_type_target_setting_methods(staff_type_records):
    staff_type_rec = hwmvu.get_HW_staff_type_rec_from_curr_ID(staff_type_records, hwc.HW_GENERAL_MEDICAL_PRACTITIONERS_CURR_ID)
    hwmvu.set_HW_staff_type_target_setting_method(staff_type_rec, hwc.HW_STAFF_LEVEL_FACILITY_CURR_ID, hwc.HW_EXISTING_PLANS_MST_ID)
    
    staff_type_rec = hwmvu.get_HW_staff_type_rec_from_curr_ID(staff_type_records, hwc.HW_PHARM_TECHS_ASSIST_CURR_ID)
    hwmvu.set_HW_staff_type_target_setting_method(staff_type_rec, hwc.HW_STAFF_LEVEL_NATIONAL_CURR_ID, hwc.HW_EXISTING_PLANS_MST_ID)
    
    staff_type_rec = hwmvu.get_HW_staff_type_rec_from_curr_ID(staff_type_records, hwc.HW_MIDWIFERY_ASSOCIATE_PROFESSIONALS_CURR_ID)
    hwmvu.set_HW_staff_type_target_setting_method(staff_type_rec, hwc.HW_STAFF_LEVEL_REGIONAL_CURR_ID, hwc.HW_EXISTING_PLANS_MST_ID)
    
    # staff_type_rec = hrmvu.get_HR_staff_type_rec_from_curr_ID(staff_type_records, hrc.HR_HLTH_SERV_MANAGERS_CURR_ID)
    # hrmvu.set_HR_staff_type_target_setting_method(staff_type_rec, hrc.HR_STAFF_LEVEL_NATIONAL_CURR_ID, hrc.HR_EXISTING_PLANS_MST_ID)
    
    # staff_type_rec = hrmvu.get_HR_staff_type_rec_from_curr_ID(staff_type_records, hrc.HR_HEALTH_MGMT_PROFESSIONALS_CURR_ID)
    # hrmvu.set_HR_staff_type_target_setting_method(staff_type_rec, hrc.HR_STAFF_LEVEL_REGIONAL_CURR_ID, hrc.HR_EXISTING_PLANS_MST_ID)
    
    # staff_type_rec = hrmvu.get_HR_staff_type_rec_from_curr_ID(staff_type_records, hrc.HR_CLERICAL_SUPP_WORKERS_CURR_ID)
    # hrmvu.set_HR_staff_type_target_setting_method(staff_type_rec, hrc.HR_STAFF_LEVEL_REGIONAL_CURR_ID, hrc.HR_EXISTING_PLANS_MST_ID)
    
    # staff_type_rec = hrmvu.get_HR_staff_type_rec_from_curr_ID(staff_type_records, hrc.HR_PLANT_MACH_OPER_ASSEMB_CURR_ID)
    # hrmvu.set_HR_staff_type_target_setting_method(staff_type_rec, hrc.HR_STAFF_LEVEL_NATIONAL_CURR_ID, hrc.HR_EXISTING_PLANS_MST_ID)

#######################################################################################################
#                                                                                                     #
#                                       In-service training types                                     #
#                                                                                                     #
#######################################################################################################

def HW_create_inserv_training_type_rec(num_years = int):

    return {
        hwmvf.HW_INSERV_TRAIN_STAFF_TYPE_TO_TRAIN    : str(hwc.HW_GENERAL_MEDICAL_PRACTITIONERS_MST_ID),
        hwmvf.HW_INSERV_TRAIN_NAME                   : '',
        hwmvf.HW_INSERV_TRAIN_COST_PER_STAFF_TRAINED : 0.0,
        hwmvf.HW_INSERV_TRAIN_NUM_STAFF_TO_TRAIN     : np.full((num_years), 0).tolist(),   
    }

def HW_init_inserv_train_type_records(num_years):
    inserv_train_type_dict_list = []

    for tt in acu.GBRange(1, hwc.HW_NUM_INSERV_TRAIN_TYPES):
        inserv_train_type_dict = HW_create_inserv_training_type_rec(num_years)
        inserv_train_type_dict_list.append(inserv_train_type_dict)

    return inserv_train_type_dict_list

#######################################################################################################
#                                                                                                     #
#                                       Attrition types                                               #
#                                                                                                     #
#######################################################################################################

def HW_create_attrition_type_rec(ID = str, name = str):

    return {
        hwmvf.HW_ATTRIT_TYPE_ID   : ID,
        hwmvf.HW_ATTRIT_TYPE_NAME : name,
    }

#######################################################################################################
#                                                                                                     #
#                                       Retention incentives                                          #
#                                                                                                     #
#######################################################################################################

def HW_create_retent_incent_rec(ID = str, name = str, num_attrit_types = int):

    retent_incent_dict =  {
        hwmvf.HW_RETENT_INCENT_ID                : ID,
        hwmvf.HW_RETENT_INCENT_NAME              : name,
        hwmvf.HW_RETENT_INCENT_PERC_REDUC_ATTRIT : [],
    }

    if num_attrit_types > 0:
        retent_incent_dict[hwmvf.HW_RETENT_INCENT_PERC_REDUC_ATTRIT] = np.full((num_attrit_types), 0).tolist()

    return retent_incent_dict

########################################################################################################################################
########################################################################################################################################
#                                                                                                                                      #
#                                                       Meta data                                                                      #
#                                                                                                                                      #
########################################################################################################################################
########################################################################################################################################

def HW_init_static_staff_list_meta():
    static_staff_list_meta = []

    for st in acu.GBRange(1, hwc.HW_NUM_STATIC_STAFF_TYPES):
        mst_ID = hwu.get_HW_static_staff_mst_ID(st)

        static_staff_list_meta.append({
            "mstID"          : mst_ID,
            "name"           : hwu.get_HW_static_staff_name(mst_ID),
            "stringConstant" : hwu.get_HW_static_staff_string_constant(mst_ID)
        })
    
    return static_staff_list_meta

#######################################################################################################
#                                                                                                     #
#                                            Results                                                  #
#                                                                                                     #
#######################################################################################################

def HW_init_staff_level_staff_type_year_arr(num_staff_types = int, num_years = int, value = 0.0):
    return np.full((hwc.HW_NUM_STAFFING_LEVELS, num_staff_types, num_years), value, gbc.GB_CALC_FLOAT_TYPE)

def HW_init_staff_level_staff_type_compens_year_arr(num_staff_types = int, num_years = int, value = 0.0):
    return np.full((hwc.HW_NUM_STAFFING_LEVELS, num_staff_types, hwc.HW_NUM_COMPENS_TYPES, num_years), value, gbc.GB_CALC_FLOAT_TYPE)

def HW_init_staff_type_year_arr(num_staff_types = int, num_years = int, value = 0.0):
    return np.full((num_staff_types, num_years), value, gbc.GB_CALC_FLOAT_TYPE)

def HW_init_inserv_train_type_year_arr(num_years = int, value = 0.0):
    return np.full((hwc.HW_NUM_INSERV_TRAIN_TYPES, num_years), value, gbc.GB_CALC_FLOAT_TYPE)