LocationTabController::LocationTabController(const model::Model & model,
                                             const QString& modelTempDir)
  : MainTabController(new LocationTabView(model,modelTempDir))
{
  LocationView * locationView = new LocationView(model, modelTempDir);
  mainContentWidget()->addSubTab("Weather File && Design Days",locationView,WEATHER_FILE);

  LifeCycleCostsView * lifeCycleCostsView = new LifeCycleCostsView(model);
  mainContentWidget()->addSubTab("Life Cycle Costs",lifeCycleCostsView,LIFE_CYCLE_COSTS);

  QLabel * label;

  label = new QLabel();
  label->setPixmap(QPixmap(":/images/utility_calibration_warning.png"));
  label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

  m_utilityBillsController = std::shared_ptr<UtilityBillsController>(new UtilityBillsController(model));

  m_utilityBillsStackedWidget = new QStackedWidget();
  m_warningWidgetIndex = m_utilityBillsStackedWidget->addWidget(label);
  m_visibleWidgetIndex = m_utilityBillsStackedWidget->addWidget(m_utilityBillsController->subTabView()); 

  mainContentWidget()->addSubTab("Utility Bills",m_utilityBillsStackedWidget,UTILITY_BILLS);

  // Determine if the utility bill sub-tab is shown
  boost::optional<model::YearDescription> yearDescription = model.yearDescription();
  if (yearDescription){
    boost::optional<int> calendarYear = yearDescription.get().calendarYear();
    if (calendarYear){
      boost::optional<model::WeatherFile> weatherFile = model.weatherFile();
      if (weatherFile){
        boost::optional<model::RunPeriod> runPeriod = model.getOptionalUniqueModelObject<model::RunPeriod>();
        if (runPeriod.is_initialized()){
          m_utilityBillsStackedWidget->setCurrentIndex(m_visibleWidgetIndex);
        }
        else {
          m_utilityBillsStackedWidget->setCurrentIndex(m_warningWidgetIndex);
        }
      }
    }
  }

  // Hack code to remove when tab active
  label = new QLabel();
  label->setPixmap(QPixmap(":/images/coming_soon_utility_rates.png"));
  label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  mainContentWidget()->addSubTab("Utility Rates",label,UTILITY_RATES);

  // Hack code to remove when tab active
  //label = new QLabel();
  //label->setPixmap(QPixmap(":/images/coming_soon_ground_temperature.png"));
  //label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Ground Temperature",label,GROUND_TEMPERATURE);

  // Hack code to remove when tab active
  //label = new QLabel();
  //label->setPixmap(QPixmap(":/images/coming_soon_water_mains_temperature.png"));
  //label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Water Mains Temperature",label,WATER_MAINS_TEMPERATURE);
}
SchedulesTabController::SchedulesTabController(bool isIP, const model::Model & model)
  : MainTabController(new SchedulesTabView(model)),
    m_model(model),
    m_isIP(isIP)
{
  mainContentWidget()->addSubTab("Schedule Sets", SCHEDULE_SETS);
  mainContentWidget()->addSubTab("Schedules", SCHEDULES);

  connect(this->mainContentWidget(), &MainTabView::tabSelected, this, &SchedulesTabController::setSubTab);
}
RunTabController::RunTabController(const model::Model & model, const openstudio::path &t_modelPath,
    const openstudio::path &t_tempFolder, openstudio::runmanager::RunManager t_runManager)
  : MainTabController(new RunTabView(model)),
    m_runView(new RunView(model, t_modelPath, t_tempFolder, t_runManager)),
    m_status(new openstudio::runmanager::JobStatusWidget(t_runManager))
{
  mainContentWidget()->addSubTab("Output", m_runView,OUTPUT);
  mainContentWidget()->addSubTab("Tree", m_status,TREE);

  connect(m_runView, &RunView::resultsGenerated, this, &RunTabController::resultsGenerated);

  connect(m_runView, &RunView::toolsUpdated, this, &RunTabController::toolsUpdated);

  //connect(m_runView, &RunView::useRadianceStateChanged, this, &RunTabController::useRadianceStateChanged);
}
LocationTabController::LocationTabController(bool isIP,
  const model::Model & model,
  const QString& modelTempDir)
  : MainTabController(new LocationTabView(model, modelTempDir)),
  m_modelTempDir(modelTempDir),
  m_model(model),
  m_isIP(isIP)
{
  mainContentWidget()->addSubTab("Weather File && Design Days", WEATHER_FILE); 
  mainContentWidget()->addSubTab("Life Cycle Costs", LIFE_CYCLE_COSTS);
  mainContentWidget()->addSubTab("Utility Bills", UTILITY_BILLS);

  setSubTab(0);
  connect(this->mainContentWidget(), &MainTabView::tabSelected, this, &LocationTabController::setSubTab);
}
LocationTabController::LocationTabController(bool isIP,
  const model::Model & model,
  const QString& modelTempDir)
  : MainTabController(new LocationTabView(model,modelTempDir)),
  m_model(model)
{
  m_locationView = new LocationView(isIP, model, modelTempDir);
  mainContentWidget()->addSubTab("Weather File && Design Days", m_locationView, WEATHER_FILE);
  connect(this, &LocationTabController::toggleUnitsClicked, m_locationView, &LocationView::toggleUnitsClicked);
  connect(m_locationView, &LocationView::calendarYearSelectionChanged, this, &LocationTabController::showUtilityBillSubTab);

  auto lifeCycleCostsView = new LifeCycleCostsView(model);
  mainContentWidget()->addSubTab("Life Cycle Costs",lifeCycleCostsView,LIFE_CYCLE_COSTS);

  QLabel * label;

  label = new QLabel();
  label->setPixmap(QPixmap(":/images/utility_calibration_warning.png"));
  label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

  m_utilityBillsController = std::shared_ptr<UtilityBillsController>(new UtilityBillsController(model));

  m_utilityBillsStackedWidget = new QStackedWidget();
  m_warningWidgetIndex = m_utilityBillsStackedWidget->addWidget(label);
  m_visibleWidgetIndex = m_utilityBillsStackedWidget->addWidget(m_utilityBillsController->subTabView()); 

  mainContentWidget()->addSubTab("Utility Bills",m_utilityBillsStackedWidget,UTILITY_BILLS);

  showUtilityBillSubTab();

  // Hack code to remove when tab active
  label = new QLabel();
  label->setPixmap(QPixmap(":/images/coming_soon_utility_rates.png"));
  label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Utility Rates",label,UTILITY_RATES); This is too slow in coming, so hide until ready

  // Hack code to remove when tab active
  //label = new QLabel();
  //label->setPixmap(QPixmap(":/images/coming_soon_ground_temperature.png"));
  //label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Ground Temperature",label,GROUND_TEMPERATURE);

  // Hack code to remove when tab active
  //label = new QLabel();
  //label->setPixmap(QPixmap(":/images/coming_soon_water_mains_temperature.png"));
  //label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Water Mains Temperature",label,WATER_MAINS_TEMPERATURE);
}
LocationTabController::LocationTabController(const model::Model & model,
                                             const QString& modelTempDir)
  : MainTabController(new LocationTabView(model,modelTempDir))
{
  LocationView * locationView = new LocationView(model, modelTempDir);
  mainContentWidget()->addSubTab("Weather File && Design Days",locationView,WEATHER_FILE);

  LifeCycleCostsView * lifeCycleCostsView = new LifeCycleCostsView(model);
  mainContentWidget()->addSubTab("Life Cycle Costs",lifeCycleCostsView,LIFE_CYCLE_COSTS);

  QLabel * label;
    
  label = new QLabel();
  label->setPixmap(QPixmap(":/images/utility_calibration_warning.png"));
  label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

  m_utilityBillsController = std::shared_ptr<UtilityBillsController>(new UtilityBillsController(model));

  m_utilityBillsStackedWidget = new QStackedWidget();
  m_warningWidgetIndex = m_utilityBillsStackedWidget->addWidget(label);
  m_visibleWidgetIndex = m_utilityBillsStackedWidget->addWidget(m_utilityBillsController->subTabView()); 

  mainContentWidget()->addSubTab("Utility Bills",m_utilityBillsStackedWidget,UTILITY_BILLS);

  m_utilityBillsStackedWidget->setCurrentIndex(m_warningWidgetIndex);

  connect(static_cast<UtilityBillsInspectorView *>(m_utilityBillsController->subTabView()->inspectorView()), &UtilityBillsInspectorView::showSubTabView,
          this, &LocationTabController::showSubTabView);

  // Hack code to remove when tab active
  label = new QLabel();
  label->setPixmap(QPixmap(":/images/coming_soon_utility_rates.png"));
  label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  mainContentWidget()->addSubTab("Utility Rates",label,UTILITY_RATES);

  // Hack code to remove when tab active
  //label = new QLabel();
  //label->setPixmap(QPixmap(":/images/coming_soon_ground_temperature.png"));
  //label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Ground Temperature",label,GROUND_TEMPERATURE);

  // Hack code to remove when tab active
  //label = new QLabel();
  //label->setPixmap(QPixmap(":/images/coming_soon_water_mains_temperature.png"));
  //label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  //mainContentWidget()->addSubTab("Water Mains Temperature",label,WATER_MAINS_TEMPERATURE);
}
  SpacesTabController::SpacesTabController(bool isIP, const model::Model& model) 
    : MainTabController(new SpacesTabView()),
    m_model(model),
    m_isIP(isIP)
{
  mainContentWidget()->addSubTab("Properties", SPACES);
  mainContentWidget()->addSubTab("Loads", LOADS);
  mainContentWidget()->addSubTab("Surfaces", SURFACES);
  mainContentWidget()->addSubTab("Subsurfaces", SUBSURFACES);
  mainContentWidget()->addSubTab("Interior Partitions", INTERIOR_PARTITIONS);
  mainContentWidget()->addSubTab("Shading", SHADING);

  connect(this->mainContentWidget(), &MainTabView::tabSelected, this, &SpacesTabController::setSubTab);

  // Evan note: TODO SpacesDaylightingGridView may be a dead class, given the latest Radiance plans
  //this->mainContentWidget()->addSubTab("Daylighting", new SpacesDaylightingGridView(m_isIP, m_model), DAYLIGHTING);
}
ScriptsTabController::ScriptsTabController()
  : MainTabController(new ScriptsTabView(0)), scriptsTabView(dynamic_cast<ScriptsTabView *>(mainContentWidget()))
{

  m_variableGroupListController = QSharedPointer<openstudio::measuretab::VariableGroupListController>(new openstudio::measuretab::VariableGroupListController(false, OSAppBase::instance()));
  m_variableGroupItemDelegate = QSharedPointer<openstudio::measuretab::VariableGroupItemDelegate>(new openstudio::measuretab::VariableGroupItemDelegate(true));

  //m_groups[MeasureType::ModelMeasure] = QString("OpenStudio Measures");
  ////m_groups[MeasureType::EnergyPlusMeasure] = QString("EnergyPlus Measures");

  //for( std::map<MeasureType,QString>::const_iterator it = m_groups.begin();
  //     it != m_groups.end();
  //     it++ )
  //{
  //  QSharedPointer<VariableGroupItem> variableGroupItem;
  //  variableGroupItem = QSharedPointer<VariableGroupItem>(new VariableGroupItem(it->first,it->second));
  //  m_variableGroupListController->addItem(variableGroupItem);
  //}

  scriptsTabView->variableGroupListView->setListController(m_variableGroupListController);
  scriptsTabView->variableGroupListView->setDelegate(m_variableGroupItemDelegate);

}
void SpacesTabController::setSubTab(int index)
{
  if (m_currentIndex == index) {
    return;
  }
  else {
    m_currentIndex = index;
  }

  if (qobject_cast<SpacesSpacesGridView *>(m_currentView)) {
    disconnect(this, &SpacesTabController::toggleUnitsClicked, qobject_cast<SpacesSpacesGridView *>(m_currentView), &SpacesSpacesGridView::toggleUnitsClicked);
    disconnect(qobject_cast<SpacesSpacesGridView *>(m_currentView), &SpacesSpacesGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
  }
  else if (qobject_cast<SpacesLoadsGridView *>(m_currentView)) {
    disconnect(this, &SpacesTabController::toggleUnitsClicked, qobject_cast<SpacesLoadsGridView *>(m_currentView), &SpacesLoadsGridView::toggleUnitsClicked);
    disconnect(qobject_cast<SpacesLoadsGridView *>(m_currentView), &SpacesLoadsGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
  }
  else if (qobject_cast<SpacesSurfacesGridView *>(m_currentView)) {
    disconnect(this, &SpacesTabController::toggleUnitsClicked, qobject_cast<SpacesSurfacesGridView *>(m_currentView), &SpacesSurfacesGridView::toggleUnitsClicked);
    disconnect(qobject_cast<SpacesSurfacesGridView *>(m_currentView), &SpacesSurfacesGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
  }
  else if (qobject_cast<SpacesSubsurfacesGridView *>(m_currentView)) {
    disconnect(this, &SpacesTabController::toggleUnitsClicked, qobject_cast<SpacesSubsurfacesGridView *>(m_currentView), &SpacesSubsurfacesGridView::toggleUnitsClicked);
    disconnect(qobject_cast<SpacesSubsurfacesGridView *>(m_currentView), &SpacesSubsurfacesGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
  }
  else if (qobject_cast<SpacesInteriorPartitionsGridView *>(m_currentView)) {
    disconnect(this, &SpacesTabController::toggleUnitsClicked, qobject_cast<SpacesInteriorPartitionsGridView *>(m_currentView), &SpacesInteriorPartitionsGridView::toggleUnitsClicked);
    disconnect(qobject_cast<SpacesInteriorPartitionsGridView *>(m_currentView), &SpacesInteriorPartitionsGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
  }
  else if (qobject_cast<SpacesShadingGridView *>(m_currentView)) {
    disconnect(this, &SpacesTabController::toggleUnitsClicked, qobject_cast<SpacesShadingGridView *>(m_currentView), &SpacesShadingGridView::toggleUnitsClicked);
    disconnect(qobject_cast<SpacesShadingGridView *>(m_currentView), &SpacesShadingGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
  }
  else if (m_currentView) {
    // Oops! Should never get here
    OS_ASSERT(false);
  }

  switch (index){
  case 0:
  {
    auto spacesSpacesGridView = new SpacesSpacesGridView(m_isIP, m_model);
    connect(this, &SpacesTabController::toggleUnitsClicked, spacesSpacesGridView, &SpacesSpacesGridView::toggleUnitsClicked);
    connect(spacesSpacesGridView, &SpacesSpacesGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
    mainContentWidget()->setSubTab(spacesSpacesGridView);
    m_currentView = spacesSpacesGridView;
    break;
  }
  case 1:
  {
    auto spacesLoadsGridView = new SpacesLoadsGridView(m_isIP, m_model);
    connect(this, &SpacesTabController::toggleUnitsClicked, spacesLoadsGridView, &SpacesLoadsGridView::toggleUnitsClicked);
    connect(spacesLoadsGridView, &SpacesLoadsGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
    mainContentWidget()->setSubTab(spacesLoadsGridView);
    m_currentView = spacesLoadsGridView;
    break;
  }
  case 2:
  {
    auto spacesSurfacesGridView = new SpacesSurfacesGridView(m_isIP, m_model);
    connect(this, &SpacesTabController::toggleUnitsClicked, spacesSurfacesGridView, &SpacesSurfacesGridView::toggleUnitsClicked);
    connect(spacesSurfacesGridView, &SpacesSurfacesGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
    mainContentWidget()->setSubTab(spacesSurfacesGridView);
    m_currentView = spacesSurfacesGridView;
    break;
  }
  case 3:
  {
    auto spacesSubsurfacesGridView = new SpacesSubsurfacesGridView(m_isIP, m_model);
    connect(this, &SpacesTabController::toggleUnitsClicked, spacesSubsurfacesGridView, &SpacesSubsurfacesGridView::toggleUnitsClicked);
    connect(spacesSubsurfacesGridView, &SpacesSubsurfacesGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
    mainContentWidget()->setSubTab(spacesSubsurfacesGridView);
    m_currentView = spacesSubsurfacesGridView;
    break;
  }
  case 4:
  {
    auto spacesInteriorPartitionsGridView = new SpacesInteriorPartitionsGridView(m_isIP, m_model);
    connect(this, &SpacesTabController::toggleUnitsClicked, spacesInteriorPartitionsGridView, &SpacesInteriorPartitionsGridView::toggleUnitsClicked);
    connect(spacesInteriorPartitionsGridView, &SpacesInteriorPartitionsGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
    mainContentWidget()->setSubTab(spacesInteriorPartitionsGridView);
    m_currentView = spacesInteriorPartitionsGridView;
    break;
  }
  case 5:
  {
    auto spacesShadingGridView = new SpacesShadingGridView(m_isIP, m_model);
    connect(this, &SpacesTabController::toggleUnitsClicked, spacesShadingGridView, &SpacesShadingGridView::toggleUnitsClicked);
    connect(spacesShadingGridView, &SpacesShadingGridView::dropZoneItemSelected, this, &SpacesTabController::dropZoneItemSelected);
    mainContentWidget()->setSubTab(spacesShadingGridView);
    m_currentView = spacesShadingGridView;
    break;
  }
  default:
    OS_ASSERT(false);
    break;
  }
}
SimSettingsTabController::SimSettingsTabController(bool isIP, const model::Model & model)
  : MainTabController(new SimSettingsTabView(isIP, model, "Simulation Settings", MainTabView::MAIN_TAB))
{
  connect(this, &SimSettingsTabController::toggleUnitsClicked, mainContentWidget(), &MainTabView::toggleUnitsClicked);
}
ScriptsTabController::ScriptsTabController()
  : MainTabController(new ScriptsTabView(nullptr)), scriptsTabView(dynamic_cast<ScriptsTabView *>(mainContentWidget()))
{
  auto app = OSAppBase::instance();
  boost::optional<path> tempDir = app->tempDir();
  OS_ASSERT(tempDir);

  // save the current osm to a temp location
  app->measureManager().saveTempModel(*tempDir);

  // update measures
  app->currentDocument()->disable();
  app->measureManager().updateMeasuresLists();
  app->currentDocument()->enable();

  m_workflowController = QSharedPointer<openstudio::measuretab::WorkflowController>(new openstudio::measuretab::WorkflowController(OSAppBase::instance()));
  m_workflowSectionItemDelegate = QSharedPointer<openstudio::measuretab::WorkflowSectionItemDelegate>(new openstudio::measuretab::WorkflowSectionItemDelegate());

  scriptsTabView->workflowView->setListController(m_workflowController);
  scriptsTabView->workflowView->setDelegate(m_workflowSectionItemDelegate);
}