// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "quaternion_demo.h"
#include "icosphere.h"

#include <Eigen/Geometry>
#include <Eigen/QR>
#include <Eigen/LU>

#include <iostream>
#include <QEvent>
#include <QMouseEvent>
#include <QInputDialog>
#include <QGridLayout>
#include <QButtonGroup>
#include <QRadioButton>
#include <QDockWidget>
#include <QPushButton>
#include <QGroupBox>

using namespace Eigen;

class FancySpheres {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  FancySpheres() {
    const int levels = 4;
    const float scale = 0.33;
    float radius = 100;
    std::vector<int> parents;

    // leval 0
    mCenters.push_back(Vector3f::Zero());
    parents.push_back(-1);
    mRadii.push_back(radius);

    // generate level 1 using icosphere vertices
    radius *= 0.45;
    {
      float dist = mRadii[0] * 0.9;
      for (int i = 0; i < 12; ++i) {
        mCenters.push_back(mIcoSphere.vertices()[i] * dist);
        mRadii.push_back(radius);
        parents.push_back(0);
      }
    }

    static const float angles[10] = {
        0, 0, EIGEN_PI, 0. * EIGEN_PI, EIGEN_PI, 0.5 * EIGEN_PI, EIGEN_PI, 1. * EIGEN_PI, EIGEN_PI, 1.5 * EIGEN_PI};

    // generate other levels
    int start = 1;
    for (int l = 1; l < levels; l++) {
      radius *= scale;
      int end = mCenters.size();
      for (int i = start; i < end; ++i) {
        Vector3f c = mCenters[i];
        Vector3f ax0 = (c - mCenters[parents[i]]).normalized();
        Vector3f ax1 = ax0.unitOrthogonal();
        Quaternionf q;
        q.setFromTwoVectors(Vector3f::UnitZ(), ax0);
        Affine3f t = Translation3f(c) * q * Scaling(mRadii[i] + radius);
        for (int j = 0; j < 5; ++j) {
          Vector3f newC =
              c + ((AngleAxisf(angles[j * 2 + 1], ax0) * AngleAxisf(angles[j * 2 + 0] * (l == 1 ? 0.35 : 0.5), ax1)) *
                   ax0) *
                      (mRadii[i] + radius * 0.8);
          mCenters.push_back(newC);
          mRadii.push_back(radius);
          parents.push_back(i);
        }
      }
      start = end;
    }
  }

  void draw() {
    int end = mCenters.size();
    glEnable(GL_NORMALIZE);
    for (int i = 0; i < end; ++i) {
      Affine3f t = Translation3f(mCenters[i]) * Scaling(mRadii[i]);
      gpu.pushMatrix(GL_MODELVIEW);
      gpu.multMatrix(t.matrix(), GL_MODELVIEW);
      mIcoSphere.draw(2);
      gpu.popMatrix(GL_MODELVIEW);
    }
    glDisable(GL_NORMALIZE);
  }

 protected:
  std::vector<Vector3f> mCenters;
  std::vector<float> mRadii;
  IcoSphere mIcoSphere;
};

// generic linear interpolation method
template <typename T>
T lerp(float t, const T& a, const T& b) {
  return a * (1 - t) + b * t;
}

// quaternion slerp
template <>
Quaternionf lerp(float t, const Quaternionf& a, const Quaternionf& b) {
  return a.slerp(t, b);
}

// linear interpolation of a frame using the type OrientationType
// to perform the interpolation of the orientations
template <typename OrientationType>
inline static Frame lerpFrame(float alpha, const Frame& a, const Frame& b) {
  return Frame(lerp(alpha, a.position, b.position),
               Quaternionf(lerp(alpha, OrientationType(a.orientation), OrientationType(b.orientation))));
}

template <typename Scalar_>
class EulerAngles {
 public:
  enum { Dim = 3 };
  typedef Scalar_ Scalar;
  typedef Matrix<Scalar, 3, 3> Matrix3;
  typedef Matrix<Scalar, 3, 1> Vector3;
  typedef Quaternion<Scalar> QuaternionType;

 protected:
  Vector3 m_angles;

 public:
  EulerAngles() {}
  inline EulerAngles(Scalar a0, Scalar a1, Scalar a2) : m_angles(a0, a1, a2) {}
  inline EulerAngles(const QuaternionType& q) { *this = q; }

