// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "DockedWindow.h"
#include "ApplicationWindow.h"
#include "MdiSubWindow.h"

#include <QApplication>
#include <QDrag>
#include <QMimeData>
#include <QMoveEvent>

/**
 * Constructor.
 */
DockedWindow::DockedWindow(ApplicationWindow *appWindow)
    : QMdiSubWindow(appWindow), d_app(appWindow),
      m_draggingToTiledWindow(false), m_isInsideTiledWindow(false),
      m_dragMouseDown(false) {
  setFocusPolicy(Qt::StrongFocus);
  setAttribute(Qt::WA_DeleteOnClose);
}

/**
 * Returns the inner MdiSubWindow.
 */
MdiSubWindow *DockedWindow::mdiSubWindow() const {
  return static_cast<MdiSubWindow *>(widget());
}

/**
 * Set the innner MdiSubWindow.
 * @param sw :: A subwindow to set.
 */
void DockedWindow::setMdiSubWindow(MdiSubWindow *sw) {
  setWidget(sw);
  // setWindowIcon(sw->windowIcon());
  connect(sw, SIGNAL(dragMousePress(QPoint)), this,
          SLOT(dragMousePress(QPoint)));
  connect(sw, SIGNAL(dragMouseRelease(QPoint)), this,
          SLOT(dragMouseRelease(QPoint)));
  connect(sw, SIGNAL(dragMouseMove(QPoint)), this, SLOT(dragMouseMove(QPoint)));
}

/**
 * Process state change events such as activation, minimizing or maximizing.
 */
bool DockedWindow::event(QEvent *e) {
  // std::cerr << "Docked event " << e->type() << '\n';
  if (e->type() == QEvent::NonClientAreaMouseButtonPress) {
    // User clicked the window title bar
    m_draggingToTiledWindow = true;
  } else if (e->type() == QEvent::NonClientAreaMouseMove) {
    // For some reason this event is fired when the user releases the mouse over
    // the title bar
    if (m_draggingToTiledWindow) {
      d_app->dropInTiledWindow(mdiSubWindow(), pos() - d_app->pos());
      return true;
    }
    m_draggingToTiledWindow = false;
    m_isInsideTiledWindow = false;
  }
  return QMdiSubWindow::event(e);
}

void DockedWindow::moveEvent(QMoveEvent *ev) {
  if (m_draggingToTiledWindow) {
    // we are here if the window is being moved by the user
    m_isInsideTiledWindow = d_app->isInTiledWindow(ev->pos() - d_app->pos());
  } else {
    m_isInsideTiledWindow = false;
  }
}

void DockedWindow::dragMousePress(QPoint pos) {
  if (d_app->hasTiledWindowOpen()) {
    m_dragMouseDown = true;
    m_dragStartPos = pos;
  }
}

void DockedWindow::dragMouseRelease(QPoint) {
  if (m_dragMouseDown) {
    m_dragMouseDown = false;
  }
}

void DockedWindow::dragMouseMove(QPoint pos) {
  if (m_dragMouseDown) {
    if ((pos - m_dragStartPos).manhattanLength() <
        QApplication::startDragDistance()) {
      return;
    }

    QDrag *drag = new QDrag(d_app);
    QMimeData *mimeData = new QMimeData;

    MdiSubWindow *ptr = mdiSubWindow();
    auto d = QByteArray::fromRawData((const char *)ptr, 1);
    mimeData->setData("TiledWindow", d);

    drag->setMimeData(mimeData);
    Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
    (void)dropAction;
  }
}
