#include <d3d8.h>

#include ".\GSGame.h"
#include ".\GSMenu.h"
#include ".\GSDone.h"
#include ".\LD.h"

#include ".\GameObject.h"
#include ".\Player.h"
#include ".\Plankton.h"
#include ".\Obstacle.h"
#include ".\HomingEnemy.h"



CGSGame::CGSGame()
{
  m_CurLevelNo = 1;
  PrepareLevel();

  /*
  for ( int i = 0; i < 20; ++i )
  {
    Plankton*   pPlankton = new Plankton();

    pPlankton->X = rand() % 640;
    pPlankton->Y = rand() % 480;

    m_Level.Objects.push_back( pPlankton );
  }

  Obstacle*  pObst = new Obstacle();
  pObst->X = 0;
  pObst->Y = 0;
  pObst->Width = 640;
  pObst->Height = 10;
  m_Level.Objects.push_back( pObst );

  pObst = new Obstacle();
  pObst->X = 0;
  pObst->Y = 0;
  pObst->Width = 10;
  pObst->Height = 480;
  m_Level.Objects.push_back( pObst );

  pObst = new Obstacle();
  pObst->X = 0;
  pObst->Y = 470;
  pObst->Width = 640;
  pObst->Height = 10;
  m_Level.Objects.push_back( pObst );

  pObst = new Obstacle();
  pObst->X = 630;
  pObst->Y = 0;
  pObst->Width = 10;
  pObst->Height = 470;
  m_Level.Objects.push_back( pObst );

  for ( int i = 0; i < 5; ++i )
  {
    HomingEnemy*   pEnemy = new HomingEnemy();

    pEnemy->X = rand() % 640;
    pEnemy->Y = rand() % 480;
    pEnemy->SizeFactor = 1.0f;

    m_Level.Objects.push_back( pEnemy );
  }

  Player*   pPlayer = new Player();
  pPlayer->X = 320;
  pPlayer->Y = 240;
  m_Level.Objects.push_back( pPlayer );
  m_Level.pPlayer = pPlayer;*/
}



CGSGame::~CGSGame(void)
{
}



void CGSGame::Display( IDirect3DDevice8* pDevice )
{
  theApp.m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

  /*
  theApp.RenderTextureSection2d( 0, 0, theApp.m_TexSec[LD::TEX_METAL_BACKGROUND] );
  theApp.RenderTextureSection2d( 0, 0, theApp.m_TexSec[LD::TEX_METAL_BACKGROUND] );
  theApp.RenderTextureSection2d( 0, 0, theApp.m_TexSec[LD::TEX_METAL_BACKGROUND] );
  theApp.RenderTextureSection2d( 0, 0, theApp.m_TexSec[LD::TEX_METAL_BACKGROUND] );
  theApp.RenderTextureSection2d( 0, 0, theApp.m_TexSec[LD::TEX_METAL_BACKGROUND] );*/

  /*
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
  theApp.m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
  */
  m_Level.Display();

  if ( m_PipetteActive )
  {
    int     pipetteImage = LD::TEX_PIPETTE_1;
    if ( m_PipetteStep >= 6 )
    {
      pipetteImage = LD::TEX_PIPETTE_5;
    }
    if ( ( m_PipetteStep >= 1 )
    &&   ( m_PipetteStep <= 5 ) )
    {
      pipetteImage += m_PipetteStep - 1;
    }
    theApp.RenderTextureSection2d( m_PipetteX, (int)m_PipetteY, theApp.m_TexSec[pipetteImage], 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 48, 256 );

    theApp.PrintNiceCentered( 320, 430, m_Level.Info.c_str() );
  }

  if ( m_LevelDone )
  {
    theApp.PrintNiceCenteredWavy( 320, 50, "WELL DONE" );
    theApp.Print( 230, 430, "Press SPACE to start next stage" );
  }

  if ( m_Level.pPlayer == NULL )
  {
    theApp.PrintNiceCenteredWavy( 320, 50, "YOU DIED", 0xffff8080 );
    theApp.Print( 240, 430, "Press SPACE to retry" );
  }

}



