#include "input.h"
#include "control.h"


//define all static thingys:

int Input::mouseX=0,
    Input::mouseY=0,

    Input::screenX=0,
    Input::screenY=0,

    Input::windowX=0,
    Input::windowY=0,

    Input::invertMouse=0,

    Input::startPressLeftBtn=0,
    Input::startPressRightBtn=0;

bool Input::pressedLeft=false,
     Input::pressedRight=false,
     Input::pressedMiddle=false,
     Input::bShiftDown=false,
     Input::bAltDown=false,
     Input::bModifierPressed=false,
     Input::bTextInput=false;

std::string Input::savedDrawingDirName="resources/savedDrawings/",
            Input::savedCharacterDirName="resources/savedCharacters/",
            Input::savedSceneDirName="resources/savedScenes/",
            Input::savedKeyFramesDirName="resources/savedKeyFrames/";

std::vector<string> Input::savedDrawings;
std::vector<string> Input::savedCharacters;
std::vector<string> Input::savedScenes;
std::vector<string> Input::savedKeyFrames;

std::string Input::inputText="";

Vector3f Input::keyVector=Vector3f(0,0,0),          //delta!!!!
         Input::mouseVector=Vector3f(0,0,0),        //delta!!!!
         Input::mouse3D=Vector3f(0,0,0);            //mouse position in 3D coordinates (uses picking)

double Input::fpsBuffer[FPSBUFFERSIZE];

Control*  Input::controller=NULL;

Actor*    Input::worldTarget=NULL;

char*           Input::debugText="Moviesandbox 2.0";


void Input::setup(){

mouseVector=Vector3f(0,0,0);
keyVector=Vector3f(0,0,0);
windowX=100;
windowY=100;

invertMouse=-1;

glutIgnoreKeyRepeat(1);

controller=new Control;

Renderer::camLoc=&controller->viewLocation;
Renderer::camLook=&controller->viewTarget;
}

void Input::update(double deltaTime){

controller->update(deltaTime);
}

void Input::pressedMouse(int button,int state,int x, int y){
}


void Input::moveMouse(int x, int y){

if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
  bShiftDown=true;
else
  bShiftDown=false;


//delta
Input::mouseVector.x=x-Input::mouseX;
Input::mouseVector.y=(y-Input::mouseY)*invertMouse;

Input::mouseX=x;
Input::mouseY=y;
}

void Input::dragMouse(int x, int y){

//delta
Input::mouseVector.x=x-Input::mouseX;
Input::mouseVector.y=(y-Input::mouseY)*invertMouse;

Input::mouseX=x;
Input::mouseY=y;
}


//****************************************************************************************
// Key is pressed down

void Input::normalKeyDown(unsigned char key, int x, int y){

if (!bTextInput)
  {
    if (key=='d')
           Input::keyVector.x=1;
    if (key=='a')
           Input::keyVector.x=-1;

    if (key=='w')
           Input::keyVector.z=1;
    if (key=='s')
           Input::keyVector.z=-1;

    if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
      bShiftDown=true;
    else
      bShiftDown=false;

    if ((int)key==27)
       exit(0);

  }
else
  {
    if (key==127 || key==8)                               //pressed Delete!!!
      {
      if (inputText.size()>0)
        inputText.erase(inputText.size()-1);
      }
    else if (key==13)                                     //pressed Enter!!!
      {
      bTextInput=false;
      }
    else if (key==27)                                     //pressed ESC!!!
      {
      bTextInput=false;
      Input::deselectAll();
      }
    else
      inputText+=key;
  }
}

void Input::specialKeyDown(int key, int x, int y){

//make this relative to where we look at!
if (key==GLUT_KEY_RIGHT)
       Input::keyVector.x=1;
if (key==GLUT_KEY_LEFT)
       Input::keyVector.x=-1;

if (key==GLUT_KEY_PAGE_UP)
       Input::keyVector.y=1;
if (key==GLUT_KEY_PAGE_DOWN)
       Input::keyVector.y=-1;


if (key==GLUT_KEY_UP)
       Input::keyVector.z=1;
if (key==GLUT_KEY_DOWN)
       Input::keyVector.z=-1;

if (key==GLUT_KEY_END)
       exit(0);

if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
  bShiftDown=true;
else
  bShiftDown=false;
}


//****************************************************************************************
// Key is released

