TEST_F(EnergyPlusFixture,ForwardTranslator_LifeCycleCostParameters)
{
  Model model;
  LifeCycleCostParameters lifeCycleCostParameters = model.getUniqueModelObject<LifeCycleCostParameters>();

  ForwardTranslator ft;
  Workspace workspace = ft.translateModelObject(lifeCycleCostParameters);
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_Parameters).size());
  EXPECT_EQ(5u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_UsePriceEscalation).size());

  const char *c_regions[] = {"U.S. Avg", "NorthEast", "MidWest", "South", "West"};
  const char *c_sectors[] = {"Commercial", "Residential", "Industrial"};

  std::vector<std::string> regions(c_regions, c_regions + 5); 
  std::vector<std::string> sectors(c_sectors, c_sectors + 3); 
  EXPECT_EQ(5u, regions.size());
  EXPECT_EQ(3u, sectors.size());

  EXPECT_TRUE(lifeCycleCostParameters.setUseNISTFuelEscalationRates(true));

  for (const std::string& region : regions){
    for (const std::string& sector : sectors){
      EXPECT_TRUE(lifeCycleCostParameters.setNISTRegion(region));
      EXPECT_TRUE(lifeCycleCostParameters.setNISTSector(sector));

      unsigned numExpected = 5;
      if (sector == "Residential"){
        numExpected = 4;
      }

      workspace = ft.translateModelObject(lifeCycleCostParameters);
      EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_Parameters).size());
      EXPECT_EQ(numExpected, workspace.getObjectsByType(IddObjectType::LifeCycleCost_UsePriceEscalation).size()) << region << " " << sector;
    }
  }

  EXPECT_TRUE(lifeCycleCostParameters.setUseNISTFuelEscalationRates(false));

  workspace = ft.translateModelObject(lifeCycleCostParameters);
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_Parameters).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_UsePriceEscalation).size());

  EXPECT_TRUE(lifeCycleCostParameters.setElectricityInflation(0.01));

  workspace = ft.translateModelObject(lifeCycleCostParameters);
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_Parameters).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::LifeCycleCost_UsePriceEscalation).size());
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateConstruction) {
  openstudio::model::Model model;

  openstudio::model::StandardOpaqueMaterial mat1(model);
  mat1.setName("test layer0");
  mat1.setRoughness("MediumRough");
  mat1.setThickness(0.02);
  mat1.setThermalConductivity(1.5);
  mat1.setDensity(20.0);
  mat1.setSpecificHeat(2.0);

  openstudio::model::StandardOpaqueMaterial mat2(model);
  mat2.setName("test layer1");
  mat2.setRoughness("MediumSmooth");
  mat2.setThickness(0.005);
  mat2.setThermalConductivity(0.3);
  mat2.setDensity(3.0);
  mat2.setSpecificHeat(0.3);

  openstudio::model::Construction construction(model);
  construction.setName("test construction");
  construction.insertLayer(0, mat1);
  construction.insertLayer(1, mat2);

  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(construction);
  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Construction));

  IdfObject constructionIdf = workspace.getObjectsByType(IddObjectType::Construction)[0];

  EXPECT_EQ(unsigned(3), constructionIdf.numFields());
  EXPECT_EQ("test construction", *(constructionIdf.name()) );
  EXPECT_EQ("test layer0", *(constructionIdf.getString(1)) );
  EXPECT_EQ("test layer1", *(constructionIdf.getString(2)) );
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateStandardOpaqueMaterial) {
  openstudio::model::Model model;
  openstudio::model::StandardOpaqueMaterial mat(model);

  mat.setName("Test Material");
  mat.setRoughness("Rough");
  mat.setThickness(0.0125);
  mat.setThermalConductivity(0.5);
  mat.setDensity(3.5);
  mat.setSpecificHeat(2.5);
  mat.setThermalAbsorptance(0.9);
  mat.setSolarAbsorptance(0.7);
  mat.setVisibleAbsorptance(0.7);

  
  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(mat);

  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Material));

  openstudio::IdfObject matIdf = workspace.getObjectsByType(IddObjectType::Material)[0];

  EXPECT_EQ(unsigned(9), matIdf.numFields());

  EXPECT_EQ( "Test Material", *(matIdf.name()) );
  EXPECT_EQ( "Rough", *(matIdf.getString(1)) );
  EXPECT_EQ( 0.0125, *(matIdf.getDouble(2)) );
  EXPECT_EQ( 0.5, *(matIdf.getDouble(3)) );
  EXPECT_EQ( 3.5, *(matIdf.getDouble(4)) );
  EXPECT_EQ( 2.5, *(matIdf.getDouble(5)) );
  EXPECT_EQ( 0.9, *(matIdf.getDouble(6)) );
  EXPECT_EQ( 0.7, *(matIdf.getDouble(7)) );
  EXPECT_EQ( 0.7, *(matIdf.getDouble(8)) );
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateScheduleCompact) {
  openstudio::model::Model model;

  openstudio::model::ScheduleCompact scheduleCompact(model);

  scheduleCompact.setName("Daytime Ventilation");

  scheduleCompact.setString(2,"Fraction");
  scheduleCompact.setString(3,"Through: 12/31");
  scheduleCompact.setString(4,"For: Weekdays SummerDesignDay");
  scheduleCompact.setString(5,"Until: 08:00");
  scheduleCompact.setString(6,"0.0");
  scheduleCompact.setString(7,"Until: 18:00");
  scheduleCompact.setString(8,"1.0");
  scheduleCompact.setString(9,"Until: 24:00");
  scheduleCompact.setString(10,"0.0");
  scheduleCompact.setString(11,"For: Weekends WinterDesignDay");
  scheduleCompact.setString(12,"Until: 10:00");
  scheduleCompact.setString(13,"0.0");
  scheduleCompact.setString(14,"Until: 16:00");
  scheduleCompact.setString(15,"1.0");
  scheduleCompact.setString(16,"Until: 24:00");
  scheduleCompact.setString(17,"0.0");
  scheduleCompact.setString(18,"For: Holidays AllOtherDays");
  scheduleCompact.setString(19,"Until: 24:00");
  scheduleCompact.setString(20,"0.0");


  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(scheduleCompact);
  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Schedule_Compact));

  openstudio::IdfObject scheduleCompactIdf = workspace.getObjectsByType(IddObjectType::Schedule_Compact)[0];

  EXPECT_EQ(20u,scheduleCompactIdf.numFields());
  EXPECT_EQ(21u,scheduleCompact.numFields());

  ASSERT_EQ(scheduleCompactIdf.numFields() + 1,scheduleCompact.numFields());

  ASSERT_TRUE(scheduleCompact.name());
  ASSERT_TRUE(scheduleCompactIdf.name());
  EXPECT_EQ(scheduleCompact.name().get(),scheduleCompactIdf.name().get());

  for( unsigned i = OS_Schedule_CompactFields::getValues().size(); i < scheduleCompact.numFields(); i++ )
  {
    boost::optional<std::string> s1 = scheduleCompactIdf.getString(i-1);
    boost::optional<std::string> s2 = scheduleCompact.getString(i);

    ASSERT_TRUE(s1);
    ASSERT_TRUE(s2);

    EXPECT_EQ(s1.get(),s2.get());
  }
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateSiteWaterMainsTemperature) {
  openstudio::model::Model model;
  openstudio::model::SiteWaterMainsTemperature watertemp = model.getUniqueModelObject<openstudio::model::SiteWaterMainsTemperature>();

  watertemp.setAnnualAverageOutdoorAirTemperature(9.69);
  watertemp.setMaximumDifferenceInMonthlyAverageOutdoorAirTemperatures(28.1);

  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(watertemp);
  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Site_WaterMainsTemperature));
    
  IdfObject watertempIdf = workspace.getObjectsByType(IddObjectType::Site_WaterMainsTemperature)[0];
  EXPECT_EQ(unsigned(4), watertempIdf.numFields());

  EXPECT_EQ( "Correlation", *(watertempIdf.getString(0)) );
  EXPECT_EQ( "", *(watertempIdf.getString(1)) );
  EXPECT_EQ( 9.69, *(watertempIdf.getDouble(2)) );
  EXPECT_EQ( 28.1, *(watertempIdf.getDouble(3)) );
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateSite) {
  openstudio::model::Model model;
  openstudio::model::Site site = model.getUniqueModelObject<openstudio::model::Site>();

  site.setName("Test Site");
  site.setLatitude(39.6);
  site.setLongitude(105.2);
  site.setTimeZone(-7.0);
  site.setElevation(1729.74);

  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(site);
  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Site_Location));
    
  IdfObject siteIdf = workspace.getObjectsByType(IddObjectType::Site_Location)[0];
  EXPECT_EQ(unsigned(5), siteIdf.numFields());

  EXPECT_EQ( "Test Site", *(siteIdf.name()) );
  EXPECT_EQ( 39.6, *(siteIdf.getDouble(1)) );
  EXPECT_EQ( 105.2, *(siteIdf.getDouble(2)) );
  EXPECT_EQ( -7.0, *(siteIdf.getDouble(3)) );
  EXPECT_EQ( 1729.74, *(siteIdf.getDouble(4)) );
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateSiteGroundTemperatureBuildingSurface) {
  openstudio::model::Model model;
  openstudio::model::SiteGroundTemperatureBuildingSurface groundtemp = model.getUniqueModelObject<openstudio::model::SiteGroundTemperatureBuildingSurface>();

  groundtemp.setJanuaryGroundTemperature(19.527);
  groundtemp.setFebruaryGroundTemperature(19.502);
  groundtemp.setMarchGroundTemperature(19.536);
  groundtemp.setAprilGroundTemperature(19.598);
  groundtemp.setMayGroundTemperature(20.002);
  groundtemp.setJuneGroundTemperature(21.64);
  groundtemp.setJulyGroundTemperature(22.225);
  groundtemp.setAugustGroundTemperature(22.375);
  groundtemp.setSeptemberGroundTemperature(21.449);
  groundtemp.setOctoberGroundTemperature(20.121);
  groundtemp.setNovemberGroundTemperature(19.802);
  groundtemp.setDecemberGroundTemperature(19.633);

  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(groundtemp);
  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Site_GroundTemperature_BuildingSurface));
    
  IdfObject groundtempIdf = workspace.getObjectsByType(IddObjectType::Site_GroundTemperature_BuildingSurface)[0];
  EXPECT_EQ(unsigned(12), groundtempIdf.numFields());

  EXPECT_EQ( 19.527, *(groundtempIdf.getDouble(0)) );
  EXPECT_EQ( 19.502, *(groundtempIdf.getDouble(1)) );
  EXPECT_EQ( 19.536, *(groundtempIdf.getDouble(2)) );
  EXPECT_EQ( 19.598, *(groundtempIdf.getDouble(3)) );
  EXPECT_EQ( 20.002, *(groundtempIdf.getDouble(4)) );
  EXPECT_EQ( 21.64, *(groundtempIdf.getDouble(5)) );
  EXPECT_EQ( 22.225, *(groundtempIdf.getDouble(6)) );
  EXPECT_EQ( 22.375, *(groundtempIdf.getDouble(7)) );
  EXPECT_EQ( 21.449, *(groundtempIdf.getDouble(8)) );
  EXPECT_EQ( 20.121, *(groundtempIdf.getDouble(9)) );
  EXPECT_EQ( 19.802, *(groundtempIdf.getDouble(10)) );
  EXPECT_EQ( 19.633, *(groundtempIdf.getDouble(11)) );
}
TEST_F(EnergyPlusFixture,ForwardTranslatorTest_TranslateSiteGroundReflectance) {
  openstudio::model::Model model;
  openstudio::model::SiteGroundReflectance groundreflect = model.getUniqueModelObject<openstudio::model::SiteGroundReflectance>();

  groundreflect.setJanuaryGroundReflectance(0.11);
  groundreflect.setFebruaryGroundReflectance(0.12);
  groundreflect.setMarchGroundReflectance(0.13);
  groundreflect.setAprilGroundReflectance(0.14);
  groundreflect.setMayGroundReflectance(0.15);
  groundreflect.setJuneGroundReflectance(0.16);
  groundreflect.setJulyGroundReflectance(0.17);
  groundreflect.setAugustGroundReflectance(0.18);
  groundreflect.setSeptemberGroundReflectance(0.19);
  groundreflect.setOctoberGroundReflectance(0.20);
  groundreflect.setNovemberGroundReflectance(0.21);
  groundreflect.setDecemberGroundReflectance(0.22);

  ForwardTranslator trans;
  Workspace workspace = trans.translateModelObject(groundreflect);
  ASSERT_EQ(1u, workspace.numObjectsOfType(IddObjectType::Site_GroundReflectance));
    
  IdfObject groundreflectIdf = workspace.getObjectsByType(IddObjectType::Site_GroundReflectance)[0];
  EXPECT_EQ(unsigned(12), groundreflectIdf.numFields());

  EXPECT_EQ( 0.11, *(groundreflectIdf.getDouble(0)) );
  EXPECT_EQ( 0.12, *(groundreflectIdf.getDouble(1)) );
  EXPECT_EQ( 0.13, *(groundreflectIdf.getDouble(2)) );
  EXPECT_EQ( 0.14, *(groundreflectIdf.getDouble(3)) );
  EXPECT_EQ( 0.15, *(groundreflectIdf.getDouble(4)) );
  EXPECT_EQ( 0.16, *(groundreflectIdf.getDouble(5)) );
  EXPECT_EQ( 0.17, *(groundreflectIdf.getDouble(6)) );
  EXPECT_EQ( 0.18, *(groundreflectIdf.getDouble(7)) );
  EXPECT_EQ( 0.19, *(groundreflectIdf.getDouble(8)) );
  EXPECT_EQ( 0.20, *(groundreflectIdf.getDouble(9)) );
  EXPECT_EQ( 0.21, *(groundreflectIdf.getDouble(10)) );
  EXPECT_EQ( 0.22, *(groundreflectIdf.getDouble(11)) );
}