  const Vector3& coeffs() const { return m_angles; }
  Vector3& coeffs() { return m_angles; }

  EulerAngles& operator=(const QuaternionType& q) {
    Matrix3 m = q.toRotationMatrix();
    return *this = m;
  }

  EulerAngles& operator=(const Matrix3& m) {
    // mat =  cy*cz          -cy*sz           sy
    //        cz*sx*sy+cx*sz  cx*cz-sx*sy*sz -cy*sx
    //       -cx*cz*sy+sx*sz  cz*sx+cx*sy*sz  cx*cy
    m_angles.coeffRef(1) = std::asin(m.coeff(0, 2));
    m_angles.coeffRef(0) = std::atan2(-m.coeff(1, 2), m.coeff(2, 2));
    m_angles.coeffRef(2) = std::atan2(-m.coeff(0, 1), m.coeff(0, 0));
    return *this;
  }

  Matrix3 toRotationMatrix(void) const {
    Vector3 c = m_angles.array().cos();
    Vector3 s = m_angles.array().sin();
    Matrix3 res;
    res << c.y() * c.z(), -c.y() * s.z(), s.y(), c.z() * s.x() * s.y() + c.x() * s.z(),
        c.x() * c.z() - s.x() * s.y() * s.z(), -c.y() * s.x(), -c.x() * c.z() * s.y() + s.x() * s.z(),
        c.z() * s.x() + c.x() * s.y() * s.z(), c.x() * c.y();
    return res;
  }

  operator QuaternionType() { return QuaternionType(toRotationMatrix()); }
};

// Euler angles slerp
template <>
EulerAngles<float> lerp(float t, const EulerAngles<float>& a, const EulerAngles<float>& b) {
  EulerAngles<float> res;
  res.coeffs() = lerp(t, a.coeffs(), b.coeffs());
  return res;
}

RenderingWidget::RenderingWidget() {
  mAnimate = false;
  mCurrentTrackingMode = TM_NO_TRACK;
  mNavMode = NavTurnAround;
  mLerpMode = LerpQuaternion;
  mRotationMode = RotationStable;
  mTrackball.setCamera(&mCamera);

  // required to capture key press events
  setFocusPolicy(Qt::ClickFocus);
}

void RenderingWidget::grabFrame(void) {
  // ask user for a time
  bool ok = false;
  double t = 0;
  if (!m_timeline.empty()) t = (--m_timeline.end())->first + 1.;
  t = QInputDialog::getDouble(this, "Eigen's RenderingWidget", "time value: ", t, 0, 1e3, 1, &ok);
  if (ok) {
    Frame aux;
    aux.orientation = mCamera.viewMatrix().linear();
    aux.position = mCamera.viewMatrix().translation();
    m_timeline[t] = aux;
  }
}

void RenderingWidget::drawScene() {
  static FancySpheres sFancySpheres;
  float length = 50;
  gpu.drawVector(Vector3f::Zero(), length * Vector3f::UnitX(), Color(1, 0, 0, 1));
  gpu.drawVector(Vector3f::Zero(), length * Vector3f::UnitY(), Color(0, 1, 0, 1));
  gpu.drawVector(Vector3f::Zero(), length * Vector3f::UnitZ(), Color(0, 0, 1, 1));

  // draw the fractal object
  float sqrt3 = std::sqrt(3.);
  glLightfv(GL_LIGHT0, GL_AMBIENT, Vector4f(0.5, 0.5, 0.5, 1).data());
  glLightfv(GL_LIGHT0, GL_DIFFUSE, Vector4f(0.5, 1, 0.5, 1).data());
  glLightfv(GL_LIGHT0, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());
  glLightfv(GL_LIGHT0, GL_POSITION, Vector4f(-sqrt3, -sqrt3, sqrt3, 0).data());

  glLightfv(GL_LIGHT1, GL_AMBIENT, Vector4f(0, 0, 0, 1).data());
  glLightfv(GL_LIGHT1, GL_DIFFUSE, Vector4f(1, 0.5, 0.5, 1).data());
  glLightfv(GL_LIGHT1, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());
  glLightfv(GL_LIGHT1, GL_POSITION, Vector4f(-sqrt3, sqrt3, -sqrt3, 0).data());

  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Vector4f(0.7, 0.7, 0.7, 1).data());
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Vector4f(0.8, 0.75, 0.6, 1).data());
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());
  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);

  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHT1);

  sFancySpheres.draw();
  glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data());
  glNormalPointer(GL_FLOAT, 0, mNormals[0].data());
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_NORMAL_ARRAY);
  glDrawArrays(GL_TRIANGLES, 0, mVertices.size());
  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_NORMAL_ARRAY);

  glDisable(GL_LIGHTING);
}

