// Modified 3/9/04 by Ben Pellow
// to include keyboard commands for changing the ball's position
// and velocity, as well as any vertex's position.

#include "cGame.h"

cGame* cGame::instance_ = 0;

cGame* cGame::instance()
{
    if(instance_ == 0)
        instance_ = new cGame;
    return instance_;
}

cGame::cGame()
{
    particleSystem_ = new cParticleSystem();
    numFrames_ = 0;
    // Nothing to do
}

void cGame::init()
{
    
    world_ = new cWorld(particleSystem_);
    loadEmpty();
    lastX_ = 0;
    lastY_ = 0;
    
    frameRate_ = 0;
    timeInSecond_ = 0;
    level_ = 0;
}

void cGame::updateParticleSystem()
{
    // clear color and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    float delay = timer_.update();
    particleSystem_->update(delay);
    particleSystem_->draw();
    
    // flush buffer
    glutSwapBuffers();
}

void cGame::display()
{    

    ++numFrames_;
    if(numFrames_ > 100 && level_ == 0) loadMushroom();
    
    if(world_->ball_.isInHole() && world_->ball_.getTimeInHole() > 2)
    {
        particleSystem_->clearNonText();
        
        
        ++level_;
        switch(level_)
        {
        case 2: loadVolcano(); break;
        case 3: loadMaze(); break;
		case 4: loadIce(); break;
        case 5: loadCastle(); break;
        }
        
    }
        
   // clear color and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    float delay = timer_.update();
    
    if(world_->levelIsLoaded() && level_ != 0)
    {
        timeInSecond_ += delay;
    
        world_->update(delay);
        world_->draw();
    }
    
    particleSystem_->update(delay);
    particleSystem_->draw();
    
    ++frameRate_;
    if (timeInSecond_ > 1 )
    {
        cout<< "fps: " << frameRate_ << endl;
        frameRate_ = 0;
        timeInSecond_ = 0;
    }
            
    // flush buffer
    glutSwapBuffers();
}

void cGame::idle()
{
    glutPostRedisplay();
}

void cGame::keyboard(unsigned char key, int x, int y) 
{
    cout << "key=" << (int)key << endl;
    
    if(key == 45) world_->camera_.radius_ -= 4;
    if(key == 43) world_->camera_.radius_ += 4;
    
    if(key == 52) world_->ball_.launchAngle_ -= .05;
    if(key == 54) world_->ball_.launchAngle_ += .05;
    
    if(key == 49) world_->ball_.launchAngle_ -= .25;
    if(key == 51) world_->ball_.launchAngle_ += .25;
    
    if(key == 53)
    {
        if(world_->ball_.launchPower_ > 5)
            world_->ball_.launchPower_ -= 5;
    }
    if(key == 56) world_->ball_.launchPower_ += 5;
    
    if(key == ' ')  world_->ball_.launch(); 
    
    if(key == 'r') world_->ball_.randomize(level_);
    
    if(key == 'v') loadVolcano();
    
    if(key == 'u') loadMushroom();

	if(key == 'i') loadIce();
    
    if(key == 'm') loadMaze();

    if(key == 'c') loadCastle();
}

void cGame::mouseClick(int button, int state, int x, int y) 
{
}

void cGame::mouseMove(int x, int y)
{
    if (lastX_>0  && abs(x-lastX_) < screenWidth_/6 && abs(y-lastY_) < screenHeight_/6)
    {	
        float theta = -.5 * 3.1415926535 * (float)(y-lastY_)/(float)screenHeight_;
        float phi = 3.1415926535 * (float)(x -lastX_)/(float)screenWidth_;
        
        world_->camera_.phi_ +=  phi;
        world_->camera_.theta_ += theta;
        
        if(world_->camera_.theta_ < -1.51187)
            world_->camera_.theta_ = -1.51187; 
    }
    
    lastX_ = x;
    lastY_ = y;
     
}


void cGame::loadIce()
{
	particleSystem_->clearNonText();
    particleSystem_->addSmiley();
    cout << "loading ice level" << endl;
    world_->unloadLevel();
    world_->loadLevel("ice.txt", 4);
    level_ = 4;
    particleSystem_->setLevel(level_);
}

void cGame::loadMushroom()
{
    particleSystem_->clearNonText();
    particleSystem_->addSmiley();
    cout << "loading mushroom level" << endl;
    world_->unloadLevel();
    world_->loadLevel("mushroom.txt", 1);
    level_ = 1;
    particleSystem_->setLevel(level_);
}

void cGame::loadMaze()
{
    particleSystem_->clearNonText();
    particleSystem_->addSmiley();
    cout << "loading maze level" << endl;
    world_->unloadLevel();
    world_->loadLevel("maze.txt", 3);
    level_ = 3;
    particleSystem_->setLevel(level_);
}

void cGame::loadCastle()
{
    particleSystem_->clearNonText();
    particleSystem_->addSmiley();
    cout << "loading castle level" << endl;
    world_->unloadLevel();
    world_->loadLevel("castle.txt", 5);
    level_ = 5;
    particleSystem_->setLevel(level_);
}

void cGame::loadVolcano()
{
    particleSystem_->clearNonText();
    particleSystem_->addSmiley();
    cout << "loading volcano level" << endl;
    world_->unloadLevel();
    world_->loadLevel("volcano.txt", 2);
    level_ = 2;
    particleSystem_->setLevel(level_);
}

void cGame::loadEmpty()
{
    //particleSystem_->addSmiley();
    cout << "loading empty level for kludeishness" << endl;
    world_->loadLevel("empty.txt", 0);
    level_ = 0;
    particleSystem_->setLevel(level_);
    
}