#include "GetPosition.h"
#include "GlFunctions.h"
#include "SetCamera.h"
#include "SceneContext.h"
#define HFOV2VFOV(h, ar) (2.0 * atan((ar) * tan( (h * FBXSDK_PI_DIV_180) * 0.5)) * FBXSDK_180_DIV_PI) //ar : aspectY / aspectX
#define VFOV2HFOV(v, ar) (2.0 * atan((ar) * tan( (v * FBXSDK_PI_DIV_180) * 0.5)) * FBXSDK_180_DIV_PI) //ar : aspectX / aspectY
void GetCameraAnimatedParameters(
FbxNode* pNode, 
 
static double gsOrthoCameraScale = 178.0; 
               int pWindowWidth, int pWindowHeight)
{
    
    FbxCamera* lCamera = GetCurrentCamera(pScene, pTime, pAnimLayer, pCameraArray);
 
        return;
    
    if (lCamera)
    {
    }
    {
        lCenter = GetGlobalPosition(lCameraNode->
GetTarget(), pTime).GetT();
 
    }
    else
    {
        if (!lCameraNode || IsProducerCamera(pScene, lCamera))
        {
            if (lCamera)
        }
        else
        {
            
            FbxVector4 lRotationVector(GetGlobalPosition(lCameraNode, pTime).GetR());
 
            lGlobalRotation.
SetR(lRotationVector);
 
            
            FbxVector4 lCameraGlobalPosition(GetGlobalPosition(lCameraNode, pTime).GetT());
 
            double      lLength = (
FbxVector4(lInterestPosition - lCameraGlobalPosition).
Length());
 
            
            
            
            
            lCenter = lGlobalRotation.
MultT(lRotationVector);
 
            lCenter *= lLength;
            lCenter += lEye;
            
            lUp = lGlobalRotation.
MultT(lRotationVector);
 
        }
    }
    
    lForward = lCenter - lEye;
    
    double lRadians = 0;
    if (lCamera)
    lUp = lUp * cos( lRadians) + lRight * sin(lRadians);
    
    double lNearPlane = 0.01;
    if (lCamera)
    double lFarPlane = 4000.0;
    if (lCamera)
    
    FbxVector4 lCameraScaling = GetGlobalPosition(lCameraNode, pTime).GetS();
 
    static const int  FORWARD_SCALE = 2;
    
    
    lNearPlane *= lCameraScaling[ FORWARD_SCALE];
    lFarPlane *= lCameraScaling[ FORWARD_SCALE];
    
    {
        
        double lAspectRatio = 1.333333;
        switch( lCamAspectRatioMode)
        {
            lAspectRatio = lAspectX / lAspectY;
            break;
            lAspectRatio = lAspectX;
            break;
            break;
            break;
            break;
        default:
            break;
        }
        
        
        double lApertureRatio = lFilmHeight / lFilmWidth;
        
        lAspectRatio = 1 / lAspectRatio;
        
        switch( lCameraGateFit )
        {
            if( lApertureRatio > lAspectRatio)  
            {
                lFilmHeight = lFilmWidth * lAspectRatio;
                lApertureRatio = lFilmHeight / lFilmWidth;
            }
            else if( lApertureRatio < lAspectRatio) 
            {
                lFilmWidth = lFilmHeight / lAspectRatio;
                lApertureRatio = lFilmHeight / lFilmWidth;
            }
            break;
            lFilmWidth = lFilmHeight / lAspectRatio;
            lApertureRatio = lFilmHeight / lFilmWidth;
            break;
            lFilmHeight = lFilmWidth * lAspectRatio;
            lApertureRatio = lFilmHeight / lFilmWidth;
            break;
            lAspectRatio = lApertureRatio;
            break;
            if( lFilmWidth > lFilmHeight)
            {
                lFilmHeight = lFilmWidth * lAspectRatio;
            }
            else
            {
                lFilmWidth = lFilmHeight / lAspectRatio;
            }
            lApertureRatio = lFilmHeight / lFilmWidth;
            break;
        default:
            break;
        }
        
        lAspectRatio = 1 / lAspectRatio;
        double lFieldOfViewX = 0.0;
        double lFieldOfViewY = 0.0;
        {
                lFieldOfViewX = VFOV2HFOV( lFieldOfViewY, 1 / lApertureRatio);
        }
        {
            lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
        }
        {
            lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
        }
        }
        double lRealScreenRatio = (double)pWindowWidth / (double)pWindowHeight;
        int  lViewPortPosX = 0, 
            lViewPortPosY = 0, 
            lViewPortSizeX = pWindowWidth, 
            lViewPortSizeY = pWindowHeight;
        
        if( lRealScreenRatio > lAspectRatio)
        {
            lViewPortSizeY = pWindowHeight;
            lViewPortSizeX = (int)( lViewPortSizeY * lAspectRatio);
            lViewPortPosY = 0;
            lViewPortPosX = (int)((pWindowWidth - lViewPortSizeX) * 0.5);
        }
        else
        {
            lViewPortSizeX = pWindowWidth;
            lViewPortSizeY = (int)(lViewPortSizeX / lAspectRatio);
            lViewPortPosX = 0;
            lViewPortPosY = (int)((pWindowHeight - lViewPortSizeY) * 0.5);
        }
        
        lFilmOffsetX = 0 - lFilmOffsetX / lFilmWidth * 2.0;
        lFilmOffsetY = 0 - lFilmOffsetY / lFilmHeight * 2.0;
        GlSetCameraPerspective( lFieldOfViewY, lAspectRatio, lNearPlane, lFarPlane, lEye, lCenter, lUp, lFilmOffsetX, lFilmOffsetY);
    
    
    
    
    
    
    
    
        
        glViewport( lViewPortPosX, lViewPortPosY, lViewPortSizeX, lViewPortSizeY);
        
    }
    
    else
    {
        double lPixelRatio = 1.0;
        if (lCamera)
        double lLeftPlane, lRightPlane, lBottomPlane, lTopPlane;
        if(pWindowWidth < pWindowHeight) 
        {   
            lLeftPlane   = -gsOrthoCameraScale * lPixelRatio;
            lRightPlane  =  gsOrthoCameraScale * lPixelRatio;
            lBottomPlane = -gsOrthoCameraScale * pWindowHeight / pWindowWidth;
            lTopPlane    =  gsOrthoCameraScale * pWindowHeight / pWindowWidth;
        } 
        else 
        {
            pWindowWidth *= (int) lPixelRatio;
            lLeftPlane   = -gsOrthoCameraScale * pWindowWidth / pWindowHeight;
            lRightPlane  =  gsOrthoCameraScale * pWindowWidth / pWindowHeight;
            lBottomPlane = -gsOrthoCameraScale;
            lTopPlane    =  gsOrthoCameraScale;
        }
        GlSetCameraOrthogonal(lLeftPlane,
            lRightPlane,
            lBottomPlane,
            lTopPlane,
            lNearPlane,
            lFarPlane,
            lEye,
            lCenter,
            lUp);
    }
}
{
    
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    {
        FbxCameraSwitcher* lCameraSwitcher = pScene->GlobalCameraSettings().GetCameraSwitcher();
 
        if (lCameraSwitcher)
        {
            int lCameraIndex = lCurve ? int(lCurve->
Evaluate(pTime)) - 1 : 0;
 
            if (lCameraIndex >= 0 && lCameraIndex < pCameraArray.GetCount())
            {
                FbxNode* lNode = pCameraArray[lCameraIndex];
 
                
                GetCameraAnimatedParameters(lNode, pTime, pAnimLayer);
            }
        }
    }
    else
    {
        int i;
        
        for (i = 0; i < pCameraArray.GetCount(); i++)
        {
            if (lCurrentCameraName.
Compare(pCameraArray[i]->GetName()) == 0)
 
            {
                lNode = pCameraArray[i];
                break;
            }
        }
        if (lNode)
        {
            
            GetCameraAnimatedParameters(lNode, pTime, pAnimLayer);
        }
    }
}
{
    lCamera->
Position.Set(GetGlobalPosition(pNode, pTime).GetT());
 
    if (fc)
    {
        if (fc)
        
        
    }
    {
        
        double lNewFieldOfViewX = lOldFieldOfViewX;
        double lNewFieldOfViewY = lOldFieldOfViewY;
        if (fc)
        if (fc)
        
        
    }
    {
        if (fc && fc ->Evaluate(pTime))
            
        
    }
}
{
        return true;
        return true;
        return true;
        return true;
        return true;
        return true;
        return true;
    return false;
}
{
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    {
    }
    else
    {
        if( lCameraNode)
        {
        }
    }
    return lRet;
}
double TransformAperture( double pAperture, double pTransform)
{
    double lTransformAperture = ( pAperture + pTransform);
    if( lTransformAperture < 0.25)
    {
        lTransformAperture = 0.25;
    }
    if( lTransformAperture  > 179.0)
    {
        lTransformAperture = 179.0;
    }
    return lTransformAperture;
}
void UpdatePerspCameraAttributes( 
FbxCamera* pCamera, 
double pNewApertureW, 
double pNewApertureH)
 
