/*
 *  Copyright (C) 2006  MakeHuman Project
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *  
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *  
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  
 *  File   : Camera.h
 *  Project: MakeHuman <info@makehuman.org>, http://www.makehuman.org/
 *  Library: MHGUI
 *
 *  For individual developers look into the AUTHORS file.
 *   
 */

#ifndef CAMERA_H
#define CAMERA_H 1

#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

#if defined(__APPLE__) && defined(__MACH__)
  #include <GLUT/glut.h>
#else
  #ifdef USE_FREEGLUT 
    #include <GL/freeglut.h>
  #else
    #include <GL/glut.h>
  #endif
#endif

#include <cmath>
#include <animorph/Matrix.h>
#include <animorph/Vector2.h>
#include <animorph/Vector3.h>
#include <animorph/util.h>
#include "CGUtilities.h"

using Animorph::Matrix;
using Animorph::Vector2f;
using Animorph::Vector3f;

namespace mhgui {

// TODO: moving world vs. moving camera problem

class Camera
{
private:
  Vector2f last_mouse_pos;
  Vector3f last_pos_camera;
  int width;
  int height;
  float angle;
  Vector3f axis ;

  Vector3f projectMouseOnSphere (int x, int y);

  Matrix cam_pos;
  Matrix cam_center;

  // Ugly Test code following - just for test purposes!
  Vector3f  mCameraPos;
  float     mAngleX;
  float     mAngleY;
  float     mAngleZ;


public:
  /// construct a Camera that manages the world Matrix
  Camera ();
  Camera (const Camera& inRHS);
  Camera& operator=(const Camera& inRHS);

  void reshape (int width, int height);
  void rotate (float theta, RotateAxis axis);
  void mouseRotateStart (int x, int y);
  void rotateMouse (int x, int y);
  void move (float x, float y, float z);
  void resetRotation();
  void resetPosition();

  void applyMatrix ();

  const Vector3f& getPosition() const {return mCameraPos;}
  float           getAngleX()    const {return mAngleX;}
  float           getAngleY()    const {return mAngleY;}
  float           getAngleZ()    const {return mAngleZ;}
};
} // namespace mhgui
#endif // CAMERA_H
