bool SurfaceNetworkBuilder::linkInteriorSubSurface(model::ThermalZone zone, model::Space space, model::Surface surface, model::SubSurface subSurface,
  model::SubSurface adjacentSubSurface, model::Surface adjacentSurface, model::Space adjacentSpace, model::ThermalZone adjacentZone)
{
  LOG(Info, "Subsurfaces '" << subSurface.name().get() << "' and '" << adjacentSubSurface.name().get() << "' connect zone '"
    << zone.name().get() << "' to zone '" << adjacentZone.name().get() << "'");
  return true;
}
void SubSurfaceConstructionVectorController::attachOtherModelObjects(const model::SubSurface& subSurface)
{
  boost::optional<model::Surface> surface = subSurface.surface();
  if (surface){
    attachOtherModelObjects(*surface);
  }

  boost::optional<model::Space> space = subSurface.space();
  if (space){
    attachOtherModelObjects(*space);
  }

  model::Building building = subSurface.model().getUniqueModelObject<model::Building>();
  attachOtherModelObjects(building);
}
boost::optional<IdfObject> ForwardTranslator::translateSubSurface( model::SubSurface & modelObject )
{
  IdfObject idfObject(openstudio::IddObjectType::FenestrationSurface_Detailed);
  
  idfObject.setString(FenestrationSurface_DetailedFields::Name, modelObject.name().get());

  std::string subSurfaceType = modelObject.subSurfaceType();
  if (istringEqual("FixedWindow", subSurfaceType)){
    subSurfaceType = "Window";
  }else if (istringEqual("OperableWindow", subSurfaceType)){
    subSurfaceType = "Window";
  }else if (istringEqual("OverheadDoor", subSurfaceType)){
    subSurfaceType = "Door";
  }else if (istringEqual("Skylight", subSurfaceType)){
    subSurfaceType = "Window";
  }

  boost::optional<ConstructionBase> construction = modelObject.construction();
  if (construction){
    idfObject.setString(FenestrationSurface_DetailedFields::ConstructionName, construction->name().get());

    if (subSurfaceType == "Door" && construction->isFenestration()){
      LOG(Warn, "SubSurface '" << modelObject.name().get() << "' uses fenestration construction, changing SubSurfaceType to Door");
      subSurfaceType = "GlassDoor";
    } else if (subSurfaceType == "GlassDoor" && !construction->isFenestration()){
      LOG(Warn, "SubSurface '" << modelObject.name().get() << "' uses non-fenestration construction, changing SubSurfaceType to GlassDoor");
      subSurfaceType = "Door";
    }
  }

  idfObject.setString(FenestrationSurface_DetailedFields::SurfaceType, subSurfaceType);

  boost::optional<Surface> surface = modelObject.surface();
  if (surface){
    idfObject.setString(FenestrationSurface_DetailedFields::BuildingSurfaceName, surface->name().get());
  }

  boost::optional<SubSurface> adjacentSubSurface = modelObject.adjacentSubSurface();
  if (adjacentSubSurface){
    idfObject.setString(FenestrationSurface_DetailedFields::OutsideBoundaryConditionObject, adjacentSubSurface->name().get());
  }

  boost::optional<double> viewFactortoGround = modelObject.viewFactortoGround();
  if (viewFactortoGround){
    idfObject.setDouble(FenestrationSurface_DetailedFields::ViewFactortoGround, *viewFactortoGround);
  }

  boost::optional<ShadingControl> shadingControl = modelObject.shadingControl();
  if (shadingControl){
    idfObject.setString(FenestrationSurface_DetailedFields::ShadingControlName, shadingControl->name().get());
  }

  boost::optional<WindowPropertyFrameAndDivider> frameAndDivider = modelObject.windowPropertyFrameAndDivider();
  openstudio::Vector3d offset(0, 0, 0);
  if (frameAndDivider){
    if (!frameAndDivider->isOutsideRevealDepthDefaulted()){
      offset = -frameAndDivider->outsideRevealDepth() * modelObject.outwardNormal();
    }
    idfObject.setString(FenestrationSurface_DetailedFields::FrameandDividerName, frameAndDivider->name().get());
  }

  if(!modelObject.isMultiplierDefaulted()){
    idfObject.setDouble(FenestrationSurface_DetailedFields::Multiplier, modelObject.multiplier());
  }

  idfObject.clearExtensibleGroups();
  for (const Point3d& point : modelObject.vertices()){
    IdfExtensibleGroup group = idfObject.pushExtensibleGroup();
    if (group.empty()) {
      LOG(Error,"Currently unable to translate " << modelObject.briefDescription() 
          << ", because it has more vertices than allowed by EnergyPlus.");
      return boost::none;
    }

    Point3d newPoint = point + offset;

    group.setDouble(0, newPoint.x());
    group.setDouble(1, newPoint.y());
    group.setDouble(2, newPoint.z());
  }
  
  m_idfObjects.push_back(idfObject);

  return idfObject;

}
bool SurfaceNetworkBuilder::linkExteriorSubSurface(model::ThermalZone zone, model::Space space, model::Surface surface, model::SubSurface subSurface)
{
  LOG(Info, "Subsurface '" << subSurface.name().get() << "' connects zone '" << zone.name().get() << "' to the ambient");
  return true;
}