{
        return;
    
        
        
            
        
    }
    
}
void CameraZoom(
FbxScene* pScene, 
int pZoomDepth, 
int pZoomMode)
 
{
    FbxCamera* lCamera = GetCurrentCamera(pScene);
 
        return;
    if( pZoomMode == SceneContext::ZOOM_FOCAL_LENGTH)
    {
        {
            double lTransform = 0 - pZoomDepth / 400.0;
            lApertureW = TransformAperture( lApertureW, lTransform);
            lApertureH = TransformAperture( lApertureH, lTransform);
            UpdatePerspCameraAttributes( lCamera, lApertureW, lApertureH);
        }
        else
        {
            if( pZoomDepth > 0)
                gsOrthoCameraScale *= 0.8;
            else
                gsOrthoCameraScale *= 1.25;
        }
    }
    else
    {
        
        if (lCamera)
        {
        }
        {
            lForward = lCenter - lEye;
        }
        else
        {
            if (!lCameraNode || IsProducerCamera(pScene, lCamera))
            {
                if (lCamera)
                {
                    lForward = lCenter - lEye;
                }
            }
            else
            {
                
                lGlobalRotation.
SetR(lRotationVector);
 
                
                
                
                
                lForward = lGlobalRotation.
MultT(lRotationVector);
 
            }
        }
        lEye += lForward * pZoomDepth;
        
    }
}
void CameraOrbit(
FbxScene* pScene, 
FbxVector4 lOrigCamPos, 
double OrigRoll, 
int dX, 
int dY)
 
