//
// 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.
// 
#include "CameraPath.hpp"

#include "MorphoViewer.hpp"

using mgx::Point3f;
using mgx::Point4f;

CameraPath::CameraPath(QObject* parent)
  : QObject(parent)
  , timer(new QTimer(this))
{
  connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
  timer->setInterval(100);
  timer->setSingleShot(false);
  connect(this, SIGNAL(endPath()), timer, SLOT(stop()));
}

CameraPath::~CameraPath()
{
  if(timer)
    delete timer;
  timer = 0;
}

void CameraPath::addFrame(MGXCamera* camera, float time)
{
  //MGXCameraFrame* frame = camera->frame();
  frames << new ToPosition(Point3f(camera->sceneCenter()), Point3f(camera->position()),
                           Point3f(camera->viewDirection()), camera->zoom(), time, this);
}

void CameraPath::addRotation(const Point3f& axis, double angle, float time)
{
  //MGXCameraFrame* frame = camera->frame();
  frames << new Rotation(Point3f(camera->sceneCenter()), axis, angle, time, this);
}

void CameraPath::animatePath(MGXCamera* camera, float dt)
{
  if(frames.empty())
    return;
  current_time = 0;
  this->dt = dt;
  this->camera = camera;
  current_index = 0;
  frames[0]->startInterpolation(camera);
  timer->start();
}

void CameraPath::nextFrame()
{
  if(current_time > 1) {
    if(current_index == frames.size() - 1) {
      frames[current_index]->interpolateFrame(camera, 1.0f);
      emit frameUpdated();
      emit endPath();
      return;
    }
    current_index++;
    frames[current_index]->startInterpolation(camera);
    current_time -= 1.0f;
  }
  frames[current_index]->interpolateFrame(camera, current_time);
  emit frameUpdated();
}

bool CameraPath::ToPosition::startInterpolation(MGXCamera* ) {
  return true;
}

bool CameraPath::ToPosition::interpolateFrame(MGXCamera*, float ) {
  return true;
}
