//=========================================================================
//  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 "smtk/simulation/windtunnel/qt/qtControlsViewConfig.h"

#include "smtk/simulation/windtunnel/qt/qtSessionData.h"

// SMTK includes
#include "smtk/operation/Manager.h"
#include "smtk/view/Configuration.h"

#include <QDebug>
#include <QDir>
#include <QMetaObject>

namespace smtk
{
namespace simulation
{
namespace windtunnel
{

qtControlsViewConfig::qtControlsViewConfig(
  const smtk::view::ConfigurationPtr config,
  QObject* parent)
  : Superclass(parent)
{
  this->initialize(config);
}

void qtControlsViewConfig::initialize(const smtk::view::ConfigurationPtr config)
{
  m_defaultRepresentation = "Surface";

  auto* sessionData = smtk::simulation::windtunnel::qtSessionData::instance();
  auto opManager = sessionData->operationManager();
  QDir foamDir(sessionData->foamDirectory());
  int index;

  // FoamApplication element
  QString caseFolder;
  index = config->details().findChild("FoamApplication");
  if (index >= 0)
  {
    smtk::view::Configuration::Component& comp = config->details().child(index);
    m_foamApp = comp.contents().c_str();

    std::string _case_directory;
    if (comp.attribute("CaseDirectory", _case_directory))
    {
      m_caseName = _case_directory.c_str();
    }
    else
    {
      m_caseName = m_foamApp;
    }
  }

  // FoamArguments element
  index = config->details().findChild("FoamArguments");
  if (index >= 0)
  {
    smtk::view::Configuration::Component& listComp = config->details().child(index);
    std::size_t numChildren = listComp.numberOfChildren();
    for (std::size_t i = 0; i < numChildren; ++i)
    {
      smtk::view::Configuration::Component& argComp = listComp.child(i);
      QString arg = argComp.contents().c_str();
      m_foamArguments << arg;
    }
  }

  // Category element
  index = config->details().findChild("Category");
  if (index >= 0)
  {
    smtk::view::Configuration::Component& comp = config->details().child(index);
    m_category = comp.contents().c_str();
  }

  // Operation element
  index = config->details().findChild("Operation");
  if (index >= 0)
  {
    smtk::view::Configuration::Component& comp = config->details().child(index);
    std::string opType = comp.contents();
    if (!opManager->registered(opType))
    {
      qWarning() << "Warning: operation" << opType.c_str() << "not found." << __FILE__ << __LINE__;
    }
    else
    {
      m_operationType = opType;
      m_useOperationDialog = comp.attributeAsBool("UseDialog");
    }
  }

  // Geometry element
  index = config->details().findChild("Geometry");
  if (index >= 0)
  {
    smtk::view::Configuration::Component& comp = config->details().child(index);
    QString geometryReference = comp.contents().c_str();

    std::string typeString;
    if (comp.attribute("Type", typeString))
    {
      if (typeString == "ResourceRole")
      {
        m_geometryType = GeometryType::Resource;
        m_resourceRole = geometryReference;
      }
      else if (typeString == "FoamFile")
      {
        m_geometryType = GeometryType::FoamFile;
        m_foamfileName = geometryReference;
      }
    }

    // Check for "Representation" attribute to use as the default
    std::string reprAtt;
    if (comp.attribute("Representation", reprAtt))
    {
      m_defaultRepresentation = reprAtt.c_str();
    }
  } // if (index >= 0)
}

const QString& qtControlsViewConfig::caseDirectory()
{
  if (m_caseDirectory.isEmpty())
  {
    auto* sessionData = smtk::simulation::windtunnel::qtSessionData::instance();
    const QString& foamDirectory = sessionData->foamDirectory();
    m_caseDirectory = QString("%1/%2").arg(foamDirectory).arg(m_caseName);
  }

  return m_caseDirectory;
}

const QString& qtControlsViewConfig::foamfilePath()
{
  if (m_foamfilePath.isEmpty() && !m_foamfileName.isEmpty())
  {
    m_foamfilePath = QString("%1/%2").arg(this->caseDirectory()).arg(m_foamfileName);
  }
  return m_foamfilePath;
}

const QString& qtControlsViewConfig::logfilePath()
{
  if (m_logfilePath.isEmpty() && !m_foamApp.isEmpty())
  {
    m_logfilePath = QString("%1/logs/%2.log").arg(this->caseDirectory()).arg(m_foamApp);
  }
  return m_logfilePath;
}

void qtControlsViewConfig::setSolverName(const QString& solverName)
{
  m_foamApp = solverName;
  m_caseDirectory.clear();                  // updated in caseDirectory() method
  QString temp = solverName;                // non-const copy
  m_foamfileName = temp.replace('F', ".f"); // i.e., icoFoam => ico.foam

  m_caseName = solverName;
  m_foamfilePath.clear(); // updated in foamfilePath() method
  m_logfilePath.clear();  // ditto
}

void qtControlsViewConfig::dump() const
{
  qDebug() << "qtControlsViewConfig:";
  qDebug() << " "
           << "m_foamApp" << m_foamApp;
  qDebug() << " "
           << "m_caseDirectory" << m_caseDirectory;
  qDebug() << " "
           << "m_geometryType" << m_geometryType;
  qDebug() << " "
           << "m_foamfileName" << m_foamfileName;
  qDebug() << " "
           << "m_foamfilePath" << m_foamfilePath;
  qDebug() << " "
           << "m_resourceRole" << m_resourceRole;
  qDebug() << " "
           << "m_defaultRepresentation" << m_defaultRepresentation;
  qDebug() << " "
           << "m_operationType" << m_operationType.c_str();
  qDebug() << " "
           << "m_useOperationDialog" << m_useOperationDialog;
  qDebug() << " "
           << "m_foamfilePath" << m_foamfilePath;
  qDebug() << " "
           << "m_logfilePath" << m_logfilePath;
}

} // namespace windtunnel
} // namespace simulation
} // namespace smtk