void CGSGame::UpdateFrame( const float ElapsedTime )
{
  if ( m_PipetteActive )
  {
    if ( m_Level.pPlayer == NULL )
    {
      return;
    }
    switch ( m_PipetteStep )
    {
      case 0:
        if ( m_PipetteY < m_Level.pPlayer->Y - 256 )
        {
          m_PipetteY += 300.0f * ElapsedTime;
          if ( m_PipetteY >= m_Level.pPlayer->Y - 256 )
          {
            m_PipetteY = m_Level.pPlayer->Y - 256.0f;
            ++m_PipetteStep;
          }
        }
        break;
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
        m_PipetteStepDelay += 2.0f * ElapsedTime;
        if ( m_PipetteStepDelay >= 0.5f )
        {
          m_PipetteStepDelay -= 0.5f;
          ++m_PipetteStep;
          if ( m_PipetteStep == 2 )
          {
            theApp.PlaySoundA( LD::SOUND_INJECT );
          }
          if ( m_PipetteStep == 4 )
          {
            m_Level.pPlayer->Hidden = false;
          }
        }
        break;
      case 6:
        if ( m_PipetteY > -256.0f )
        {
          m_PipetteY -= 300.0f * ElapsedTime;
          if ( m_PipetteY <= -256.0f )
          {
            m_PipetteActive = false;
          }
        }
        break;
    }
    return;
  }

  if ( m_Level.pPlayer == NULL )
  {
    if ( ( theApp.m_bKeyReleased[VK_SPACE] )
    &&   ( theApp.m_bKeyPressed[VK_SPACE] ) )
    {
      theApp.m_bKeyReleased[VK_SPACE] = false;
      PrepareLevel();
    }
    m_Level.UpdateFrame( ElapsedTime );
    return;
  }


  if ( !m_LevelDone )
  {
    bool    isDone = true;
    std::list<GameObject*>::iterator    itO( m_Level.Objects.begin() );
    while ( itO != m_Level.Objects.end() )
    {
      GameObject*   pObj( *itO );

      if ( ( pObj->m_Type == LD::GO_PLANKTON )
      ||   ( pObj->m_Type == LD::GO_SITTING_ENEMY )
      ||   ( pObj->m_Type == LD::GO_HOMING_ENEMY ) )
      {
        isDone = false;
        break;
      }
      ++itO;
    }
    m_LevelDone = isDone;
    if ( m_LevelDone )
    {
      theApp.StopSound( LD::SOUND_SLIME );
    }
  }

  if ( m_LevelDone )
  {
    if ( ( theApp.m_bKeyReleased[VK_SPACE] )
    &&   ( theApp.m_bKeyPressed[VK_SPACE] ) )
    {
      theApp.m_bKeyReleased[VK_SPACE] = false;
      ++m_CurLevelNo;
      PrepareLevel();
      return;
    }
  }
  m_Level.UpdateFrame( ElapsedTime );
}



void CGSGame::OnMouse( int X, int Y, int Buttons )
{

}



void CGSGame::OnChar( int iChar )
{
  if ( iChar == 'n' )
  {
    ++m_CurLevelNo;
    PrepareLevel();
  }
  else if ( iChar == 'r' )
  {
    PrepareLevel();
  }
  else if ( iChar == 27 )
  {
    theApp.NextState( new CGSMenu() );
  }
}



void CGSGame::OnKeyDown( int iChar )
{

}



void CGSGame::PrepareLevel()
{
  m_Level.Load( m_CurLevelNo );

  m_PipetteActive = true;
  m_PipetteY = -256.0f;
  m_PipetteStepDelay = 0.0f;
  m_PipetteStep = 0;
  m_LevelDone = false;

  if ( m_Level.pPlayer )
  {
    m_PipetteX = m_Level.pPlayer->X - 16;
    m_PipetteY = -256.0f;
    m_Level.pPlayer->Hidden = true;
  }
  else
  {
    theApp.NextState( new GSDone() );
  }
}