/********************************************************************

  Module: TitanUI

  Author: Jon Wiesman (not originally, but assuming ownership)

  Description:

  TODO

  Copyright 2006 Sony Online Entertainment.  All rights reserved.

*********************************************************************/

#ifndef __TITANUI_H__
#define __TITANUI_H__

#include "TitanI.h"
#include "TitanController.h"
#include "InputConsole.h"
#include "TiBitmapInfo.h"
#include "TiMiniMap.h"
#include "SyResourceID.h"
#include "SyMaterial.h"
#include "SyString.h"
#include "SyHavokEnable.h"
#include <map>


class RawController;
class SyCollide;  
class SyDictionary;
class SyInputConsole;
class SyParameterValidator;
class SyPerformanceStats;
class SyRaster;   
class SyScene;    
class SySimpleMaterial;
class SySoundDevice; 
class TiCommandMessage;
class TiGameWindow;
class TitanI;
class TiUIControl;
class TiStartWindow;
class TiSceneController;
class TitanApp;
class SyESFParse;
struct SyWaterSystem;
class TiUI;
class TiConsoleWindow;

#ifdef HAVOK_ENABLED
class SyHavok;
#endif

class TitanUI : public TitanUII
{
public:
  TitanUI();
  virtual ~TitanUI();

  int Init();

  // Get the scene titan can use for drawing
  virtual SyScene* GetScene();
  virtual SyPerformanceStats* GetPerformanceStats();
  virtual SyInputConsole* GetInputConsole();
  virtual int GetBloomEffectHandle();

  // Get a pointer to an interface that can be used to poll a controller state
  virtual TitanControllerI* GetController( int controllerId );

  virtual TiUII*          GetUII();
  virtual TiUI*           GetUI() const { return( mpUI ); }
  virtual SyESFParse&     GetESFParser() const { return( *mpESFParser ); }
  virtual bool            GetDisplayStats() const;
  virtual bool            GetShowUI() const { return( mShowUI ); }
  virtual TitanOptionsI*  GetOptions() { return( mpOptions ); }
  virtual void            SetMinimap(const SyString&  textureName,
                                     const SyVect2&   worldPos1,
                                     const SyVect2&   worldPos2,
                                     const SyVect2&   mapPos1,
                                     const SyVect2&   mapPos2,
                                     SyRaster*        raster,
                                     SyDictionary*    dictionary);

  static TitanButton GetTitanButton( int buttonIndex );
  static int         GetButtonIndex( TitanButton titanButton );
  static int         GetAxisIndex( int titanAxis);

  virtual uint64 GetTime();

  typedef enum
  {
    CONTROLLER_MAPPING_PS2,
    CONTROLLER_MAPPING_AIRFLO,
    CONTROLLER_MAPPING_LOGITECH,
  } eControllerMapping;
  static void        SetControllerMapping(eControllerMapping mapping);

  virtual int       PawnDebugUI(const char *src, int linenum, const char *variables);
  void              PawnDebugOutput(const char *output);

  virtual void      ProcessCommandMessage( TiCommandMessage* pMessage );

  void Main();
  void OnFrame();

  void ProcessInput();
  void ProcessUI();

  void OnChar( int data, int mouseX, int mouseY, bool shiftDown, bool controlDown, bool altDown, bool extendedKey );
  void OnKeyDown( SyInputEvent::KeyCode data, int mouseX, int mouseY, bool shiftDown, bool controlDown, bool altDown, bool extendedKey );
  void OnKeyUp( SyInputEvent::KeyCode data, int mouseX, int mouseY, bool shiftDown, bool controlDown, bool altDown, bool extendedKey );

  void OnControllerAxisMove( int deviceId, int axisX, int axisY, int buttonStates );
  void OnControllerButtonDown( int deviceId, int buttonId, int axisX, int axisY, int buttonStates );
  void OnControllerButtonUp( int deviceId, int buttonId, int axisX, int axisY, int buttonStates );
  void OnControllerConnect( int deviceId, int axisX, int axisY, int buttonStates );
  void OnControllerDisconnect( int deviceId, int axisX, int axisY, int buttonStates );

  // add parameters to the SyParameterValidator that this object is interested in
  void InitParameterValidator( SyParameterValidator* parameterValidator );

  void UpdateInputConsole();
  void UpdatePhysics( float deltatime );
  const SyString& GetCurrentLevelFilename() const { return( mCurrentLevelFilename ); }

  // added by Jon Wiesman
  virtual void  BeginLetterbox(bool bInstant = false);
  virtual void  EndLetterbox(bool bInstant = false);
  virtual bool  IsLetterboxMode() const {return m_eLetterbox != LM_Normal;}
  virtual void  FadeOut(float32 fTransition);
  virtual void  FadeIn(float32 fTransition);
  virtual void  FadeAndExit(float32 fDelayBeforeFading, float32 fFadeDuration);
  virtual bool  IsExiting() {return FAE_Normal != m_eFadeAndExit;}


  virtual void  SetPaused( int i )                { mbHardPause = i; }
  virtual void  SetHavokStabilizeAndExit( int i ) { mbHardPause = 1; mbStabilizeHavokObjects = 1; mbExitAfterStabilize = 1; }
  virtual void  SetHavokRagdoll( int i );

  virtual TitanI  *GetTitanI() {return mpTitan;}
  static TitanUI  *Instance() {return sm_pSingleton;}


