#include "BirdiesRevenge.h"

#include "GSMenu.h"
#include "GameLogic.h"

#include <Controls/Xtreme/GUIComponentDisplayer.h>



BirdiesRevenge           theApp;



BirdiesRevenge::BirdiesRevenge() :
  CXFrameApp()
{
  ConfigureApp( "Birdie's Revenge.assetproject", "GR Games\\Birdie's Revenge" );
}



BirdiesRevenge::~BirdiesRevenge()
{
}



bool BirdiesRevenge::InitInstance()
{
  if ( !CXFrameApp::InitInstance() )
  {
    return false;
  }

  if ( !RunDefaultModules() )
  {
    return false;
  }

  // first automated key binding
  if ( BoundKey( Birdie2::ControlKey::JUMP ) == Xtreme::KEY_INVALID )
  {
    if ( InputClass()->IsJoystickAvailable() )
    {
      SetKeyBinding( Birdie2::ControlKey::JUMP, InputClass()->MapKeyToVKey( Xtreme::JOYSTICK_1_BUTTON_1 ) );
      SetKeyBinding( Birdie2::ControlKey::ACTION, InputClass()->MapKeyToVKey( Xtreme::JOYSTICK_1_BUTTON_2 ) );
      SetKeyBinding( Birdie2::ControlKey::LEFT, InputClass()->MapKeyToVKey( Xtreme::JOYSTICK_1_LEFT ) );
      SetKeyBinding( Birdie2::ControlKey::RIGHT, InputClass()->MapKeyToVKey( Xtreme::JOYSTICK_1_RIGHT ) );
    }
    else
    {
      SetKeyBinding( Birdie2::ControlKey::JUMP, InputClass()->MapKeyToVKey( Xtreme::KEY_UP ) );
      SetKeyBinding( Birdie2::ControlKey::ACTION, InputClass()->MapKeyToVKey( Xtreme::KEY_SPACE ) );
      SetKeyBinding( Birdie2::ControlKey::LEFT, InputClass()->MapKeyToVKey( Xtreme::KEY_LEFT ) );
      SetKeyBinding( Birdie2::ControlKey::RIGHT, InputClass()->MapKeyToVKey( Xtreme::KEY_RIGHT ) );
    }
  }

  GameLogic::EnemyInfos[Birdie2::UT_AUFZIEH] = Birdie2::EnemyInfo( Birdie2::UT_AUFZIEH, "Aufzieh.X" );
  GameLogic::EnemyInfos[Birdie2::UT_BIRD] = Birdie2::EnemyInfo( Birdie2::UT_BIRD, "Bird.X" );
  GameLogic::EnemyInfos[Birdie2::UT_BAT] = Birdie2::EnemyInfo( Birdie2::UT_BAT, "Bat.X" );
  GameLogic::EnemyInfos[Birdie2::UT_THING] = Birdie2::EnemyInfo( Birdie2::UT_THING, "Thing.X" );
  GameLogic::EnemyInfos[Birdie2::UT_PUMPKIN] = Birdie2::EnemyInfo( Birdie2::UT_PUMPKIN, "Pumpkin.X" );

  // TODO - das ist NICHT schön hier!
  InitialiseImplementationSpecificAssets();

  m_pRenderClass->SetState( XRenderer::RS_MINFILTER, XRenderer::RSV_FILTER_POINT );
  m_pRenderClass->SetState( XRenderer::RS_MAGFILTER, XRenderer::RSV_FILTER_POINT );
  m_pRenderClass->SetState( XRenderer::RS_MIPFILTER, XRenderer::RSV_FILTER_POINT );
  m_pRenderClass->SetState( XRenderer::RS_LIGHTING, XRenderer::RSV_DISABLE );

  XMaterial       mat;

  ZeroMemory( &mat, sizeof( XMaterial ) );
  mat.m_dwAmbient = 0xff808080;
  m_pRenderClass->SetMaterial( mat );

  m_GUI.AddListener( &m_StateManager );

  m_StateManager.PushState( new CGSMenu() );
  return true;

}



void BirdiesRevenge::ExitInstance()
{
  m_StateManager.PopAllStates();

  CXFrameApp::ExitInstance();
}



