# Extend the class to add Medium Office specific stuff
class OpenStudio::Model::Model
  def define_space_type_map(building_type, template, climate_zone)
    space_type_map = nil
    case template
    when 'NECB 2011'
      # Dom is G
      space_type_map = {
        'Dormitory - living quarters' => ['Floor 1 Anesthesia', 'Floor 1 Bio Haz', 'Floor 1 Cafe',
                                          'Floor 1 Clean', 'Floor 1 Clean Work', 'Floor 1 Dictation',
                                          'Floor 1 Dressing Room', 'Floor 1 Electrical Room', 'Floor 1 Elevator Pump Room',
                                          'Floor 1 Operating Room 1', 'Floor 1 Operating Room 2', 'Floor 1 Operating Room 3',
                                          'Floor 1 Humid', 'Floor 1 IT Hall', 'Floor 1 IT Room', 'Floor 1 Lobby Hall',
                                          'Floor 1 Lobby', 'Floor 1 Lobby Toilet', 'Floor 1 Locker Room Hall',
                                          'Floor 1 Locker Room', 'Floor 1 Lounge', 'Floor 1 Med Gas',
                                          'Floor 1 MRI Control Room', 'Floor 1 MRI Hall', 'Floor 1 MRI Room', 'Floor 1 MRI Toilet',
                                          'Floor 1 Nourishment', 'Floor 1 Nurse Hall', 'Floor 1 Nurse Janitor',
                                          'Floor 1 Nurse Station', 'Floor 1 Nurse Toilet', 'Floor 1 Office',
                                          'Floor 1 PACU', 'Floor 1 Pre-Op Hall', 'Floor 1 Pre-Op Room 1', 'Floor 1 Pre-Op Room 2',
                                          'Floor 1 Pre-Op Toilet', 'Floor 1 Procedure Room', 'Floor 1 Reception Hall',
                                          'Floor 1 Reception', 'Floor 1 Recovery Room', 'Floor 1 Scheduling', 'Floor 1 Scrub',
                                          'Floor 1 Soil Hold', 'Floor 1 Soil', 'Floor 1 Soil Work', 'Floor 1 Step Down',
                                          'Floor 1 Sterile Hall', 'Floor 1 Sterile Storage', 'Floor 1 Storage',
                                          'Floor 1 Sub-Sterile', 'Floor 1 Utility Hall', 'Floor 1 Utility Janitor',
                                          'Floor 1 Utility Room', 'Floor 1 Vestibule', 'Floor 2 Conference',
                                          'Floor 2 Conference Toilet', 'Floor 2 Dictation', 'Floor 2 Exam 1', 'Floor 2 Exam 2',
                                          'Floor 2 Exam 3', 'Floor 2 Exam 4', 'Floor 2 Exam 5', 'Floor 2 Exam 6', 'Floor 2 Exam 7',
                                          'Floor 2 Exam 8', 'Floor 2 Exam 9', 'Floor 2 Exam Hall 1', 'Floor 2 Exam Hall 2',
                                          'Floor 2 Exam Hall 3', 'Floor 2 Exam Hall 4', 'Floor 2 Exam Hall 5',
                                          'Floor 2 Exam Hall 6', 'Floor 2 Janitor', 'Floor 2 Lounge', 'Floor 2 Nurse Station 1',
                                          'Floor 2 Nurse Station 2', 'Floor 2 Office Hall', 'Floor 2 Office', 'Floor 2 Reception Hall',
                                          'Floor 2 Reception', 'Floor 2 Reception Toilet', 'Floor 2 Scheduling 1',
                                          'Floor 2 Scheduling 2', 'Floor 2 Storage 1', 'Floor 2 Storage 2',
                                          'Floor 2 Storage 3', 'Floor 2 Utility', 'Floor 2 Work Hall',
                                          'Floor 2 Work', 'Floor 2 Work Toilet', 'Floor 2 X-Ray', 'Floor 3 Dressing Room',
                                          'Floor 3 Elevator Hall', 'Floor 3 Humid', 'Floor 3 Janitor', 'Floor 3 Locker',
                                          'Floor 3 Lounge', 'Floor 3 Lounge Toilet', 'Floor 3 Mechanical Hall',
                                          'Floor 3 Mechanical', 'Floor 3 Office Hall', 'Floor 3 Office', 'Floor 3 Office Toilet',
                                          'Floor 3 Physical Therapy 1', 'Floor 3 Physical Therapy 2', 'Floor 3 Physical Therapy Toilet',
                                          'Floor 3 Storage 1', 'Floor 3 Storage 2', 'Floor 3 Treatment',
                                          'Floor 3 Undeveloped 1', 'Floor 3 Undeveloped 2',
                                          'Floor 3 Utility', 'Floor 3 Work', 'NE Stair', 'NW Elevator', 'NW Stair', 'SW Stair']
      }
    else
      space_type_map = {
        # 'Floor 1 Anesthesia', 'Floor 1 Bio Haz', 'Floor 1 Cafe', 'Floor 1 Clean', 'Floor 1 Clean Work',
        # 'Floor 1 Dictation', 'Floor 1 Dressing Room', 'Floor 1 Electrical Room', 'Floor 1 Elevator Pump Room',
        # 'Floor 1 Humid', 'Floor 1 IT Hall', 'Floor 1 IT Room', 'Floor 1 Lobby', 'Floor 1 Lobby Hall',
        # 'Floor 1 Lobby Toilet', 'Floor 1 Locker Room', 'Floor 1 Locker Room Hall', 'Floor 1 Lounge',
        # 'Floor 1 Med Gas', 'Floor 1 MRI Control Room', 'Floor 1 MRI Hall', 'Floor 1 MRI Room',
        # 'Floor 1 MRI Toilet', 'Floor 1 Nourishment', 'Floor 1 Nurse Hall', 'Floor 1 Nurse Janitor',
        # 'Floor 1 Nurse Station', 'Floor 1 Nurse Toilet', 'Floor 1 Office', 'Floor 1 Operating Room 1',
        # 'Floor 1 Operating Room 2', 'Floor 1 Operating Room 3', 'Floor 1 PACU', 'Floor 1 Pre-Op Hall',
        # 'Floor 1 Pre-Op Room 1', 'Floor 1 Pre-Op Room 2', 'Floor 1 Pre-Op Toilet', 'Floor 1 Procedure Room',
        # 'Floor 1 Reception', 'Floor 1 Reception Hall', 'Floor 1 Recovery Room', 'Floor 1 Scheduling',
        # 'Floor 1 Scrub', 'Floor 1 Soil', 'Floor 1 Soil Hold', 'Floor 1 Soil Work', 'Floor 1 Step Down',
        # 'Floor 1 Sterile Hall', 'Floor 1 Sterile Storage', 'Floor 1 Storage', 'Floor 1 Sub-Sterile',
        # 'Floor 1 Utility Hall', 'Floor 1 Utility Janitor', 'Floor 1 Utility Room', 'Floor 1 Vestibule',
        # 'Floor 2 Conference', 'Floor 2 Conference Toilet', 'Floor 2 Dictation', 'Floor 2 Exam 1',
        # 'Floor 2 Exam 2', 'Floor 2 Exam 3', 'Floor 2 Exam 4', 'Floor 2 Exam 5', 'Floor 2 Exam 6',
        # 'Floor 2 Exam 7', 'Floor 2 Exam 8', 'Floor 2 Exam 9', 'Floor 2 Exam Hall 1',
        # 'Floor 2 Exam Hall 2', 'Floor 2 Exam Hall 3', 'Floor 2 Exam Hall 4', 'Floor 2 Exam Hall 5',
        # 'Floor 2 Exam Hall 6', 'Floor 2 Janitor', 'Floor 2 Lounge', 'Floor 2 Nurse Station 1',
        # 'Floor 2 Nurse Station 2', 'Floor 2 Office', 'Floor 2 Office Hall', 'Floor 2 Reception',
        # 'Floor 2 Reception Hall', 'Floor 2 Reception Toilet', 'Floor 2 Scheduling 1', 'Floor 2 Scheduling 2',
        # 'Floor 2 Storage 1', 'Floor 2 Storage 2', 'Floor 2 Storage 3', 'Floor 2 Utility', 'Floor 2 Work',
        # 'Floor 2 Work Hall', 'Floor 2 Work Toilet', 'Floor 2 X-Ray', 'Floor 3 Dressing Room',
        # 'Floor 3 Elevator Hall', 'Floor 3 Humid', 'Floor 3 Janitor', 'Floor 3 Locker',
        # 'Floor 3 Lounge', 'Floor 3 Lounge Toilet', 'Floor 3 Mechanical', 'Floor 3 Mechanical Hall',
        # 'Floor 3 Office', 'Floor 3 Office Hall', 'Floor 3 Office Toilet', 'Floor 3 Physical Therapy 1',
        # 'Floor 3 Physical Therapy 2', 'Floor 3 Physical Therapy Toilet', 'Floor 3 Storage 1',
        # 'Floor 3 Storage 2', 'Floor 3 Treatment', 'Floor 3 Undeveloped 1', 'Floor 3 Undeveloped 2',
        # 'Floor 3 Utility', 'Floor 3 Work', 'NE Stair', 'NW Elevator', 'NW Stair', 'SW Stair'

        # TODO: still need to put these into their space types...
        #  all zones mapped

        'Anesthesia' => ['Floor 1 Anesthesia'],
        'BioHazard' => ['Floor 1 Bio Haz'],
        'Cafe' => ['Floor 1 Cafe'],
        'CleanWork' => ['Floor 1 Clean', 'Floor 1 Clean Work'],
        'Conference' => ['Floor 2 Conference'],
        'DressingRoom' => ['Floor 1 Dressing Room', 'Floor 3 Dressing Room'],
        'Elec/MechRoom' => ['Floor 1 Electrical Room', 'Floor 3 Mechanical'],
        'ElevatorPumpRoom' => ['Floor 1 Elevator Pump Room'],
        # 'Floor 3 Treatment' same as 'Exam'
        'Exam' => ['Floor 2 Exam 1', 'Floor 2 Exam 2', 'Floor 2 Exam 3', 'Floor 2 Exam 4', 'Floor 2 Exam 5', 'Floor 2 Exam 6', 'Floor 2 Exam 7',
                   'Floor 2 Exam 8', 'Floor 2 Exam 9', 'Floor 3 Treatment'],
        # 'Floor 1 Scrub', 'Floor 1 Sub-Sterile', 'Floor 1 Vestibule' same as 'Hall'
        'Hall' => ['Floor 1 IT Hall', 'Floor 1 Lobby Hall', 'Floor 1 Locker Room Hall', 'Floor 1 MRI Hall', 'Floor 1 Nurse Hall', 'Floor 1 Pre-Op Hall',
                   'Floor 1 Reception Hall', 'Floor 1 Sterile Hall', 'Floor 2 Exam Hall 1', 'Floor 2 Exam Hall 2', 'Floor 2 Exam Hall 3',
                   'Floor 2 Exam Hall 4', 'Floor 2 Exam Hall 5', 'Floor 2 Exam Hall 6', 'Floor 2 Office Hall', 'Floor 2 Reception Hall', 'Floor 2 Work Hall',
                   'Floor 3 Mechanical Hall', 'Floor 1 Scrub'],
        'Hall_infil' => ['Floor 1 Utility Hall', 'Floor 1 Sub-Sterile', 'Floor 1 Vestibule', 'Floor 3 Elevator Hall', 'Floor 3 Office Hall'],
        'IT_Room' => ['Floor 1 IT Room'],
        # ['Floor 1 Sterile Storage', 'Floor 1 Storage', 'Floor 1 Utility Room', 'Floor 2 Storage 1', 'Floor 2 Storage 2', 'Floor 2 Storage 3', ...
        # 'Floor 2 Utility', 'Floor 3 Storage 1', 'Floor 3 Storage 2', 'Floor 3 Utility'] same as 'Janitor'
        'Janitor' => ['Floor 1 Nurse Janitor', 'Floor 1 Utility Janitor', 'Floor 2 Janitor', 'Floor 3 Janitor', 'Floor 1 Sterile Storage',
                      'Floor 1 Storage', 'Floor 1 Utility Room', 'Floor 2 Storage 1', 'Floor 2 Storage 2', 'Floor 2 Storage 3', 'Floor 2 Utility',
                      'Floor 3 Storage 1', 'Floor 3 Storage 2', 'Floor 3 Utility'],
        'Lobby' => ['Floor 1 Lobby'],
        'LockerRoom' => ['Floor 1 Locker Room', 'Floor 3 Locker'],
        'Lounge' => ['Floor 1 Lounge', 'Floor 2 Lounge', 'Floor 3 Lounge'],
        'MRI' => ['Floor 1 MRI Room'],
        'MRI_Control' => ['Floor 1 MRI Control Room'],
        'MedGas' => ['Floor 1 Med Gas'],
        # 'Floor 1 Nourishment' same as 'NurseStation'
        'NurseStation' => ['Floor 1 Nurse Station', 'Floor 1 Nourishment', 'Floor 2 Nurse Station 1', 'Floor 2 Nurse Station 2'],
        'OR' => ['Floor 1 Operating Room 1', 'Floor 1 Operating Room 2', 'Floor 1 Operating Room 3'],
        # ['Floor 1 Dictation', 'Floor 1 Humid','Floor 1 Scheduling', 'Floor 2 Dictation', 'Floor 2 Scheduling 1', 'Floor 2 Scheduling 2', ...
        # 'Floor 2 Work', 'Floor 3 Humid', 'Floor 3 Work'] same as 'Office', 'IT Room' and 'Dressing Room'
        # TODO 'Floor 2 Work' has slightly different equipment density
        'Office' => ['Floor 1 Office', 'Floor 2 Office', 'Floor 3 Office', 'Floor 1 Dictation', 'Floor 1 Humid', 'Floor 1 Scheduling',
                     'Floor 2 Dictation', 'Floor 2 Scheduling 1', 'Floor 2 Scheduling 2', 'Floor 2 Work', 'Floor 3 Humid', 'Floor 3 Work'],
        # 'Floor 1 Recovery Room' and 'Floor 1 Step Down' same as 'PACU'
        'PACU' => ['Floor 1 PACU', 'Floor 1 Recovery Room', 'Floor 1 Step Down'],
        'PhysicalTherapy' => ['Floor 3 Physical Therapy 1', 'Floor 3 Physical Therapy 2'],
        'PreOp' => ['Floor 1 Pre-Op Room 1', 'Floor 1 Pre-Op Room 2'],
        'ProcedureRoom' => ['Floor 1 Procedure Room'],
        'Soil Work' => ['Floor 1 Soil', 'Floor 1 Soil Hold', 'Floor 1 Soil Work'],
        'Stair' => ['NE Stair', 'NW Stair', 'SW Stair', 'NW Elevator'],
        'Toilet' => ['Floor 1 Nurse Toilet', 'Floor 1 Pre-Op Toilet', 'Floor 1 Lobby Toilet', 'Floor 1 MRI Toilet', 'Floor 2 Conference Toilet',
                     'Floor 2 Reception Toilet', 'Floor 2 Work Toilet', 'Floor 3 Lounge Toilet', 'Floor 3 Office Toilet', 'Floor 3 Physical Therapy Toilet'],
        'Xray' => ['Floor 2 X-Ray'],
        # Add new space type 'Reception'
        'Reception' => ['Floor 1 Reception', 'Floor 2 Reception'],
        # Add new space type 'Undeveloped'
        'Undeveloped' => ['Floor 3 Undeveloped 1', 'Floor 3 Undeveloped 2']
      }
    end

    return space_type_map
  end

  def define_hvac_system_map(building_type, template, climate_zone)
    case template
    when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
      system_to_space_map = [
        {
          'type' => 'PVAV',
          'name' => 'PVAV Outpatient F1',
          'space_names' => [
            'Floor 1 Anesthesia', 'Floor 1 Bio Haz', 'Floor 1 Cafe', 'Floor 1 Clean', 'Floor 1 Clean Work', 'Floor 1 Dictation',
            'Floor 1 Dressing Room', 'Floor 1 Electrical Room', 'Floor 1 Elevator Pump Room', 'Floor 1 Humid', 'Floor 1 IT Hall',
            'Floor 1 IT Room', 'Floor 1 Lobby', 'Floor 1 Lobby Hall', 'Floor 1 Lobby Toilet', 'Floor 1 Locker Room',
            'Floor 1 Locker Room Hall', 'Floor 1 Lounge', 'Floor 1 Med Gas', 'Floor 1 MRI Control Room', 'Floor 1 MRI Hall',
            'Floor 1 MRI Room', 'Floor 1 MRI Toilet', 'Floor 1 Nourishment', 'Floor 1 Nurse Hall', 'Floor 1 Nurse Janitor',
            'Floor 1 Nurse Station', 'Floor 1 Nurse Toilet', 'Floor 1 Office', 'Floor 1 Operating Room 1', 'Floor 1 Operating Room 2',
            'Floor 1 Operating Room 3', 'Floor 1 PACU', 'Floor 1 Pre-Op Hall', 'Floor 1 Pre-Op Room 1', 'Floor 1 Pre-Op Room 2',
            'Floor 1 Pre-Op Toilet', 'Floor 1 Procedure Room', 'Floor 1 Reception', 'Floor 1 Reception Hall', 'Floor 1 Recovery Room',
            'Floor 1 Scheduling', 'Floor 1 Scrub', 'Floor 1 Soil', 'Floor 1 Soil Hold', 'Floor 1 Soil Work', 'Floor 1 Step Down',
            'Floor 1 Sterile Hall', 'Floor 1 Sterile Storage', 'Floor 1 Storage', 'Floor 1 Sub-Sterile', 'Floor 1 Utility Hall',
            'Floor 1 Utility Janitor', 'Floor 1 Utility Room', 'Floor 1 Vestibule'
          ]
        },
        {
          'type' => 'PVAV',
          'name' => 'PVAV Outpatient F2 F3',
          'space_names' => [
            'Floor 2 Conference', 'Floor 2 Conference Toilet', 'Floor 2 Dictation', 'Floor 2 Exam 1', 'Floor 2 Exam 2',
            'Floor 2 Exam 3', 'Floor 2 Exam 4', 'Floor 2 Exam 5', 'Floor 2 Exam 6', 'Floor 2 Exam 7', 'Floor 2 Exam 8',
            'Floor 2 Exam 9', 'Floor 2 Exam Hall 1', 'Floor 2 Exam Hall 2', 'Floor 2 Exam Hall 3', 'Floor 2 Exam Hall 4',
            'Floor 2 Exam Hall 5', 'Floor 2 Exam Hall 6', 'Floor 2 Janitor', 'Floor 2 Lounge', 'Floor 2 Nurse Station 1',
            'Floor 2 Nurse Station 2', 'Floor 2 Office', 'Floor 2 Office Hall', 'Floor 2 Reception', 'Floor 2 Reception Hall',
            'Floor 2 Reception Toilet', 'Floor 2 Scheduling 1', 'Floor 2 Scheduling 2', 'Floor 2 Storage 1', 'Floor 2 Storage 2',
            'Floor 2 Storage 3', 'Floor 2 Utility', 'Floor 2 Work', 'Floor 2 Work Hall', 'Floor 2 Work Toilet', 'Floor 2 X-Ray',
            'Floor 3 Dressing Room', 'Floor 3 Elevator Hall', 'Floor 3 Humid', 'Floor 3 Janitor', 'Floor 3 Locker', 'Floor 3 Lounge',
            'Floor 3 Lounge Toilet', 'Floor 3 Mechanical', 'Floor 3 Mechanical Hall', 'Floor 3 Office', 'Floor 3 Office Hall',
            'Floor 3 Office Toilet', 'Floor 3 Physical Therapy 1', 'Floor 3 Physical Therapy 2', 'Floor 3 Physical Therapy Toilet',
            'Floor 3 Storage 1', 'Floor 3 Storage 2', 'Floor 3 Treatment', 'Floor 3 Undeveloped 1', 'Floor 3 Undeveloped 2',
            'Floor 3 Utility', 'Floor 3 Work', 'NE Stair', 'NW Elevator', 'NW Stair', 'SW Stair'
          ]
        },
        {
          'type' => 'Exhaust Fan',
          'name' => 'Outpatient AHU1 Exhaust Fans',
          'availability_sch_name' => 'OutPatientHealthCare Hours_of_operation',
          'flow_rate' =>
            [
              6.79561743E-02,    # Floor 1 Anesthesia
              4.24726077E-02,    # Floor 1 Lobby Toilet
              0.1586,            # Floor 1 MRI Control Room
              0.4153,            # Floor 1 MRI Room
              4.24726077E-02,    # Floor 1 MRI Toilet
              4.24726077E-02,    # Floor 1 Nurse Toilet
              4.24726077E-02,    # Floor 1 Pre-Op Toilet
              9.91027512E-02,    # Floor 1 Soil
              4.40456672E-02,    # Floor 1 Soil Hold
              1.41575359E-01,    # Floor 1 Soil Work
            ],
          'flow_fraction_schedule_name' => nil,
          'balanced_exhaust_fraction_schedule_name' => nil,
          'space_names' =>
            [
              'Floor 1 Anesthesia',
              'Floor 1 Lobby Toilet',
              'Floor 1 MRI Control Room',
              'Floor 1 MRI Room',
              'Floor 1 MRI Toilet',
              'Floor 1 Nurse Toilet',
              'Floor 1 Pre-Op Toilet',
              'Floor 1 Soil',
              'Floor 1 Soil Hold',
              'Floor 1 Soil Work'
            ]
        },
        {
          'type' => 'Exhaust Fan',
          'name' => 'Outpatient AHU2&3 Exhaust Fans',
          'availability_sch_name' => 'OutPatientHealthCare BLDG_OA_SCH',
          'flow_rate' =>
            [
              5.03379054E-02,    # Floor 2 Conference Toilet
              9.91027512E-02,    # Floor 2 Reception Toilet
              4.24726077E-02,    # Floor 2 Work Toilet
              0.8495,            # Floor 2 X-Ray
              1.51013716E-01,    # Floor 3 Lounge Toilet
              4.24726077E-02,    # Floor 3 Office Toilet
              6.60685008E-02,    # Floor 3 Physical Therapy Toilet
            ],
          'flow_fraction_schedule_name' => nil,
          'balanced_exhaust_fraction_schedule_name' => nil,
          'space_names' =>
            [
              'Floor 2 Conference Toilet',
              'Floor 2 Reception Toilet',
              'Floor 2 Work Toilet',
              'Floor 2 X-Ray',
              'Floor 3 Lounge Toilet',
              'Floor 3 Office Toilet',
              'Floor 3 Physical Therapy Toilet'
            ]
        }

      ]

    when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
      system_to_space_map = [
        {
          'type' => 'PVAV',
          'name' => 'PVAV Outpatient F1',
          'space_names' => [
            'Floor 1 Anesthesia', 'Floor 1 Bio Haz', 'Floor 1 Cafe', 'Floor 1 Clean', 'Floor 1 Clean Work', 'Floor 1 Dictation',
            'Floor 1 Dressing Room', 'Floor 1 Humid', 'Floor 1 IT Hall',
            'Floor 1 IT Room', 'Floor 1 Lobby', 'Floor 1 Lobby Hall', 'Floor 1 Locker Room',
            'Floor 1 Locker Room Hall', 'Floor 1 Lounge', 'Floor 1 Med Gas', 'Floor 1 MRI Control Room', 'Floor 1 MRI Hall',
            'Floor 1 MRI Room', 'Floor 1 Nourishment', 'Floor 1 Nurse Hall',
            'Floor 1 Nurse Station', 'Floor 1 Office', 'Floor 1 Operating Room 1', 'Floor 1 Operating Room 2',
            'Floor 1 Operating Room 3', 'Floor 1 PACU', 'Floor 1 Pre-Op Hall', 'Floor 1 Pre-Op Room 1', 'Floor 1 Pre-Op Room 2',
            'Floor 1 Procedure Room', 'Floor 1 Reception', 'Floor 1 Reception Hall', 'Floor 1 Recovery Room',
            'Floor 1 Scheduling', 'Floor 1 Scrub', 'Floor 1 Soil', 'Floor 1 Soil Hold', 'Floor 1 Soil Work', 'Floor 1 Step Down',
            'Floor 1 Sterile Hall', 'Floor 1 Sterile Storage', 'Floor 1 Sub-Sterile', 'Floor 1 Utility Hall',
            'Floor 1 Vestibule'
          ]
        },
        {
          'type' => 'PVAV',
          'name' => 'PVAV Outpatient F2 F3',
          'space_names' => [
            'Floor 2 Conference', 'Floor 2 Dictation', 'Floor 2 Exam 1', 'Floor 2 Exam 2',
            'Floor 2 Exam 3', 'Floor 2 Exam 4', 'Floor 2 Exam 5', 'Floor 2 Exam 6', 'Floor 2 Exam 7', 'Floor 2 Exam 8',
            'Floor 2 Exam 9', 'Floor 2 Exam Hall 1', 'Floor 2 Exam Hall 2', 'Floor 2 Exam Hall 3', 'Floor 2 Exam Hall 4',
            'Floor 2 Exam Hall 5', 'Floor 2 Exam Hall 6', 'Floor 2 Lounge', 'Floor 2 Nurse Station 1',
            'Floor 2 Nurse Station 2', 'Floor 2 Office', 'Floor 2 Office Hall', 'Floor 2 Reception', 'Floor 2 Reception Hall',
            'Floor 2 Scheduling 1', 'Floor 2 Scheduling 2',
            'Floor 2 Work', 'Floor 2 Work Hall', 'Floor 2 X-Ray',
            'Floor 3 Dressing Room', 'Floor 3 Elevator Hall', 'Floor 3 Humid', 'Floor 3 Locker', 'Floor 3 Lounge',
            'Floor 3 Mechanical Hall', 'Floor 3 Office', 'Floor 3 Office Hall',
            'Floor 3 Physical Therapy 1', 'Floor 3 Physical Therapy 2',
            'Floor 3 Treatment', 'Floor 3 Work'
          ]
        },
        {
          'type' => 'Exhaust Fan',
          'name' => 'Outpatient AHU1 Exhaust Fans',
          'availability_sch_name' => 'OutPatientHealthCare AHU1-Fan_Pre2004',
          'flow_rate' =>
            [
              0.068,      # Floor 1 Anesthesia
              0.0793,     # Floor 1 MRI Control Room
              0.2077,     # Floor 1 MRI Room
              0.0991,     # Floor 1 Soil
              0.044,      # Floor 1 Soil Hold
              0.1416,     # Floor 1 Soil Work
            ],
          'flow_fraction_schedule_name' => nil,
          'balanced_exhaust_fraction_schedule_name' => nil,
          'space_names' =>
            [
              'Floor 1 Anesthesia',
              'Floor 1 MRI Control Room',
              'Floor 1 MRI Room',
              'Floor 1 Soil',
              'Floor 1 Soil Hold',
              'Floor 1 Soil Work'
            ]
        }
      ]
    end

    return system_to_space_map
  end

  def custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
    OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding HVAC')

    system_to_space_map = define_hvac_system_map(building_type, template, climate_zone)

    # add elevator for the elevator pump room (the fan&lights are already added via standard spreadsheet)
    add_extra_equip_elevator_pump_room(template)
    # adjust cooling setpoint at vintages 1B,2B,3B
    adjust_clg_setpoint(template, climate_zone)
    # Get the hot water loop
    hot_water_loop = nil
    getPlantLoops.each do |loop|
      # If it has a boiler:hotwater, it is the correct loop
      unless loop.supplyComponents('OS:Boiler:HotWater'.to_IddObjectType).empty?
        hot_water_loop = loop
      end
    end
    # add humidifier to AHU1 (contains operating room 1)
    if hot_water_loop
      add_humidifier(template, hot_water_loop)
    else
      OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', 'Could not find hot water loop to attach humidifier to.')
    end
    # adjust infiltration for vintages 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
    adjust_infiltration(template)
    # add door infiltration for vertibule
    add_door_infiltration(template, climate_zone)
    # reset boiler sizing factor to 0.3 (default 1)
    reset_boiler_sizing_factor
    # assign the minimum total air changes to the cooling minimum air flow in Sizing:Zone
    apply_minimum_total_ach(building_type, template)

    OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding HVAC')

    return true
  end

  def add_extra_equip_elevator_pump_room(template)
    elevator_pump_room = getSpaceByName('Floor 1 Elevator Pump Room').get
    elec_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(self)
    elec_equip_def.setName('Elevator Pump Room Electric Equipment Definition')
    elec_equip_def.setFractionLatent(0)
    elec_equip_def.setFractionRadiant(0.1)
    elec_equip_def.setFractionLost(0.9)
    elec_equip_def.setDesignLevel(48_165)
    elec_equip = OpenStudio::Model::ElectricEquipment.new(elec_equip_def)
    elec_equip.setName('Elevator Pump Room Elevator Equipment')
    elec_equip.setSpace(elevator_pump_room)
    case template
    when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
      elec_equip.setSchedule(add_schedule('OutPatientHealthCare BLDG_ELEVATORS'))
    when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
      elec_equip.setSchedule(add_schedule('OutPatientHealthCare BLDG_ELEVATORS_Pre2004'))
    end
    return true
  end

  def adjust_clg_setpoint(template, climate_zone)
    getSpaceTypes.sort.each do |space_type|
      space_type_name = space_type.name.get
      thermostat_name = space_type_name + ' Thermostat'
      thermostat = getThermostatSetpointDualSetpointByName(thermostat_name).get
      case template
      when '90.1-2004', '90.1-2007', '90.1-2010'
        case climate_zone
        when 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-3B'
          thermostat.setCoolingSetpointTemperatureSchedule(add_schedule('OutPatientHealthCare CLGSETP_SCH_YES_OPTIMUM'))
        end
      end
    end
    return true
  end

  def adjust_infiltration(template)
    case template
    when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
      getSpaces.sort.each do |space|
        space_type = space.spaceType.get
        # Skip interior spaces
        next if space.exterior_wall_and_window_area <= 0
        # Skip spaces that have no infiltration objects to adjust
        next if space_type.spaceInfiltrationDesignFlowRates.size <= 0

        # get the infiltration information from the space type infiltration
        infiltration_space_type = space_type.spaceInfiltrationDesignFlowRates[0]
        infil_sch = infiltration_space_type.schedule.get
        infil_rate = nil
        infil_ach = nil
        if infiltration_space_type.flowperExteriorWallArea.is_initialized
          infil_rate = infiltration_space_type.flowperExteriorWallArea.get
        elsif infiltration_space_type.airChangesperHour.is_initialized
          infil_ach = infiltration_space_type.airChangesperHour.get
        end
        # Create an infiltration rate object for this space
        infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
        infiltration.setName("#{space.name} Infiltration")
        infiltration.setFlowperExteriorSurfaceArea(infil_rate) unless infil_rate.nil? || infil_rate.to_f.zero?
        infiltration.setAirChangesperHour(infil_ach) unless infil_ach.nil? || infil_ach.to_f.zero?
        infiltration.setSchedule(infil_sch)
        infiltration.setSpace(space)
      end
      getSpaceTypes.each do |space_type|
        space_type.spaceInfiltrationDesignFlowRates.each(&:remove)
      end
    else
      return true
    end
  end

  def add_door_infiltration(template, climate_zone)
    # add extra infiltration for vestibule door
    case template
    when 'DOE Ref 1980-2004', 'DOE Ref Pre-1980'
      return true
    else
      vestibule_space = getSpaceByName('Floor 1 Vestibule').get
      infiltration_vestibule_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
      infiltration_vestibule_door.setName('Vestibule door Infiltration')
      infiltration_rate_vestibule_door = 0
      case template
      when '90.1-2004'
        infiltration_rate_vestibule_door = 1.186002811
        infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
      when '90.1-2007', '90.1-2010', '90.1-2013'
        case climate_zone
        when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B'
          infiltration_rate_vestibule_door = 1.186002811
          infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
        else
          infiltration_rate_vestibule_door = 0.776824762
          infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.131'))
        end
      end
      infiltration_vestibule_door.setDesignFlowRate(infiltration_rate_vestibule_door)
      infiltration_vestibule_door.setSpace(vestibule_space)
    end
  end

  def update_waterheater_loss_coefficient(template)
    case template
    when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', 'NECB 2011'
      getWaterHeaterMixeds.sort.each do |water_heater|
        if water_heater.name.to_s.include?('Booster')
          water_heater.setOffCycleLossCoefficienttoAmbientTemperature(1.053159296)
          water_heater.setOnCycleLossCoefficienttoAmbientTemperature(1.053159296)
        else
          water_heater.setOffCycleLossCoefficienttoAmbientTemperature(9.643286505)
          water_heater.setOnCycleLossCoefficienttoAmbientTemperature(9.643286505)
        end
      end
    end
  end

  # add humidifier to AHU1 (contains operating room1)
  def add_humidifier(template, hot_water_loop)
    operatingroom1_space = getSpaceByName('Floor 1 Operating Room 1').get
    operatingroom1_zone = operatingroom1_space.thermalZone.get
    humidistat = OpenStudio::Model::ZoneControlHumidistat.new(self)
    humidistat.setHumidifyingRelativeHumiditySetpointSchedule(add_schedule('OutPatientHealthCare MinRelHumSetSch'))
    humidistat.setDehumidifyingRelativeHumiditySetpointSchedule(add_schedule('OutPatientHealthCare MaxRelHumSetSch'))
    operatingroom1_zone.setZoneControlHumidistat(humidistat)
    getAirLoopHVACs.each do |air_loop|
      if air_loop.thermalZones.include? operatingroom1_zone
        humidifier = OpenStudio::Model::HumidifierSteamElectric.new(self)
        humidifier.setRatedCapacity(3.72E-5)
        humidifier.setRatedPower(100_000)
        humidifier.setName("#{air_loop.name.get} Electric Steam Humidifier")
        # get the water heating coil and add humidifier to the outlet of heating coil (right before fan)
        htg_coil = nil
        air_loop.supplyComponents.each do |equip|
          if equip.to_CoilHeatingWater.is_initialized
            htg_coil = equip.to_CoilHeatingWater.get
          end
        end
        heating_coil_outlet_node = htg_coil.airOutletModelObject.get.to_Node.get
        supply_outlet_node = air_loop.supplyOutletNode
        humidifier.addToNode(heating_coil_outlet_node)
        humidity_spm = OpenStudio::Model::SetpointManagerSingleZoneHumidityMinimum.new(self)
        case template
        when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
          extra_elec_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self, alwaysOnDiscreteSchedule)
          extra_elec_htg_coil.setName('AHU1 extra Electric Htg Coil')
          extra_water_htg_coil = OpenStudio::Model::CoilHeatingWater.new(self, alwaysOnDiscreteSchedule)
          extra_water_htg_coil.setName('AHU1 extra Water Htg Coil')
          hot_water_loop.addDemandBranchForComponent(extra_water_htg_coil)
          extra_elec_htg_coil.addToNode(supply_outlet_node)
          extra_water_htg_coil.addToNode(supply_outlet_node)
        end
        # humidity_spm.addToNode(supply_outlet_node)
        humidity_spm.addToNode(humidifier.outletModelObject.get.to_Node.get)
        humidity_spm.setControlZone(operatingroom1_zone)
      end
    end
  end

  # for 90.1-2010 Outpatient, AHU2 set minimum outdoor air flow rate as 0
  # AHU1 doesn't have economizer
  def modify_oa_controller(template)
    getAirLoopHVACs.each do |air_loop|
      oa_system = air_loop.airLoopHVACOutdoorAirSystem.get
      controller_oa = oa_system.getControllerOutdoorAir
      controller_mv = controller_oa.controllerMechanicalVentilation
      # AHU1 OA doesn't have controller:mechanicalventilation
      if air_loop.name.to_s.include? 'Outpatient F1'
        controller_mv.setAvailabilitySchedule(alwaysOffDiscreteSchedule)
        # add minimum fraction of outdoor air schedule to AHU1
        controller_oa.setMinimumFractionofOutdoorAirSchedule(add_schedule('OutPatientHealthCare AHU-1_OAminOAFracSchedule'))
      # for AHU2, at vintages '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', the minimum OA schedule is not the same as
      # airloop availability schedule, but separately assigned.
      elsif template == '90.1-2004' || template == '90.1-2007' || template == '90.1-2010' || template == '90.1-2013'
        controller_oa.setMinimumOutdoorAirSchedule(add_schedule('OutPatientHealthCare BLDG_OA_SCH'))
        # add minimum fraction of outdoor air schedule to AHU2
        controller_oa.setMinimumFractionofOutdoorAirSchedule(add_schedule('OutPatientHealthCare BLDG_OA_FRAC_SCH'))
      end
    end
  end

  # For operating room 1&2 in 2010 and 2013, VAV minimum air flow is set by schedule
  def reset_or_room_vav_minimum_damper(prototype_input, template)
    case template
    when '90.1-2004', '90.1-2007'
      return true
    when '90.1-2010', '90.1-2013'
      getAirTerminalSingleDuctVAVReheats.sort.each do |airterminal|
        airterminal_name = airterminal.name.get
        if airterminal_name.include?('Floor 1 Operating Room 1') || airterminal_name.include?('Floor 1 Operating Room 2')
          airterminal.setZoneMinimumAirFlowMethod('Scheduled')
          airterminal.setMinimumAirFlowFractionSchedule(add_schedule('OutPatientHealthCare OR_MinSA_Sched'))
        end
      end
    end
  end

  def reset_boiler_sizing_factor
    getBoilerHotWaters.sort.each do |boiler|
      boiler.setSizingFactor(0.3)
    end
  end

  def update_exhaust_fan_efficiency(template)
    case template
    when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
      getFanZoneExhausts.sort.each do |exhaust_fan|
        fan_name = exhaust_fan.name.to_s
        if (fan_name.include? 'X-Ray') || (fan_name.include? 'MRI Room')
          exhaust_fan.setFanEfficiency(0.16)
          exhaust_fan.setPressureRise(125)
        else
          exhaust_fan.setFanEfficiency(0.31)
          exhaust_fan.setPressureRise(249)
        end
      end
    when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
      getFanZoneExhausts.sort.each do |exhaust_fan|
        exhaust_fan.setFanEfficiency(0.338)
        exhaust_fan.setPressureRise(125)
      end
    end
  end

  # assign the minimum total air changes to the cooling minimum air flow in Sizing:Zone
  def apply_minimum_total_ach(building_type, template)
    getSpaces.each do |space|
      space_type_name = space.spaceType.get.standardsSpaceType.get
      search_criteria = {
        'template' => template,
        'building_type' => building_type,
        'space_type' => space_type_name
      }
      data = find_object($os_standards['space_types'], search_criteria)

      # skip space type without minimum total air changes
      next if data['minimum_total_air_changes'].nil?

      # calculate the minimum total air flow
      minimum_total_ach = data['minimum_total_air_changes'].to_f
      space_volume = space.volume
      space_area = space.floorArea
      minimum_airflow_per_zone = minimum_total_ach * space_volume / 3600
      minimum_airflow_per_zone_floor_area = minimum_airflow_per_zone / space_area
      # add minimum total air flow limit to sizing:zone
      zone = space.thermalZone.get
      sizingzone = zone.sizingZone
      sizingzone.setCoolingDesignAirFlowMethod('DesignDayWithLimit')
      case template
      when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
        sizingzone.setCoolingMinimumAirFlow(minimum_airflow_per_zone)
      when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
        sizingzone.setCoolingMinimumAirFlowperZoneFloorArea(minimum_airflow_per_zone_floor_area)
      end
    end
  end

  def custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
    update_waterheater_loss_coefficient(template)

    return true
  end
end