{
    
    FbxCamera* lCamera = GetCurrentCamera(pScene);
 
    if (!lCamera) return;
    if (dX == 0 && dY == 0) return;
    FbxVector4 lRotationVector, lNewPosition, lCurPosition;
 
    
    lCurPosition = lPosition-lCenter;
    
    lNewPosition = lOrigCamPos-lCenter;
    int rotX;
    if (lNewPosition[2] == 0) {
        rotX = 90;
    } else {
        rotX = (int) (atan((
double)lNewPosition[0]/(
double)lNewPosition[2]) * 
FBXSDK_180_DIV_PI);
 
    }
    bool bRoll = (((int)OrigRoll % 360) != 0);
    if (   (lNewPosition[2] < 0 && !bRoll)
        || (lNewPosition[2] > 0 && bRoll) ) {
            dY = -dY;
    }
    if (bRoll) dX = -dX;
    
    lRotationVector[1] = -rotX;
    lRotation.
SetR(lRotationVector);
 
    lNewPosition = lRotation.
MultT(lNewPosition);
 
    
    lRotationVector[1] = 0;
    lRotationVector[0] = dY;
    lRotation.
SetR(lRotationVector);
 
    lNewPosition = lRotation.
MultT(lNewPosition);
 
    
    lRotationVector[0] = 0;
    lRotationVector[1] = rotX;
    lRotation.
SetR(lRotationVector);
 
    lNewPosition = lRotation.
MultT(lNewPosition);
 
    
    lRotationVector[1] = -dX;
    lRotation.
SetR(lRotationVector);
 
    lNewPosition = lRotation.
MultT(lNewPosition);
 
    
    if (   lNewPosition[0]*lCurPosition[0] < 0 
        && lNewPosition[2]*lCurPosition[2] < 0) {
            
            double lRoll = lCamera->
Roll.
Get();
 
            lRoll = 180.0-lRoll;
    }
    
    lNewPosition = lNewPosition + lCenter;
}
    
    FbxCamera* lCamera = GetCurrentCamera(pScene);
 
    if (!lCamera) return;
    if (!IsProducerCamera(pScene, lCamera)) return;
    if (dX == 0 && dY == 0) return;
    FbxVector4 lRotationXV, lRotationYV, lTranslationV;
 
    FbxAMatrix lRotationX, lRotationY, lRotationXInverse, lRotationYInverse, lTranslation;
 
    
        lTranslationV[0] = -dX;
        lTranslationV[1] = 0;
        lTranslationV[2] = dY;
        lTranslationV[0] = dX;
        lTranslationV[1] = 0;
        lTranslationV[2] = dY;
        lTranslationV[0] = -dX;
        lTranslationV[1] = -dY;
        lTranslationV[2] = 0;
        lTranslationV[0] = dX;
        lTranslationV[1] = -dY;
        lTranslationV[2] = 0;
        lTranslationV[0] = 0;
        lTranslationV[1] = -dY;
        lTranslationV[2] = dX;
        lTranslationV[0] = 0;
        lTranslationV[1] = -dY;
        lTranslationV[2] = -dX;
    } else {
        
        
        bool bRoll = (((int)OrigRoll % 360) != 0);
        if (bRoll) {
            dX = -dX;
            dY = -dY;
        }
        
        double aZ, aY;
        
        double dist = (double)(lDist[0]*lDist[0]+lDist[1]*lDist[1]+lDist[2]*lDist[2]);
        
        if (lDist[2] == 0) {
            aZ = 90.0;
        } else {
        }
        if (lNewPosition[2] < lNewCenter[2]) aZ += 180;
        
        if (dist > 0.001) {
        } else {
            aY = 0;
        }
        if (lNewPosition[1] < lNewCenter[1]) aY = -aY;
        
        lTranslationV[0] = -dX;
        lTranslationV[1] = -dY;
        lTranslationV[2] = 0;
        
        lRotationYV[0] = 0;
        lRotationYV[1] = -aZ;
        lRotationYV[2] = 0;
        lRotationY.
SetR(lRotationYV);
 
        
        lRotationXV[0] = aY;
        lRotationXV[1] = 0;
        lRotationXV[2] = 0;
        lRotationX.
SetR(lRotationXV);
 
        
        lTranslation.
SetT(lTranslationV);
 
        lRotationYInverse = lRotationY.
Inverse();
 
        lRotationXInverse = lRotationX.
Inverse();
 
        lTranslation = lRotationYInverse * lRotationXInverse * lTranslation * lRotationY * lRotationX;
        lTranslationV = lTranslation.
GetT();
 
    }
    
    lNewPosition += lTranslationV;
    lNewCenter   += lTranslationV;
}