void BirdiesRevenge::RenderBackground( XRenderer& Renderer, const std::string& Image )
{
  Renderer.SetShader( XRenderer::ST_FLAT );

  XTextureSection   tsBG( Section( Image ) );

  for ( int i = 0; i < (int)Renderer.Width() / 40; ++i )
  {
    for ( int j = 0; j < (int)Renderer.Height() / 40; ++j )
    {
      Renderer.RenderTextureSection2d( i * 40, j * 40, tsBG );
    }
  }
}



void BirdiesRevenge::PlaySong( const std::string& Song )
{
  if ( m_ActiveSong != Song )
  {
    if ( m_ActiveSong.empty() )
    {
      // first song
      MusicClass()->SetVolume( 0 );

      m_MusicFadeIn = true;
      m_ActiveSong = Song;
      MusicClass()->LoadMusic( CMisc::AppPath( "sounds/%s.ogg", Song.c_str() ).c_str() );
      MusicClass()->Play();
    }
    else
    {
      m_NextSong = Song;
      m_MusicFadeOut = true;
      m_MusicFadeIn = false;
    }
  }
}



bool BirdiesRevenge::ProcessEvent( const GR::Gamebase::tXFrameEvent& Event )
{
  switch ( Event.m_Type )
  {
    case GR::Gamebase::tXFrameEvent::ET_RENDERER_SWITCHED:
      break;
    case GR::Gamebase::tXFrameEvent::ET_DISPLAY_MODE_CHANGED:
      break;
  }
  return CXFrameApp::ProcessEvent( Event );
}



bool BirdiesRevenge::ProcessEvent( const GUI::OutputEvent& Event )
{
  if ( m_StateManager.ProcessEvent( Event ) )
  {
    return true;
  }
  return false;
}



void BirdiesRevenge::UpdatePerDisplayFrame( const float fElapsedTime )
{
  if ( m_MusicFadeOut )
  {
    m_TempVolume -= 50.0f * fElapsedTime;
    if ( m_TempVolume <= 0.0f )
    {
      m_MusicFadeOut = false;
      m_MusicFadeIn = true;

      m_ActiveSong = m_NextSong;
      m_NextSong = "";

      MusicClass()->SetVolume( 0 );
      MusicClass()->LoadMusic( CMisc::AppPath( "sounds/%s.ogg", m_ActiveSong.c_str() ).c_str() );
      MusicClass()->Play();
    }
    else
    {
      MusicClass()->SetVolume( (int)m_TempVolume );
    }
  }
  else if ( m_MusicFadeIn )
  {
    m_TempVolume += 50.0f * fElapsedTime;
    if ( m_TempVolume >= GetVarI( "Music.Volume" ) )
    {
      m_MusicFadeIn = false;

      MusicClass()->SetVolume( GetVarI( "Music.Volume" ) );
    }
    else
    {
      MusicClass()->SetVolume( (int)m_TempVolume );
    }
  }

  m_GUI.UpdateAllControls( fElapsedTime );
}



void BirdiesRevenge::UpdateFixedLogic()
{
  // Game-States
  m_StateManager.UpdateCurrentState();
}



void BirdiesRevenge::PrintText( int X, int Y, const std::string& Text )
{
  XFont*    pFont = theApp.Font( "Game" );

  m_pRenderClass->RenderText2d( pFont, X, Y, Text.c_str(), 2.0f, 2.0f, 0xffffffff );
}



void BirdiesRevenge::PrintTextCentered( int X, int Y, const std::string& Text )
{
  XFont*    pFont = theApp.Font( "Game" );

  int   textWidth = pFont->TextLength( Text.c_str() ) * 2;

  m_pRenderClass->RenderText2d( pFont, X - textWidth / 2, Y, Text.c_str(), 2.0f, 2.0f, 0xffffffff );
}



INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
  theApp.Create( WS_VISIBLE | WS_OVERLAPPED | WS_SYSMENU | WS_DLGFRAME, 800, 600, "Birdie's Revenge", 0, IDI_ICON_3DAPP, 0 );

  theApp.Run();

  return 0;
}

