//=========================================================================
//  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.
//=========================================================================
#include "pqACE3PRecentProjectsMenu.h"

#include "pqACE3PLoader.h"

#include "pqApplicationCore.h"
#include "pqInterfaceTracker.h"
#include "pqRecentlyUsedResourcesList.h"
#include "pqServer.h"
#include "pqServerConfiguration.h"
#include "pqServerResource.h"
#include "pqWaitCursor.h"

#include <QAction>
#include <QDebug>
#include <QList>
#include <QMap>
#include <QMenu>
#include <QString>

//=============================================================================
pqACE3PRecentProjectsMenu::pqACE3PRecentProjectsMenu(QMenu* menu, QObject* p)
  : QObject(p)
  , m_menu(menu)
{
  QObject::connect(m_menu, &QMenu::aboutToShow, this, &pqACE3PRecentProjectsMenu::buildMenu);
  QObject::connect(m_menu, &QMenu::triggered, this, &pqACE3PRecentProjectsMenu::onOpenProject);
}

//-----------------------------------------------------------------------------
pqACE3PRecentProjectsMenu::~pqACE3PRecentProjectsMenu() {}

//-----------------------------------------------------------------------------
void pqACE3PRecentProjectsMenu::buildMenu()
{
  if (!m_menu)
  {
    return;
  }

  m_menu->clear();
  auto loader = pqACE3PLoader::instance();

  // Get the set of all resources in most-recently-used order ...
  const pqRecentlyUsedResourcesList::ListT& resources =
    pqApplicationCore::instance()->recentlyUsedResources().list();

  // Sort resources to cluster them by servers.
  typedef QMap<QString, QList<pqServerResource>> ClusteredResourcesType;
  ClusteredResourcesType clusteredResources;

  for (int cc = 0; cc < resources.size(); cc++)
  {
    const pqServerResource& resource = resources[cc];
    if (!loader->canLoad(resource))
    {
      continue;
    }

    QString key;
    // if (this->SortByServers)
    if (true)
    {
      pqServerConfiguration config = resource.configuration();
      if (config.isNameDefault())
      {
        pqServerResource hostResource = (resource.scheme() == "session")
          ? resource.sessionServer().schemeHostsPorts()
          : resource.schemeHostsPorts();
        key = hostResource.toURI();
      }
      else
      {
        key = resource.configuration().URI();
      }
    }
    clusteredResources[key].push_back(resource);
  }

  // Display the servers ...
  for (ClusteredResourcesType::const_iterator criter = clusteredResources.begin();
       criter != clusteredResources.end();
       ++criter)
  {
    if (!criter.key().isEmpty())
    {
      // Q_ASSERT(this->SortByServers == true);

      // Add a separator for the server.
      QAction* const action = new QAction(criter.key(), m_menu);
      action->setIcon(QIcon(":/pqWidgets/Icons/pqConnect16.png"));

      // ensure that the server stands out
      QFont font = action->font();
      font.setBold(true);
      action->setFont(font);
      m_menu->addAction(action);
    }

    // now add actions for the recent items.
    for (int kk = 0; kk < criter.value().size(); ++kk)
    {
      const pqServerResource& item = criter.value()[kk];

      QString label;
      //QIcon icon;
      // if (rfm::iconAndLabel(ifaces, item, icon, label))
      if (true)
      {
        label = item.toURI();
        QAction* const act = new QAction(label, m_menu);
        act->setData(item.serializeString());
        //act->setIcon(icon);
        m_menu->addAction(act);
      }
    }
  }
}

//-----------------------------------------------------------------------------
void pqACE3PRecentProjectsMenu::onOpenProject(QAction* action)
{
  QString data = action ? action->data().toString() : QString();
  if (!data.isEmpty())
  {
    pqServerResource resource(action->data().toString());
    pqWaitCursor cursor;
    pqACE3PLoader::instance()->load(resource);
  }
}
