//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2015 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
//
#ifndef CAMERAPATH_HPP
#define CAMERAPATH_HPP

#include <Config.hpp>

#include <Misc.hpp>

#include <QObject>
#include <QTimer>
#include <QPointer>
#include <QList>

class MGXCamera;

class CameraPath : public QObject 
{
  Q_OBJECT
public:
  CameraPath(QObject* parent);
  ~CameraPath();
  void addFrame(MGXCamera* camera, float time = 1.0);
  void addRotation(const mgx::Point3f& axis, double angle, float time = 2.0);

  void animatePath(MGXCamera* camera, float dt);

protected slots:
  void nextFrame();

signals:
  void endPath();
  void frameUpdated();

protected:
  struct Action : public QObject 
	{
    Action(float t, QObject* parent = 0) : QObject(parent), time(t) {}

    // Returns true when the end is reached
    virtual bool startInterpolation(MGXCamera* camera) = 0;
    virtual bool interpolateFrame(MGXCamera* camera, float t) = 0;
    float time;
  };

  struct ToPosition : public Action {
    ToPosition(const mgx::Point3f& c, const mgx::Point3f& p, 
										     const mgx::Point3f& d, float z, float t, QObject* parent = 0)
      : Action(t, parent), center(c), position(p), direction(d), zoom(z) {}

    virtual bool startInterpolation(MGXCamera* camera);
    virtual bool interpolateFrame(MGXCamera* camera, float t);
    mgx::Point3f center;
    mgx::Point3f position;
    mgx::Point3f direction;
    float zoom;

    // Quaternions for camera orientation
    qglviewer::Quaternion oq1, oq2;
    // Quaternions for camera position
    qglviewer::Quaternion pq1, pq2;
  };

  struct Rotation : public Action 
	{
    Rotation(const mgx::Point3f& c, const mgx::Point3f& ax, float an, float t, QObject* parent = 0)
      : Action(t, parent), center(c), axis(ax), angle(an) {}
    virtual bool startInterpolation(MGXCamera*) { return true; }
    virtual bool interpolateFrame(MGXCamera*, float) { return true; }
    mgx::Point3f center;
    mgx::Point3f axis;
    double angle;
  };

  QList<QPointer<Action> > frames;
  MGXCamera* camera;
  float dt;
  float current_time;
  int current_index;
  QTimer* timer;
};

#endif