void RenderingWidget::animate() {
  m_alpha += double(m_timer.interval()) * 1e-3;

  TimeLine::const_iterator hi = m_timeline.upper_bound(m_alpha);
  TimeLine::const_iterator lo = hi;
  --lo;

  Frame currentFrame;

  if (hi == m_timeline.end()) {
    // end
    currentFrame = lo->second;
    stopAnimation();
  } else if (hi == m_timeline.begin()) {
    // start
    currentFrame = hi->second;
  } else {
    float s = (m_alpha - lo->first) / (hi->first - lo->first);
    if (mLerpMode == LerpEulerAngles)
      currentFrame = ::lerpFrame<EulerAngles<float> >(s, lo->second, hi->second);
    else if (mLerpMode == LerpQuaternion)
      currentFrame = ::lerpFrame<Eigen::Quaternionf>(s, lo->second, hi->second);
    else {
      std::cerr << "Invalid rotation interpolation mode (abort)\n";
      exit(2);
    }
    currentFrame.orientation.coeffs().normalize();
  }

  currentFrame.orientation = currentFrame.orientation.inverse();
  currentFrame.position = -(currentFrame.orientation * currentFrame.position);
  mCamera.setFrame(currentFrame);

  updateGL();
}

void RenderingWidget::keyPressEvent(QKeyEvent* e) {
  switch (e->key()) {
    case Qt::Key_Up:
      mCamera.zoom(2);
      break;
    case Qt::Key_Down:
      mCamera.zoom(-2);
      break;
    // add a frame
    case Qt::Key_G:
      grabFrame();
      break;
    // clear the time line
    case Qt::Key_C:
      m_timeline.clear();
      break;
    // move the camera to initial pos
    case Qt::Key_R:
      resetCamera();
      break;
    // start/stop the animation
    case Qt::Key_A:
      if (mAnimate) {
        stopAnimation();
      } else {
        m_alpha = 0;
        connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));
        m_timer.start(1000 / 30);
        mAnimate = true;
      }
      break;
    default:
      break;
  }

  updateGL();
}

void RenderingWidget::stopAnimation() {
  disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));
  m_timer.stop();
  mAnimate = false;
  m_alpha = 0;
}

void RenderingWidget::mousePressEvent(QMouseEvent* e) {
  mMouseCoords = Vector2i(e->pos().x(), e->pos().y());
  bool fly = (mNavMode == NavFly) || (e->modifiers() & Qt::ControlModifier);
  switch (e->button()) {
    case Qt::LeftButton:
      if (fly) {
        mCurrentTrackingMode = TM_LOCAL_ROTATE;
        mTrackball.start(Trackball::Local);
      } else {
        mCurrentTrackingMode = TM_ROTATE_AROUND;
        mTrackball.start(Trackball::Around);
      }
      mTrackball.track(mMouseCoords);
      break;
    case Qt::MidButton:
      if (fly)
        mCurrentTrackingMode = TM_FLY_Z;
      else
        mCurrentTrackingMode = TM_ZOOM;
      break;
    case Qt::RightButton:
      mCurrentTrackingMode = TM_FLY_PAN;
      break;
    default:
      break;
  }
}
void RenderingWidget::mouseReleaseEvent(QMouseEvent*) {
  mCurrentTrackingMode = TM_NO_TRACK;
  updateGL();
}