void Input::keyUp(unsigned char key,int x,int y){

Input::windowX=glutGet( GLUT_WINDOW_X);
Input::windowY=glutGet( GLUT_WINDOW_Y);

if (!bTextInput)
  {
    if (key=='a' && keyVector.x==-1)
           Input::keyVector.x=0;
    if (key=='d' && keyVector.x==1)
           Input::keyVector.x=0;

    if (key=='w')
           Input::keyVector.z=0;
    if (key=='s')
           Input::keyVector.z=0;


    if (key==9)                             //pressed TAB
      controller->toggleFlyMode();

    if (key==27)                                     //pressed ESC!!!
      Input::deselectAll();

    if (key==' ')                           //TODO: read these keycommands from an xml file
      controller->switchMode();

    if (key==127 || key==8)                               //pressed Delete!!!
      {
      Renderer::pick(mouseX,mouseY);
      if(worldTarget && worldTarget->name!="ground")
        Renderer::removeActor(worldTarget);
      }


    if (key=='p')
      Renderer::bUpdatePhysics=!Renderer::bUpdatePhysics;
  }

}


void Input::specialKeyUp (int key,int x, int y){

if (key==GLUT_KEY_LEFT && keyVector.x==-1)
       Input::keyVector.x=0;
if (key==GLUT_KEY_RIGHT && keyVector.x==1)
       Input::keyVector.x=0;

if (key==GLUT_KEY_PAGE_UP)
       Input::keyVector.y=0;
if (key==GLUT_KEY_PAGE_DOWN)
       Input::keyVector.y=0;


if (key==GLUT_KEY_UP)
       Input::keyVector.z=0;
if (key==GLUT_KEY_DOWN)
       Input::keyVector.z=0;

if (key==GLUT_KEY_F1)
        controller->switchCamToOne();

if (key==GLUT_KEY_F2)
        controller->switchCamToTwo();

}

void Input::deselectAll(){
}

void Input::displayFPS(){

double deltaTime=0;

//shift buffer
for (int i=FPSBUFFERSIZE-1;i>0;i--)
  Input::fpsBuffer[i]=Input::fpsBuffer[i-1];

//update buffer
Input::fpsBuffer[0]=Renderer::deltaTime;

//calculate buffer
for (int i=0;i<FPSBUFFERSIZE;i++)
  deltaTime+=Input::fpsBuffer[i];

deltaTime=deltaTime/FPSBUFFERSIZE;

char string[30];
sprintf(string,"FPS: %4.2f",1000/deltaTime);
Input::drawText(string,screenX-150,20 );
Input::drawText(debugText,screenX-150,50 );
}

void Input::drawText(char string[], float x, float y){

int spacing =3;
  char *c;
  float x1=x;
  glColor3f(1.0,1.0,1.0);
  for (c=string; *c != '\0'; c++) {
	glRasterPos2f(x1,y);
    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
	x1 = x1 + glutBitmapWidth(GLUT_BITMAP_HELVETICA_10,*c) + spacing;
  }
}

void Input::saveAll(std::string filename){
}

void Input::loadAll(std::string fileName){
}


//TODO: this is windows territory!
void Input::getAllDrawings(){

    cout << "getting drawings..." << endl;

    savedDrawings.clear();

    char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\savedDrawings\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
          {
		  cout << fd.cFileName << endl;
		  savedDrawings.push_back(fd.cFileName);
          }
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllCharacters(){

    cout << "getting characters..." << endl;

    savedCharacters.clear();

    char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\savedCharacters\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  savedCharacters.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllScenes(){

    cout << "getting scenes..." << endl;

    savedScenes.clear();

    char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\savedScenes\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  savedScenes.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllKeyFrames(){

    cout << "getting keyFrames..." << endl;

    savedKeyFrames.clear();

    char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\savedKeyFrames\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  savedKeyFrames.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

/*

The font options available are:

# GLUT_BITMAP_8_BY_13
# GLUT_BITMAP_9_BY_15
# GLUT_BITMAP_TIMES_ROMAN_10
# GLUT_BITMAP_TIMES_ROMAN_24
# GLUT_BITMAP_HELVETICA_10
# GLUT_BITMAP_HELVETICA_12
# GLUT_BITMAP_HELVETICA_18

*/

/*

Special Keys:

GLUT_KEY_F1		F1 function key
GLUT_KEY_F2		F2 function key
GLUT_KEY_F3		F3 function key
GLUT_KEY_F4		F4 function key
GLUT_KEY_F5		F5 function key
GLUT_KEY_F6		F6 function key
GLUT_KEY_F7		F7 function key
GLUT_KEY_F8		F8 function key
GLUT_KEY_F9		F9 function key
GLUT_KEY_F10		F10 function key
GLUT_KEY_F11		F11 function key
GLUT_KEY_F12		F12 function key
GLUT_KEY_LEFT		Left function key
GLUT_KEY_RIGHT		Up function key
GLUT_KEY_UP		Right function key
GLUT_KEY_DOWN		Down function key
GLUT_KEY_PAGE_UP	Page Up function key
GLUT_KEY_PAGE_DOWN	Page Down function key
GLUT_KEY_HOME		Home function key
GLUT_KEY_END		End function key
GLUT_KEY_INSERT		Insert function key


*/