  void		UpdateCharacterData();


private:
  enum GameMode
  {
    kGameModeNone
    , kGameModeFrontScreen
    , kGameModeGame
  };

    // game mode control
  void      SetDesiredGameMode(GameMode mode);      // causes mode change to be deferred until main loop (this is needed because otherwise changing modes would destroy objects that were on the call-stack)
  void      SetGameMode(GameMode mode);     // changes to the specified game mode (does this by calling clearing current game mode first)
  void      ClearCurrentGameMode();         // clears current game mode (put game in kGameModeNone state)

    // initialization of framework stuff
  int       FrameworkCreate();              // create the game framework (called only on application startup)
  void      FrameworkDestroy();             // destroys the game framework (called only on application shutdown)
  int       FrameworkReset();               // resets all the framework objects to their initial state without actually destroying and re-creating them.

    // currently interface is destroyed and recreated with each game mode change because the interface has asset handles
    // that get invalidated when the dictionary is cleared, which happens on all mode changes. - JEFFP
  void      InterfaceCreate();              // creates all the interface elements (called everytime game mode changes)
  void      InterfaceDestroy();             // destroys all the interface elements (called everytime game mode changes)

    // game mode functions
  void      OnFrameGame();
  int       InitGame();
  int       ClearGame();

    // front screen mode functions
  void      OnFrameFrontScreen();
  int       InitFrontScreen();
  int       ClearFrontScreen();

    // common functions
  int       InitCommon();
  int       ClearCommon();

    // helper functions
  int       LoadAtlasDirectory( const char8* pFilename );
  void      InputConsoleCreate(int width, int height);      // creates the SyInputConsole used to manage controller and keyboard input (helper function for FrameworkCreate)
  void      LoadLevel( const SyString& Filename );
  void      LoadStartScene();
  SyString  GetStartupLevel();

  void      SetDisplaySize( int32 Width, int32 Height );
  void      ScreenCap();
  void      DrawStats();
  void      DrawVersion();

  void      ProcessStartMessage( TiCommandMessage* pMessage );
  void      ProcessGotoLevelMessage( TiCommandMessage* pMessage );
  // added by Jon Wiesman
  void      ProcessLetterbox(float32 fElapsed);
  void      ProcessFade(float32 fElapsed);
  void      ProcessFadeAndExit(float32 fElapsed);

private:

  SyParameterValidator* mpParameters;

  GameMode            mMode;
  GameMode            mDesiredMode;

  RawController*      mRawController;
  std::map<int,TitanController*> mControllers;

  std::map< SyResourceID, TiBitmapInfo > mAtlasDirectory;

  SyInputConsole*     mpInputConsole;
  SyScene*            mpScene;
  SyRaster*           mpRaster;
  SyDictionary*       mpDictionary;
  SyCollide*          mpCollide;
  SySoundDevice*      mpSoundDevice;
  SyWaterSystem*      mpWaterSystem;
#ifdef HAVOK_ENABLED
  SyHavok*            mpPhysics;
#endif

  int                 mBloomEffectHandle;
  int32               mFontHandle;

  SyPerformanceStats* mpPerformanceStats;
  int                 mbHardPause;
  int                 mbStabilizeHavokObjects;
  int                 mbExitAfterStabilize;

  SySimpleMaterial*   mpAtlasMaterial;
  int                 mAtlasMaterialHandle;
  int                 mAtlasSurfaceHandle;

  TitanI*             mpTitan;

  TitanApp*           mpTitanApp;
  TiUI*               mpUI;
  TiUIControl*        mpStats;
  TiGameWindow*       mpGameWindow;
  TiStartWindow*      mpStartWindow;
  TiSceneController*  mpSceneControl; // for the front screens

  // Console Window stuff (Jon Wiesman)
  static TitanUI      *sm_pSingleton; // Sorry, boys.  I need it.
  bool                m_bConsoleActive;
  TiConsoleWindow     *m_pConsoleWindow;
  // Letterbox stuff (Jon Wiesman)
  enum ELetterboxMode
  {
    LM_Normal,
    LM_Shrinking,
    LM_Expanding,
    LM_Letterbox,
  };
  enum EFadeMode
  {
    FM_Normal,
    FM_FadingOut,
    FM_FadingIn,
    FM_Faded,
  };
  enum EFadeAndExitMode
  {
    FAE_Normal,
    FAE_WaitingToFade,
    FAE_Fading,
    FAE_Exiting,
  };
  ELetterboxMode      m_eLetterbox;
  float32             m_fLetterboxProgress;
  EFadeMode           m_eFade;
  float32             m_fFadeProgress;
  float32             m_fFadeTransition;
  EFadeAndExitMode    m_eFadeAndExit;
  float32             m_fFAEWaitTime;
  float32             m_fFAEFadeTime;
  float32             m_fFAEProgress;


  SyString            mMovieFilename;
  int                 mMovieFrame;
  SyString            mCurrentLevelFilename;

  SyESFParse*         mpESFParser;

  SyTime              mLastMouseEvent;

  bool                mShowStats;
  bool                mShowVersion;
  bool                mShowUI;
  bool                mShowPlayerPos;

  TitanOptionsI*      mpOptions;

  int32				  m_nGameToLoad;

};

#endif // __TITANUI_H__