void RenderingWidget::mouseMoveEvent(QMouseEvent* e) {
  // tracking
  if (mCurrentTrackingMode != TM_NO_TRACK) {
    float dx = float(e->x() - mMouseCoords.x()) / float(mCamera.vpWidth());
    float dy = -float(e->y() - mMouseCoords.y()) / float(mCamera.vpHeight());

    // speedup the transformations
    if (e->modifiers() & Qt::ShiftModifier) {
      dx *= 10.;
      dy *= 10.;
    }

    switch (mCurrentTrackingMode) {
      case TM_ROTATE_AROUND:
      case TM_LOCAL_ROTATE:
        if (mRotationMode == RotationStable) {
          // use the stable trackball implementation mapping
          // the 2D coordinates to 3D points on a sphere.
          mTrackball.track(Vector2i(e->pos().x(), e->pos().y()));
        } else {
          // standard approach mapping the x and y displacements as rotations
          // around the camera's X and Y axes.
          Quaternionf q = AngleAxisf(dx * EIGEN_PI, Vector3f::UnitY()) * AngleAxisf(-dy * EIGEN_PI, Vector3f::UnitX());
          if (mCurrentTrackingMode == TM_LOCAL_ROTATE)
            mCamera.localRotate(q);
          else
            mCamera.rotateAroundTarget(q);
        }
        break;
      case TM_ZOOM:
        mCamera.zoom(dy * 100);
        break;
      case TM_FLY_Z:
        mCamera.localTranslate(Vector3f(0, 0, -dy * 200));
        break;
      case TM_FLY_PAN:
        mCamera.localTranslate(Vector3f(dx * 200, dy * 200, 0));
        break;
      default:
        break;
    }

    updateGL();
  }

  mMouseCoords = Vector2i(e->pos().x(), e->pos().y());
}

void RenderingWidget::paintGL() {
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_CULL_FACE);
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glDisable(GL_COLOR_MATERIAL);
  glDisable(GL_BLEND);
  glDisable(GL_ALPHA_TEST);
  glDisable(GL_TEXTURE_1D);
  glDisable(GL_TEXTURE_2D);
  glDisable(GL_TEXTURE_3D);

  // Clear buffers
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  mCamera.activateGL();

  drawScene();
}

void RenderingWidget::initializeGL() {
  glClearColor(1., 1., 1., 0.);
  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  glDepthMask(GL_TRUE);
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

  mCamera.setPosition(Vector3f(-200, -200, -200));
  mCamera.setTarget(Vector3f(0, 0, 0));
  mInitFrame.orientation = mCamera.orientation().inverse();
  mInitFrame.position = mCamera.viewMatrix().translation();
}

void RenderingWidget::resizeGL(int width, int height) { mCamera.setViewport(width, height); }

void RenderingWidget::setNavMode(int m) { mNavMode = NavMode(m); }

void RenderingWidget::setLerpMode(int m) { mLerpMode = LerpMode(m); }

void RenderingWidget::setRotationMode(int m) { mRotationMode = RotationMode(m); }

void RenderingWidget::resetCamera() {
  if (mAnimate) stopAnimation();
  m_timeline.clear();
  Frame aux0 = mCamera.frame();
  aux0.orientation = aux0.orientation.inverse();
  aux0.position = mCamera.viewMatrix().translation();
  m_timeline[0] = aux0;

  Vector3f currentTarget = mCamera.target();
  mCamera.setTarget(Vector3f::Zero());

  // compute the rotation duration to move the camera to the target
  Frame aux1 = mCamera.frame();
  aux1.orientation = aux1.orientation.inverse();
  aux1.position = mCamera.viewMatrix().translation();
  float duration = aux0.orientation.angularDistance(aux1.orientation) * 0.9;
  if (duration < 0.1) duration = 0.1;

  // put the camera at that time step:
  aux1 = aux0.lerp(duration / 2, mInitFrame);
  // and make it look at the target again
  aux1.orientation = aux1.orientation.inverse();
  aux1.position = -(aux1.orientation * aux1.position);
  mCamera.setFrame(aux1);
  mCamera.setTarget(Vector3f::Zero());

  // add this camera keyframe
  aux1.orientation = aux1.orientation.inverse();
  aux1.position = mCamera.viewMatrix().translation();
  m_timeline[duration] = aux1;

  m_timeline[2] = mInitFrame;
  m_alpha = 0;
  animate();
  connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));
  m_timer.start(1000 / 30);
  mAnimate = true;
}

