ExampleApp::ExampleApp(Eegeo::EegeoWorld* pWorld,
                       const Eegeo::Rendering::ScreenProperties& screenProperties)
	: m_pCameraControllerFactory(NULL)
	, m_pCameraTouchController(NULL)
	, m_pWorld(pWorld)
    , m_pLoadingScreen(NULL)
    , m_screenPropertiesProvider(screenProperties)
{
	Eegeo::EegeoWorld& eegeoWorld = *pWorld;

	Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration touchControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration::CreateDefault();

	m_pCameraTouchController = new Eegeo::Camera::GlobeCamera::GlobeCameraTouchController(touchControllerConfig,
                                                                                          m_screenPropertiesProvider.GetScreenProperties());

	const bool useLowSpecSettings = false;
	Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration globeCameraControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration::CreateDefault(useLowSpecSettings);

    Eegeo::Modules::Map::MapModule& mapModule = eegeoWorld.GetMapModule();
    Eegeo::Modules::Map::Layers::TerrainModelModule& terrainModelModule = eegeoWorld.GetTerrainModelModule();
    
    const bool twoFingerPanTiltEnabled = true;
    const float interestPointLatitudeDegrees = 37.793436f;
    const float interestPointLongitudeDegrees = -122.398654f;
    const float interestPointAltitudeMeters = 2.7f;
    const float cameraControllerOrientationDegrees = 0.0f;
    const float cameraControllerDistanceFromInterestPointMeters = 1781.0f;
    
    m_pCameraControllerFactory = new Examples::DefaultCameraControllerFactory(
                                                                    terrainModelModule,
                                                                    mapModule,
                                                                    *m_pCameraTouchController,
                                                                    m_screenPropertiesProvider,
                                                                    globeCameraControllerConfig,
                                                                    twoFingerPanTiltEnabled,
                                                                    interestPointLatitudeDegrees,
                                                                    interestPointLongitudeDegrees,
                                                                    interestPointAltitudeMeters,
                                                                    cameraControllerOrientationDegrees,
                                                                    cameraControllerDistanceFromInterestPointMeters);
    
    m_pLoadingScreen = CreateLoadingScreen(screenProperties, eegeoWorld.GetRenderingModule(), eegeoWorld.GetPlatformAbstractionModule());
    
    m_pCameraController = m_pCameraControllerFactory->Create();
}
/**
*
* This function processes the game's logic cycle
*
* @author Daniel Jay
* @param _fDeltaTick The difference in time between the current and last frames
*
*/
void 
CTotalCubeDomination::Process(float32 _fDeltaTick)
{
	if(true == m_bIsLoading)
	{
		CreateLoadingScreen();
		m_pLoadingScreen->Process(_fDeltaTick);

		m_bIsLoading = false;
		//m_bIsStartingGame = true;
	}
	else if(true == m_bChangeToGame)
	{
		m_bChangeToGame = false;

		SetProgramState(new CGameState);
	}
	else if(true == m_bChangeToMenu)
	{
		m_bChangeToMenu = false;

		SetProgramState(new CMenuState);
	}
	else
	{
		delete m_pLastState;
		m_pLastState = 0;

		CInputHandler::GetInstance().Update();

		if (m_pState)
		{
			m_pState->Process(_fDeltaTick);
		}
	}
}
/**
*
* This function clears the renderer's buffers
*
* @author Daniel Jay
* @param _hInstance The red component of the colour
* @param _hWnd The green component of the colour
* @param _iWidth The blue component of the colour
* @param _iHeight The blue component of the colour
* @param _bFullscreen The blue component of the colour
* @return The success or failure of the initialisation
*
*/
bool 
CTotalCubeDomination::Initialise(HINSTANCE _hInstance, HWND _hWnd, int32 _iWidth, int32 _iHeight, bool _bFullscreen)
{
	m_hApplicationInstance = _hInstance;
	m_hMainWindow = _hWnd;

#ifdef _DEBUG
	for (int32 i = 0; i < LOG_MESSAGE_MAX; ++i)
	{
		m_apLogManager[i] = new CLogManager;
	}

	{
		CLogFile* pLogFile = new CLogFile;
		pLogFile->Initialise("init.log");

		m_apLogManager[LOG_MESSAGE_INIT]->AddLogTarget(pLogFile);

		CLogDebugOutput* pOutput = new CLogDebugOutput;

		m_apLogManager[LOG_MESSAGE_INIT]->AddLogTarget(pOutput);

		pLogFile = new CLogFile;
		pLogFile->Initialise("paths.log");
		m_apLogManager[LOG_MESSAGE_PATHS]->AddLogTarget(pLogFile);
		pOutput = new CLogDebugOutput;
		m_apLogManager[LOG_MESSAGE_PATHS]->AddLogTarget(pOutput);

		pLogFile = new CLogFile;
		pLogFile->Initialise("sound.log");
		m_apLogManager[LOG_MESSAGE_SOUND]->AddLogTarget(pLogFile);
		pOutput = new CLogDebugOutput;
		m_apLogManager[LOG_MESSAGE_SOUND]->AddLogTarget(pOutput);

		//pLogFile = new CLogFile;
		//pLogFile->Initialise("tower.log");
		//m_apLogManager[LOG_MESSAGE_TOWER]->AddLogTarget(pLogFile);
		pOutput = new CLogDebugOutput;
		m_apLogManager[LOG_MESSAGE_OUTPUT]->AddLogTarget(pOutput);

		// Test harness logging file.
		pLogFile = new CLogFile;
		pLogFile->Initialise("tests.log");

		m_apLogManager[LOG_MESSAGE_TEST]->AddLogTarget(pLogFile);
	}
#endif // _DEBUG

	m_pClock = new CPerformanceClock;

	if (!m_pClock->Initialise())
	{
#ifdef _DEBUG
	LogMessage("Performance counter failed, using system clock", LOG_MESSAGE_INIT);
#endif // _DEBUG

		m_pClock = new CSystemClock;
	}

	VALIDATE(m_pClock->Initialise());
	m_pClock->Process();

	m_pRenderer = new CRenderer;

	VALIDATE(m_pRenderer->Initialise(_hWnd, _iWidth, _iHeight, _bFullscreen));
	m_pRenderer->SetClearColour(0.0f, 0.0f, 0.0f);

    D3DMATERIAL9 material;

    ZeroMemory(&material, sizeof(material) );
    material.Ambient.a = 1.0f;
    material.Ambient.g = 1.0f;
    material.Ambient.r = 1.0f;
    material.Ambient.b = 1.0f;

    m_pRenderer->GetDevice()->SetMaterial(&material);

	VALIDATE(CInputHandler::GetInstance().Initialise(m_hApplicationInstance, m_hMainWindow));

	CreateLoadingScreen();

	ChangeToMenuState();
	//SetProgramState(new CMenuState);

	ShowCursor(false);

#ifdef _DEBUG
	/*// Instantiate test harness manager.
	m_pTestManager = new CTestManager();

	//Set up
	m_pTestManager->SetUp();

	//Run tests
	m_pTestManager->RunTest();

	//Tear down
	m_pTestManager->TearDown();

	delete m_pTestManager;
	m_pTestManager = 0;*/
#endif // _DEBUG

#ifdef _DEBUG
	LogMessage("Initialisation successful", LOG_MESSAGE_INIT);
#endif // _DEBUG

	return (true);
}
    MobileExampleApp::MobileExampleApp(
        const std::string& apiKey,
        Eegeo::Modules::IPlatformAbstractionModule& platformAbstractions,
        Eegeo::Rendering::ScreenProperties& screenProperties,
        Eegeo::Location::ILocationService& locationService,
        Eegeo::UI::NativeUIFactories& nativeUIFactories,
        Eegeo::Config::PlatformConfig platformConfig,
        Eegeo::Helpers::Jpeg::IJpegLoader& jpegLoader,
        ExampleApp::InitialExperience::SdkModel::IInitialExperienceModule& initialExperienceModule,
        ExampleApp::PersistentSettings::IPersistentSettingsModel& persistentSettings,
        ExampleAppMessaging::TMessageBus& messageBus,
        ExampleAppMessaging::TSdkModelDomainEventBus& sdkModelDomainEventBus,
        Net::SdkModel::INetworkCapabilities& networkCapabilities,
        ExampleApp::Search::SdkModel::ISearchServiceModule& searchServiceModule,
        ExampleApp::Metrics::IMetricsService& metricsService,
        const ExampleApp::ApplicationConfig::ApplicationConfiguration& applicationConfiguration,
        Eegeo::IEegeoErrorHandler& errorHandler)
        : m_pGlobeCameraController(NULL)
        , m_pCameraTouchController(NULL)
        , m_pCurrentTouchController(NULL)
        , m_pNavigationService(NULL)
        , m_pWorld(NULL)
        , m_platformAbstractions(platformAbstractions, networkCapabilities)
        , m_pLoadingScreen(NULL)
        , m_pinDiameter(48.f)
        , m_initialisedApplicationViewState(false)
        , m_pCameraTransitionController(NULL)
        , m_pSecondaryMenuModule(NULL)
        , m_pSearchResultMenuModule(NULL)
        , m_pModalityModule(NULL)
        , m_pCategorySearchModule(NULL)
        , m_pMapModeModule(NULL)
        , m_pFlattenButtonModule(NULL)
        , m_pSearchModule(NULL)
        , m_pPinIconsTexturePageLayout(NULL)
        , m_pPinsModule(NULL)
        , m_pWorldPinsModule(NULL)
        , m_pSearchResultOnMapModule(NULL)
        , m_pReactionModelModule(NULL)
        , m_pReactionControllerModule(NULL)
        , m_pSearchResultPoiModule(NULL)
        , m_pPlaceJumpsModule(NULL)
        , m_pWeatherMenuModule(NULL)
        , m_pCompassModule(NULL)
        , m_pGpsMarkerModule(NULL)
        , m_pWorldAreaLoaderModule(NULL)
        , m_pAboutPageModule(NULL)
        , m_initialExperienceModule(initialExperienceModule)
        , m_pBlitter(NULL)
        , m_messageBus(messageBus)
        , m_sdkDomainEventBus(sdkModelDomainEventBus)
        , m_persistentSettings(persistentSettings)
        , m_pMyPinCreationModule(NULL)
        , m_pPoiRingModule(NULL)
        , m_pMyPinCreationDetailsModule(NULL)
        , m_pMyPinsModule(NULL)
        , m_pMyPinDetailsModule(NULL)
        , m_pOptionsModule(NULL)
        , m_pWatermarkModule(NULL)
        , m_pInteriorsExplorerModule(NULL)
        , m_pInteriorsEntitiesPinsModule(NULL)
        , m_screenProperties(screenProperties)
        , m_networkCapabilities(networkCapabilities)
        , m_setMetricsLocation(false)
        , m_searchServiceModule(searchServiceModule)
        , m_metricsService(metricsService)
        , m_applicationConfiguration(applicationConfiguration)
        , m_interiorsEnabled(platformConfig.OptionsConfig.EnableInteriors)
    {
        m_metricsService.BeginSession(ExampleApp::FlurryApiKey, EEGEO_PLATFORM_VERSION_NUMBER);

        m_pBlitter = Eegeo_NEW(Eegeo::Blitter)(1024 * 128, 1024 * 64, 1024 * 32);
        m_pBlitter->Initialise();
        
        m_pWorld = Eegeo_NEW(Eegeo::EegeoWorld)(apiKey,
                                                m_platformAbstractions,
                                                jpegLoader,
                                                screenProperties,
                                                locationService,
                                                *m_pBlitter,
                                                nativeUIFactories,
                                                Eegeo::EnvironmentCharacterSet::Latin,
                                                platformConfig,
                                                NULL,
                                                "http://cdn1.eegeo.com/coverage-trees/vglobal/v742/manifest.txt.gz",
                                                "http://d2xvsc8j92rfya.cloudfront.net/mobile-themes-new/v366/manifest.txt.gz",
                                                &errorHandler
                                                );

        Eegeo::Modules::Map::Layers::TerrainModelModule& terrainModelModule = m_pWorld->GetTerrainModelModule();
        Eegeo::Modules::Map::MapModule& mapModule = m_pWorld->GetMapModule();

        m_pNavigationService = Eegeo_NEW(Eegeo::Location::NavigationService)(&m_pWorld->GetLocationService(),
                               &terrainModelModule.GetTerrainHeightProvider());

        Eegeo::Camera::GlobeCamera::GpsGlobeCameraControllerFactory cameraControllerFactory(terrainModelModule.GetTerrainHeightProvider(),
                mapModule.GetEnvironmentFlatteningService(),
                mapModule.GetResourceCeilingProvider(),
                *m_pNavigationService);

        m_pAppModeModel = Eegeo_NEW(AppModes::SdkModel::AppModeModel)(m_pWorld->GetMapModule().GetInteriorsPresentationModule().GetInteriorSelectionModel(), m_messageBus);

        const bool useLowSpecSettings = false;

        Eegeo::Camera::GlobeCamera::GpsGlobeCameraComponentConfiguration gpsGlobeCameraConfig = Eegeo::Camera::GlobeCamera::GpsGlobeCameraComponentConfiguration::CreateDefault();
        gpsGlobeCameraConfig.panToUnlockThreshold =  0.03f;
        Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration touchControllerConfig = Eegeo::Camera::GlobeCamera::GlobeCameraTouchControllerConfiguration::CreateDefault();
        Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration globeCameraConfig = Eegeo::Camera::GlobeCamera::GlobeCameraControllerConfiguration::CreateDefault(useLowSpecSettings);

        m_pGlobeCameraController = cameraControllerFactory.Create(gpsGlobeCameraConfig, touchControllerConfig, globeCameraConfig, m_screenProperties);

        m_pCameraTouchController = &m_pGlobeCameraController->GetTouchController();

        Eegeo::Camera::GlobeCamera::GlobeCameraTouchSettings touchSettings = m_pGlobeCameraController->GetGlobeCameraController().GetTouchSettings();
        touchSettings.TiltEnabled = true;
        m_pGlobeCameraController->GetGlobeCameraController().SetTouchSettings(touchSettings);

        Eegeo::Space::LatLongAltitude location = m_applicationConfiguration.InterestLocation();
        float cameraControllerOrientationDegrees = m_applicationConfiguration.OrientationDegrees();
        float cameraControllerDistanceFromInterestPointMeters = m_applicationConfiguration.DistanceToInterestMetres();

        Eegeo::Space::EcefTangentBasis cameraInterestBasis;
        Eegeo::Camera::CameraHelpers::EcefTangentBasisFromPointAndHeading(location.ToECEF(), cameraControllerOrientationDegrees, cameraInterestBasis);

        m_pGlobeCameraController->SetView(cameraInterestBasis, cameraControllerDistanceFromInterestPointMeters);

        m_pCameraTransitionController = Eegeo_NEW(ExampleApp::CameraTransitions::SdkModel::CameraTransitionController)(*m_pGlobeCameraController, *m_pNavigationService, terrainModelModule.GetTerrainHeightProvider());

        m_pStreamingVolume = Eegeo_NEW(Eegeo::Streaming::CameraFrustumStreamingVolume)(mapModule.GetResourceCeilingProvider(),
                                                                                       Eegeo::Config::LodRefinementConfig::GetLodRefinementAltitudesForDeviceSpec(platformConfig.PerformanceConfig.DeviceSpecification),
                                                                                       Eegeo::Streaming::QuadTreeCube::MAX_DEPTH_TO_VISIT,
                                                                                       mapModule.GetEnvironmentFlatteningService());
        
        CreateApplicationModelModules();
        
        m_pLoadingScreen = CreateLoadingScreen(screenProperties, m_pWorld->GetRenderingModule(), m_pWorld->GetPlatformAbstractionModule());


        
        if(m_applicationConfiguration.TryStartAtGpsLocation())
        {
            m_pNavigationService->SetGpsMode(Eegeo::Location::NavigationService::GpsModeFollow);
        }
    }