void CCoherentUISystem::SetTexturesForListeners()
    {
        CCoherentViewListener* pListener = NULL;

        // Create HUD texture
        pListener = ( m_HudViewListener ? m_HudViewListener.get() : NULL );

        if ( pListener && pListener->GetTexture() == NULL )
        {
            void* pD3DTextureDst = NULL;
            ITexture* pCryTex = gD3DSystem->CreateTexture(
                                    &pD3DTextureDst,
                                    gEnv->pRenderer->GetWidth(),
                                    gEnv->pRenderer->GetHeight(),
                                    1,
                                    eTF_A8R8G8B8,
                                    FT_USAGE_DYNAMIC
                                );

            pListener->SetTexture( pD3DTextureDst, pCryTex->GetTextureID() );
        }

        // Create textures for entities
        for ( View::const_iterator iter = m_Views.begin(); iter != m_Views.end(); ++iter )
        {
            pListener = iter->first;

            if ( pListener && pListener->GetTexture() == NULL )
            {
                ChangeEntityDiffuseTextureForMaterial( pListener, pListener->GetEngineObjectName(), pListener->GetOverriddenMaterialName() );
            }
        }
    }
    bool CCoherentUISystem::RaycastClosestViewListenersGeometry( const Vec3& origin, const Vec3& dir, int& outX, int& outY, CCoherentViewListener*& pViewListener )
    {
        // check hud view
        if ( m_HudViewListener )
        {
            float t;
            int x, y;
            if ( m_HudViewListener->RaycastGeometry( origin, dir, t, x, y ) )
            {
                outX = x;
                outY = y;
                pViewListener = m_HudViewListener.get();

                return true;
            }
        }
		

        // check other views
        float minDist = std::numeric_limits<float>::max();
        int viewX;
        int viewY;
        CCoherentViewListener* pHitListener = NULL;

        for ( View::const_iterator iter = m_Views.begin(); iter != m_Views.end(); ++iter )
        {
            CCoherentViewListener* pListener = iter->first;

            float t;
            int x, y;

            if ( pListener->RaycastGeometry( origin, dir, t, x, y ) )
            {
                if ( t < minDist )
                {
                    minDist = t;
                    viewX = x;
                    viewY = y;

                    pHitListener = pListener;
                }
            }
        }

        if ( pHitListener != NULL )
        {
            outX = viewX;
            outY = viewY;
            pViewListener = pHitListener;

            return true;
        }

        return false;
    }
    virtual void ProcessEvent( EFlowEvent evt, SActivationInfo* pActInfo )
    {
        switch ( evt )
        {
        case eFE_Suspend:
            pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
            break;

        case eFE_Resume:
            pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
            break;

        case eFE_Initialize:
            break;

        case eFE_Activate:
        {
            if ( IsPortActive( pActInfo, EIP_ACTIVATE ) ) {
                m_iViewId = GetPortInt( pActInfo, EIP_VIEWID );
                m_bHandlerRegistered = false;
                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
            }
        }
        break;

        case eFE_Update:
            if ( !m_bHandlerRegistered )
            {
                CCoherentViewListener* pViewListener = gCoherentUISystem->GetViewListener( m_iViewId );
                if ( pViewListener && pViewListener->IsReadyForBindings() )
                {
                    Coherent::UI::View* pView = pViewListener->GetView();
                    if ( pView )
                    {
                        std::string sEvent = GetPortString( pActInfo, EIP_EVENT );
                        pView->RegisterForEvent( sEvent.c_str(), Coherent::UI::MakeHandler(this, &CFlowCUIHandleEvent::HandleEvent));
                        m_bHandlerRegistered = true;
                    }
                }
            }
            if ( m_bReceivedEvent )
            {
                m_bReceivedEvent = false;
                string strArg = m_event.strArg.c_str();
                ActivateOutput( pActInfo, EIP_ARG1, strArg );
                ActivateOutput( pActInfo, EIP_ARG2, m_event.boolArg );
            }
            break;
        }
    }
    void CCoherentUISystem::UpdateHUD()
    {
        static Vec3 lastPosition = Vec3Constants<Vec3::value_type>::fVec3_Zero;
        static float lastRotation = 0;

        CCoherentViewListener* pHUDListener = NULL;
        pHUDListener = ( m_HudViewListener ? m_HudViewListener.get() : NULL );

        if ( pHUDListener )
        {
            CCamera& camera = gEnv->pSystem->GetViewCamera();
            Vec3 viewDir = camera.GetViewdir();
            float rotation = cry_atan2f( viewDir.y, viewDir.x ) * 180.0f / 3.14159f;
            // Adjust rotation so it is the same as in the game
            rotation = -rotation - 135.0f;
            Coherent::UI::View* pView = pHUDListener->GetView();

            if ( pView && pHUDListener->IsReadyForBindings() )
            {
                if ( rotation != lastRotation )
                {
                    pView->TriggerEvent( "SetAbsoluteCompassRotation", rotation );
                    // Adjust the rotation for the map, too...
                    pView->TriggerEvent( "SetPlayerRotationOnMap", rotation - 45.0f );

                    lastRotation = rotation;
                }

                Vec3 cameraPosition = camera.GetPosition();

                if ( ( cameraPosition - lastPosition ).GetLengthSquared() > VEC_EPSILON )
                {
                    pView->TriggerEvent( "SetPlayerPositionOnMap", cameraPosition.x, cameraPosition.y );

                    lastPosition = cameraPosition;
                }
            }
        }
    }
    CCoherentViewListener* CCoherentUISystem::CreateView( ViewConfig* pConfig )
    {
        CCoherentViewListener* pViewListener = new CCoherentViewListener();

        if ( !pConfig->CollisionMesh.empty() )
        {
            pViewListener->SetCollisionMesh( pConfig->CollisionMesh.c_str() );
        }

        string entityName;

        if ( pConfig->Entity )
        {
            entityName = pConfig->Entity->GetName();
        }

        pViewListener->SetEngineObjectAndMaterialNames( entityName, pConfig->MaterialName.c_str() );

        m_pUISystem->CreateView( pConfig->ViewInfo, pConfig->Url.c_str(), pViewListener );

        m_Views.insert( View::value_type( pViewListener, pConfig ) );
        return pViewListener;
    }
            virtual void ProcessEvent( EFlowEvent evt, SActivationInfo* pActInfo )
            {
                switch ( evt )
                {
                    case eFE_Suspend:
                        break;

                    case eFE_Resume:
                        break;

                    case eFE_Initialize:
                        INITIALIZE_OUTPUTS( pActInfo );
                        break;

                    case eFE_SetEntityId:
                        m_pEntity = pActInfo->pEntity;
                        break;

                    case eFE_Activate:
                        if ( IsPortActive( pActInfo, EIP_ACTIVATE ) && m_pEntity )
                        {
                            // get the view definition
                            std::string sUrl = GetPortString( pActInfo, EIP_URL );
                            std::wstring sUrlW( sUrl.length(), L' ' );
                            sUrlW.assign( sUrl.begin(), sUrl.end() );

                            Coherent::UI::ViewInfo info;
                            info.Width = GetPortInt( pActInfo, EIP_WIDTH );
                            info.Height = GetPortInt( pActInfo, EIP_HEIGHT );
                            info.IsTransparent = GetPortBool( pActInfo, EIP_TRANSPARENT );
                            info.UsesSharedMemory = GetPortBool( pActInfo, EIP_SHARED_MEMORY );
                            info.SupportClickThrough = GetPortBool( pActInfo, EIP_CLICKABLE );

                            m_pViewConfig->ViewInfo = info;
                            m_pViewConfig->Url = sUrlW;
                            m_pViewConfig->Entity = m_pEntity;
                            m_pViewConfig->CollisionMesh = GetPortString( pActInfo, EIP_MESH );

                            // indicate that we have to create/update the view later
                            m_bViewNeedsUpdate = true;
                            pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
                        }

                        break;

                    case eFE_Update:
                        // make sure the view is created/updated, after the system is ready
                        if ( m_bViewNeedsUpdate &&  gCoherentUISystem->IsReady() )
                        {
                            if ( m_pViewListener )
                            {
                                gCoherentUISystem->DeleteView( m_pViewListener );
                            }
                            m_pViewListener = gCoherentUISystem->CreateView( m_pViewConfig );
                            m_bViewNeedsUpdate = false;
                        }

                        // set the view id output after the view is available
                        if ( m_pViewListener )
                        {
                            Coherent::UI::View* view = m_pViewListener->GetView();
                            if ( view )
                            {
                                ActivateOutput<int>( pActInfo, EOP_VIEWID, view->GetId() );
                                // updates are not necessary until next initialization
                                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
                            }
                        }
                        break;
                }
            }
            virtual void ProcessEvent( EFlowEvent evt, SActivationInfo* pActInfo )
            {
                switch ( evt )
                {
                    case eFE_Suspend:
                        break;

                    case eFE_Resume:
                        break;

                    case eFE_Initialize:
                        INITIALIZE_OUTPUTS( pActInfo );
                        break;

                    case eFE_Activate:
                        {
                            if ( IsPortActive( pActInfo, EIP_ACTIVATE ) )
                            {
                                // get the view definition
                                std::string sPath = GetPortString( pActInfo, EIP_PATH );
                                m_sPathW.assign( sPath.begin(), sPath.end() );

                                // indicate that we have to create/update the view later
                                m_bViewNeedsUpdate = true;
                                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true );
                            }
                        }
                        break;

                    case eFE_Update:
                        // make sure the view is created, after the system is ready
                        if ( m_bViewNeedsUpdate &&  gCoherentUISystem->IsReady() )
                        {
                            if ( m_pViewListener )
                            {
                                // update only
                                Coherent::UI::View* view = m_pViewListener->GetView();
                                view->Load( m_sPathW.c_str() );
                                view->Reload( true );
                            }
                            else
                            {
                                // create
                                m_pViewListener = gCoherentUISystem->CreateHUDView( m_sPathW );
                            }
                            m_bViewNeedsUpdate = false;
                        }

                        // set the view id output after the view is available
                        if ( m_pViewListener )
                        {
                            Coherent::UI::View* view = m_pViewListener->GetView();
                            if ( view )
                            {
                                ActivateOutput<int>( pActInfo, EOP_VIEWID, view->GetId() );
                                // updates are not necessary until next initialization
                                pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
                            }
                        }
                        break;
                }
            }