QWidget* RenderingWidget::createNavigationControlWidget() {
  QWidget* panel = new QWidget();
  QVBoxLayout* layout = new QVBoxLayout();

  {
    QPushButton* but = new QPushButton("reset");
    but->setToolTip("move the camera to initial position (with animation)");
    layout->addWidget(but);
    connect(but, SIGNAL(clicked()), this, SLOT(resetCamera()));
  }
  {
    // navigation mode
    QGroupBox* box = new QGroupBox("navigation mode");
    QVBoxLayout* boxLayout = new QVBoxLayout;
    QButtonGroup* group = new QButtonGroup(panel);
    QRadioButton* but;
    but = new QRadioButton("turn around");
    but->setToolTip("look around an object");
    group->addButton(but, NavTurnAround);
    boxLayout->addWidget(but);
    but = new QRadioButton("fly");
    but->setToolTip("free navigation like a spaceship\n(this mode can also be enabled pressing the \"shift\" key)");
    group->addButton(but, NavFly);
    boxLayout->addWidget(but);
    group->button(mNavMode)->setChecked(true);
    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setNavMode(int)));
    box->setLayout(boxLayout);
    layout->addWidget(box);
  }
  {
    // track ball, rotation mode
    QGroupBox* box = new QGroupBox("rotation mode");
    QVBoxLayout* boxLayout = new QVBoxLayout;
    QButtonGroup* group = new QButtonGroup(panel);
    QRadioButton* but;
    but = new QRadioButton("stable trackball");
    group->addButton(but, RotationStable);
    boxLayout->addWidget(but);
    but->setToolTip("use the stable trackball implementation mapping\nthe 2D coordinates to 3D points on a sphere");
    but = new QRadioButton("standard rotation");
    group->addButton(but, RotationStandard);
    boxLayout->addWidget(but);
    but->setToolTip(
        "standard approach mapping the x and y displacements\nas rotations around the camera's X and Y axes");
    group->button(mRotationMode)->setChecked(true);
    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setRotationMode(int)));
    box->setLayout(boxLayout);
    layout->addWidget(box);
  }
  {
    // interpolation mode
    QGroupBox* box = new QGroupBox("spherical interpolation");
    QVBoxLayout* boxLayout = new QVBoxLayout;
    QButtonGroup* group = new QButtonGroup(panel);
    QRadioButton* but;
    but = new QRadioButton("quaternion slerp");
    group->addButton(but, LerpQuaternion);
    boxLayout->addWidget(but);
    but->setToolTip("use quaternion spherical interpolation\nto interpolate orientations");
    but = new QRadioButton("euler angles");
    group->addButton(but, LerpEulerAngles);
    boxLayout->addWidget(but);
    but->setToolTip("use Euler angles to interpolate orientations");
    group->button(mNavMode)->setChecked(true);
    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setLerpMode(int)));
    box->setLayout(boxLayout);
    layout->addWidget(box);
  }
  layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
  panel->setLayout(layout);
  return panel;
}

QuaternionDemo::QuaternionDemo() {
  mRenderingWidget = new RenderingWidget();
  setCentralWidget(mRenderingWidget);

  QDockWidget* panel = new QDockWidget("navigation", this);
  panel->setAllowedAreas((QFlags<Qt::DockWidgetArea>)(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea));
  addDockWidget(Qt::RightDockWidgetArea, panel);
  panel->setWidget(mRenderingWidget->createNavigationControlWidget());
}

int main(int argc, char* argv[]) {
  std::cout << "Navigation:\n";
  std::cout << "  left button:           rotate around the target\n";
  std::cout << "  middle button:         zoom\n";
  std::cout << "  left button + ctrl     quake rotate (rotate around camera position)\n";
  std::cout << "  middle button + ctrl   walk (progress along camera's z direction)\n";
  std::cout << "  left button:           pan (translate in the XY camera's plane)\n\n";
  std::cout << "R : move the camera to initial position\n";
  std::cout << "A : start/stop animation\n";
  std::cout << "C : clear the animation\n";
  std::cout << "G : add a key frame\n";

  QApplication app(argc, argv);
  QuaternionDemo demo;
  demo.resize(600, 500);
  demo.show();
  return app.exec();
}

#include "quaternion_demo.moc"
