/*
 * This file is part of the LibreOffice project.
 *
 * 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 "Camera.h"
#include <glm/gtx/rotate_vector.hpp>
#include <time.h>
#pragma warning(disable : 4996)
const float PI = float(atan(1.0)*4.0);

CPhysicalCamera::CPhysicalCamera()
{
	vEye = glm::vec3(0.0f, 0.0f, 0.0f);
	vView = glm::vec3(0.0f, 0.0, -1.0f);
	vUp = glm::vec3(0.0f, 1.0f, 0.0f);
	fSpeed = 25.0f;
	fSensitivity = 0.1f;
    flength = 0.0f;
}

CPhysicalCamera::CPhysicalCamera(glm::vec3 a_vEye, glm::vec3 a_vView, glm::vec3 a_vUp, double a_fSpeed, double a_fSensitivity)
{
	vEye = a_vEye; vView = a_vView; vUp = a_vUp;
	fSpeed = a_fSpeed;
	fSensitivity = a_fSensitivity;
    fPreTime = 0.0f;
    fTotalMoveTime = 0.0f;
    bMove_camera_flag = false;
    bRoate_camera_flag = false;
}

void CPhysicalCamera::rotateCamera(double horizontal, double vertical,
    double planar, double time)
{
    if(time != 0)
    {
        bRoate_camera_flag = true;
        fSetTime = time;
        glm::vec3 endView(horizontal,vertical,planar);
        glm::vec3 vRotate = endView - vView;
        vRotate /= time;
        vSpeed = vRotate;   
    }
    else
    {
        vView = glm::vec3(horizontal,vertical,planar);
    }
}

void CPhysicalCamera::moveCamera(double x, double y, double z,
    double time)
{

    if (time != 0)
    {
        bMove_camera_flag = true;
        fSetTime = time;
        glm::vec3 endView(x,y,z);
        glm::vec3 vRotate = endView - vView;
        vRotate /= time ;
        vSpeed = vRotate;
    }
    else
    {
        vView += glm::vec3(x,y,z);
        vEye += glm::vec3(x,y,z);
    }
}

float CPhysicalCamera::GetAngleY()
{
	glm::vec3 vDir = vView-vEye; vDir.y = 0.0f;
	glm::normalize(vDir);
	float fAngle = acos(glm::dot(glm::vec3(0, 0, -1), vDir))*(180.0f/PI);
	if(vDir.x < 0)fAngle = 360.0f-fAngle;
	return fAngle;
}

void CPhysicalCamera::SetRotationAngle(double fRotateCube , double fRotatePyramid ,
    double fCubeRotateSpeed,double fPyramidRotateSpeed )
{
    PIover180 = 3.1415f/180.0f;
    fRotationAngleCube = fRotateCube;
    fRotationAnglePyramid = fRotatePyramid;
    fCubeRotationSpeed = fCubeRotateSpeed;
    fPyramidRotationSpeed = fPyramidRotateSpeed;
}

glm::mat4 CPhysicalCamera::Look()
{
	return glm::lookAt(vEye, vView, vUp);
}
glm::mat4 CPhysicalCamera::getModelViewMatrix(glm::mat4* pMatrix)
{
    glm::mat4 modelViewMatrix;
    time_t tt = time(NULL);  
    struct tm *t = localtime(&tt);  
    int  hour = t->tm_hour;  
    int min = t->tm_min;  
    int sec = t->tm_sec;
    int cTime = sec + min * 60 + hour * 3600;
    float fMoveTime = (float)(cTime - fPreTime);
    //glm::mat4 modelViewMatrix;
    if(fPreTime <= 0)
    {
        modelViewMatrix  = Look() * (*pMatrix);
    }
    else
    {
        fTotalMoveTime += fMoveTime;
        if(fTotalMoveTime <= fSetTime)
        {
            if(bRoate_camera_flag == true)
            {
                vView += vSpeed * fMoveTime;
            }
            if(bMove_camera_flag == true)
            {
                vEye += vSpeed  * fMoveTime;
                vView += vSpeed * fMoveTime;
            } 
            modelViewMatrix  = Look() * (*pMatrix);
        }
        else
        {
            modelViewMatrix = Look() * (*pMatrix);
        }    
    }
    fPreTime = cTime;
    return modelViewMatrix;
}