//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================

// local includes
#include "plugin/pqACE3PAutoStart.h"

#include "smtk/newt/qtNewtInterface.h"
#include "smtk/simulation/ace3p/qt/qtNerscFileItem.h"

#include "smtk/simulation/ace3p/Metadata.h"
#include "smtk/simulation/ace3p/Registrar.h"

// SMTK includes
#include "smtk/extension/paraview/appcomponents/pqSMTKBehavior.h"
#include "smtk/extension/paraview/appcomponents/pqSMTKResourcePanel.h"
#include "smtk/extension/paraview/appcomponents/pqSMTKWrapper.h"
#include "smtk/extension/qt/qtSMTKUtilities.h"
#include "smtk/project/Project.h"
#include "smtk/view/ResourcePhraseModel.h"

// ParaView includes
#include "pqActiveObjects.h"
#include "pqCoreUtilities.h"
#include "pqServer.h"

#include <QApplication>
#include <QDebug>
#include <QMainWindow>
#include <QTimer>
#include <QWidget>

namespace
{
// Configure resource panel to omit displaying projects
// Code is copied from smtk::project::AutoStart
void setView()
{
  for (QWidget* w : QApplication::topLevelWidgets())
  {
    QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(w);
    if (mainWindow)
    {
      pqSMTKResourcePanel* dock = mainWindow->findChild<pqSMTKResourcePanel*>();
      // If the dock is not there, just try it again.
      if (dock)
      {
        auto phraseModel = std::dynamic_pointer_cast<smtk::view::ResourcePhraseModel>(
          dock->resourceBrowser()->phraseModel());
        if (phraseModel)
        {
          phraseModel->setFilter([](const smtk::resource::Resource& resource) {
            return !resource.isOfType(smtk::common::typeName<smtk::project::Project>());
          });
        }
      }
      else
      {
        QTimer::singleShot(10, []() { setView(); });
      }
    }
  }
}
} // namespace

pqACE3PAutoStart::pqACE3PAutoStart(QObject* parent)
  : Superclass(parent)
{
}

void pqACE3PAutoStart::startup()
{
// Set workflows folder for developer builds
#ifdef WORKFLOWS_SOURCE_DIR
  QDir workflowsDir(WORKFLOWS_SOURCE_DIR);
  if (workflowsDir.exists())
  {
    smtk::simulation::ace3p::Metadata::WORKFLOWS_DIRECTORY = WORKFLOWS_SOURCE_DIR;
  }
#endif

  // Check for current/active pqServer
  pqServer* server = pqActiveObjects::instance().activeServer();
  if (server != nullptr)
  {
    pqSMTKWrapper* wrapper = pqSMTKBehavior::instance()->resourceManagerForServer(server);
    this->resourceManagerAdded(wrapper, server);
  }

  // Listen for server connections
  auto smtkBehavior = pqSMTKBehavior::instance();
  QObject::connect(
    smtkBehavior,
    static_cast<void (pqSMTKBehavior::*)(pqSMTKWrapper*, pqServer*)>(
      &pqSMTKBehavior::addedManagerOnServer),
    this,
    &pqACE3PAutoStart::resourceManagerAdded);
  QObject::connect(
    smtkBehavior,
    static_cast<void (pqSMTKBehavior::*)(pqSMTKWrapper*, pqServer*)>(
      &pqSMTKBehavior::removingManagerFromServer),
    this,
    &pqACE3PAutoStart::resourceManagerRemoved);

  // Instantiate newt interface
  newt::qtNewtInterface::instance(pqCoreUtilities::mainWidget());

  // Since the loading order of smtk plugins is indeterminate, a spinning
  // function call is used here to customize the resource view.
  QTimer::singleShot(10, []() { setView(); });
}

void pqACE3PAutoStart::shutdown() {}

void pqACE3PAutoStart::resourceManagerAdded(pqSMTKWrapper* wrapper, pqServer* server)
{
  if (!wrapper || !server)
  {
    return;
  }

  smtk::resource::ManagerPtr resManager = wrapper->smtkResourceManager();
  smtk::view::ManagerPtr viewManager = wrapper->smtkViewManager();
  smtk::operation::ManagerPtr opManager = wrapper->smtkOperationManager();
  smtk::project::ManagerPtr projManager = wrapper->smtkProjectManager();
  if (!resManager || !viewManager || !opManager || !projManager)
  {
    return;
  }

  smtk::simulation::ace3p::Registrar::registerTo(projManager);

  // Register custom item view for NERSC file browser
  qtSMTKUtilities::registerItemConstructor(
    "NERSCDirectory", smtk::simulation::ace3p::qtNerscFileItem::createItemWidget);
}

void pqACE3PAutoStart::resourceManagerRemoved(pqSMTKWrapper* wrapper, pqServer* server)
{
  if (!wrapper || !server)
  {
    return;
  }

  smtk::view::ManagerPtr viewManager = wrapper->smtkViewManager();
  if (viewManager != nullptr)
  {
  }

  smtk::project::ManagerPtr projManager = wrapper->smtkProjectManager();
  if (projManager != nullptr)
  {
    smtk::simulation::ace3p::Registrar::unregisterFrom(projManager);
  }
}
