boost::optional<IdfObject> ForwardTranslator::translateDaylightingDeviceShelf( model::DaylightingDeviceShelf & modelObject )
{
  IdfObject idfObject(openstudio::IddObjectType::DaylightingDevice_Shelf);

  m_idfObjects.push_back(idfObject);

  idfObject.setString(DaylightingDevice_ShelfFields::Name, modelObject.name().get());

  OptionalString s = modelObject.getString(OS_DaylightingDevice_ShelfFields::WindowName, false, true);
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::WindowName, *s);
  }else{
    LOG(Error, "Missing required input 'Window Name' for DaylightingDevice:Shelf named '" << modelObject.name().get() << "'");
  }

  // TODO: make sure inside shelf is converted to a surface
  s = modelObject.getString(OS_DaylightingDevice_ShelfFields::InsideShelfName, false, true);
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::InsideShelfName, *s);
  }

  s = modelObject.getString(OS_DaylightingDevice_ShelfFields::OutsideShelfName, false, true);
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::OutsideShelfName, *s);
  }

  // TODO: map construction from shading surface
  s.reset();
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::OutsideShelfConstructionName, *s);
  }

  OptionalDouble d = modelObject.getDouble(OS_DaylightingDevice_ShelfFields::ViewFactortoOutsideShelf, false);
  if (d){
    idfObject.setDouble(DaylightingDevice_ShelfFields::ViewFactortoOutsideShelf, *d);
  }

  return boost::none;
}
boost::optional<IdfObject> ForwardTranslator::translateDaylightingDeviceShelf( model::DaylightingDeviceShelf & modelObject )
{
  SubSurface window = modelObject.subSurface();
  boost::optional<Space> space = window.space();
  boost::optional<InteriorPartitionSurface> insideShelf = modelObject.insideShelf();
  boost::optional<ShadingSurface> outsideShelf = modelObject.outsideShelf();

  if (!space){
    return boost::none;
  }

  if (!(insideShelf || outsideShelf)){
    return boost::none;
  }

  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::DaylightingDevice_Shelf, 
                                                       modelObject);

  idfObject.setString(DaylightingDevice_ShelfFields::WindowName, window.name().get());


  // inside shelf is converted to a surface
  if (insideShelf){

    openstudio::Transformation transformation;
    boost::optional<InteriorPartitionSurfaceGroup> group = insideShelf->interiorPartitionSurfaceGroup();
    if (group){
      transformation = group->transformation();
    }

    Point3dVector vertices = transformation*insideShelf->vertices();
    Surface newSurface(vertices, modelObject.model());
    newSurface.setName(modelObject.name().get());
    newSurface.setSpace(*space);
    newSurface.setAdjacentSurface(newSurface);

    boost::optional<ConstructionBase> construction = insideShelf->construction();
    if (!construction){
      Model t_model = modelObject.model();
      construction = interiorPartitionSurfaceConstruction(t_model);
    }
    OS_ASSERT(construction);
    newSurface.setConstruction(*construction);
    
    boost::optional<IdfObject> newSurfaceObject = translateAndMapModelObject(newSurface);
    if (newSurfaceObject){
      idfObject.setString(DaylightingDevice_ShelfFields::InsideShelfName, newSurfaceObject->name().get());
    }
  }

  if (outsideShelf){

    idfObject.setString(DaylightingDevice_ShelfFields::OutsideShelfName, outsideShelf->name().get());
    
    boost::optional<ConstructionBase> construction = outsideShelf->construction();
    if (!construction){
      Model t_model = modelObject.model();
      construction = exteriorSurfaceConstruction(t_model);
    }
    OS_ASSERT(construction);
    idfObject.setString(DaylightingDevice_ShelfFields::OutsideShelfConstructionName, construction->name().get());

    OptionalDouble d = modelObject.viewFactortoOutsideShelf();
    if (d){
      idfObject.setDouble(DaylightingDevice_ShelfFields::ViewFactortoOutsideShelf, *d);
    }
  }

  return idfObject;
}