//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================

#include "dme_controls/dmedagrenderpanel.h"
#include "movieobjects/dmedag.h"
#include "movieobjects/dmemodel.h"
#include "movieobjects/timeutils.h"
#include "movieobjects/dmeanimationlist.h"
#include "movieobjects/dmeclip.h"
#include "movieobjects/dmechannel.h"
#include "movieobjects/dmemdlmakefile.h"
#include "movieobjects/dmedccmakefile.h"
#include "movieobjects/dmemesh.h"
#include "movieobjects/dmedrawsettings.h"
#include "dme_controls/dmepanel.h"
#include "tier1/KeyValues.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "tier3/tier3.h"
#include "materialsystem/imaterialsystemhardwareconfig.h"
#include "materialsystem/imesh.h"
#include "vgui_controls/Menu.h"
#include "vgui_controls/MenuBar.h"
#include "vgui_controls/MenuButton.h"
#include "vgui/IVGui.h"


//-----------------------------------------------------------------------------
//
// Hook into the dme panel editor system
//
//-----------------------------------------------------------------------------
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDag, "DmeDagRenderer", "DmeDag Preview Renderer", false );
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceSkin, "DmeSourceSkinPreview", "MDL Skin Previewer", false );
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceAnimation, "DmeSourceAnimationPreview", "MDL Animation Previewer", false );
IMPLEMENT_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDCCMakefile, "DmeMakeFileOutputPreview", "DCC MakeFile Output Preview", false );


//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CDmeDagRenderPanel::CDmeDagRenderPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
{											 
	// Used to poll input
	vgui::ivgui()->AddTickSignal( GetVPanel() );

	m_bDrawJointNames = false;
	m_bDrawJoints = false;
	m_bDrawGrid = true;

	// Deal with the default cubemap
	ITexture *pCubemapTexture = g_pMaterialSystem->FindTexture( "editor/cubemap", NULL, true );
	m_DefaultEnvCubemap.Init( pCubemapTexture );
	pCubemapTexture = g_pMaterialSystem->FindTexture( "editor/cubemap.hdr", NULL, true );
	m_DefaultHDREnvCubemap.Init( pCubemapTexture );

	m_pDrawSettings = CreateElement< CDmeDrawSettings >( "drawSettings", g_pDataModel->FindOrCreateFileId( "DagRenderPanelDrawSettings" ) );
	m_hDrawSettings = m_pDrawSettings;

	m_pMenuBar = new vgui::MenuBar( this, "Dag Render Panel Menu Bar" );

	m_pShadingMenu = new vgui::Menu( NULL, "Shading Menu" );
	m_nMenuSmoothShade = m_pShadingMenu->AddCheckableMenuItem( "&Smooth Shade", new KeyValues( "SmoothShade" ), this );
	m_nMenuFlatShade = m_pShadingMenu->AddCheckableMenuItem( "&Flat Shade", new KeyValues( "FlatShade" ), this );
	m_nMenuWireframe = m_pShadingMenu->AddCheckableMenuItem( "&Wireframe", new KeyValues( "Wireframe" ), this );
	m_pShadingMenu->AddSeparator();
	m_nMenuBoundingBox = m_pShadingMenu->AddCheckableMenuItem( "&Bounding Box", new KeyValues( "BoundingBox" ), this );
	m_pShadingMenu->AddSeparator();	// Bug is visibility
	m_nMenuNormals = m_pShadingMenu->AddCheckableMenuItem( "&Normals", new KeyValues( "Normals" ), this );
	m_nMenuWireframeOnShaded = m_pShadingMenu->AddCheckableMenuItem( "WireFrame &On Shaded", new KeyValues( "WireframeOnShaded" ), this );
	m_nMenuBackfaceCulling = m_pShadingMenu->AddCheckableMenuItem( "&Backface Culling", new KeyValues( "BackfaceCulling" ), this );
	m_nMenuXRay = m_pShadingMenu->AddCheckableMenuItem( "&X-Ray", new KeyValues( "XRay" ), this );
	m_nMenuGrayShade = m_pShadingMenu->AddCheckableMenuItem( "&Gray Shade", new KeyValues( "GrayShade" ), this );

	// For now...
	m_pShadingMenu->SetItemVisible( m_nMenuFlatShade, false );
	m_pShadingMenu->SetItemEnabled( m_nMenuFlatShade, false );
	m_pShadingMenu->SetItemVisible( m_nMenuBoundingBox, false );
	m_pShadingMenu->SetItemEnabled( m_nMenuBoundingBox, false );
	m_pShadingMenu->SetItemVisible( m_nMenuBackfaceCulling, false );
	m_pShadingMenu->SetItemEnabled( m_nMenuBackfaceCulling, false );
	m_pShadingMenu->SetItemVisible( m_nMenuXRay, false );
	m_pShadingMenu->SetItemEnabled( m_nMenuXRay, false );

	m_pMenuBar->AddMenu( "&Shading", m_pShadingMenu );

	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmeDagRenderPanel::~CDmeDagRenderPanel()
{
}


//-----------------------------------------------------------------------------
// Scheme settings
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
	BaseClass::ApplySchemeSettings( pScheme );
	SetBorder( pScheme->GetBorder( "MenuBorder") );
	m_hFont = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
}


//-----------------------------------------------------------------------------
// Set the scene
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::SetDmeElement( CDmeDag *pScene )
{
	m_hDag = pScene;
	ComputeDefaultTangentData( m_hDag, false );
}


//-----------------------------------------------------------------------------
// Other methods which hook into DmePanel
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::SetDmeElement( CDmeSourceSkin *pSkin )
{
	// First, try to grab the dependent makefile
	CDmeMakefile *pSourceMakefile = pSkin->GetDependentMakefile();
	if ( !pSourceMakefile )
	{
		m_hDag = NULL;
		return;
	}

	// Next, try to grab the output of that makefile
	CDmElement *pOutput = pSourceMakefile->GetOutputElement( true );
	if ( !pOutput )
	{
		m_hDag = NULL;
		return;
	}

	// Finally, grab the 'skin' attribute of that makefile
	m_hDag = pOutput->GetValueElement< CDmeDag >( "model" );
	ComputeDefaultTangentData( m_hDag, false );
	DrawJoints( false );
	DrawJointNames( false );
}

void CDmeDagRenderPanel::SetDmeElement( CDmeSourceAnimation *pAnimation )
{
	// First, try to grab the dependent makefile
	CDmeMakefile *pSourceMakefile = pAnimation->GetDependentMakefile();
	if ( !pSourceMakefile )
	{
		m_hDag = NULL;
		return;
	}

	// Next, try to grab the output of that makefile
	CDmElement *pOutput = pSourceMakefile->GetOutputElement( true );
	if ( !pOutput )
	{
		m_hDag = NULL;
		return;
	}

	// Finally, grab the 'model' or 'skeleton' attribute of that makefile
	CDmeDag *pDag = pOutput->GetValueElement< CDmeDag >( "model" );
	if ( !pDag )
	{
		pDag = pOutput->GetValueElement< CDmeDag >( "skeleton" ); 
	}
	if ( !pDag )
		return;

	CDmeAnimationList *pAnimationList = pOutput->GetValueElement< CDmeAnimationList >( "animationList" );
	if ( !pAnimationList )
		return;

	if ( pAnimationList->FindAnimation( pAnimation->m_SourceAnimationName ) < 0 )
		return;

	m_hDag = pDag;
	ComputeDefaultTangentData( m_hDag, false );
	m_hAnimationList = pAnimationList;
	SelectAnimation( pAnimation->m_SourceAnimationName );
	DrawJoints( true );
	DrawJointNames( true );
}

void CDmeDagRenderPanel::SetDmeElement( CDmeDCCMakefile *pDCCMakefile )
{
	// First, try to grab the dependent makefile
	CDmElement *pOutputElement = pDCCMakefile->GetOutputElement( true );
	if ( !pOutputElement )
	{
		m_hDag = NULL;
		return;
	}

	// Finally, grab the 'model' or 'skeleton' attribute of that makefile
	CDmeDag *pDag = pOutputElement->GetValueElement< CDmeDag >( "model" );
	if ( !pDag )
	{
		pDag = pOutputElement->GetValueElement< CDmeDag >( "skeleton" ); 
	}
	if ( !pDag )
		return;

	CDmeAnimationList *pAnimationList = pOutputElement->GetValueElement< CDmeAnimationList >( "animationList" );

	m_hDag = pDag;
	ComputeDefaultTangentData( m_hDag, false );
	m_hAnimationList = pAnimationList;
	SelectAnimation( 0 );
	DrawJoints( pAnimationList != NULL );
	DrawJointNames( pAnimationList != NULL );
}

CDmeDag *CDmeDagRenderPanel::GetDmeElement()
{
	return m_hDag;
}


//-----------------------------------------------------------------------------
// Draw joint names
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::DrawJointNames( CDmeDag *pRoot, CDmeDag *pDag, const matrix3x4_t& parentToWorld )
{
	CDmeTransform *pJointTransform = pDag->GetTransform();
	int nJointIndex = -1;

	CDmeModel *pRootModel = CastElement<CDmeModel>( pRoot );
	if ( pRootModel )
	{
		nJointIndex = pRootModel->GetJointTransformIndex( pJointTransform );
		if ( nJointIndex < 0 && pRootModel != pDag )
			return;
	}

	matrix3x4_t jointToParent, jointToWorld;
	pJointTransform->GetTransform( jointToParent );
	ConcatTransforms( parentToWorld, jointToParent, jointToWorld );

	CDmeJoint *pJoint = CastElement< CDmeJoint >( pDag );
	if ( pJoint )
	{
		Vector vecJointOrigin;
		MatrixGetColumn( jointToWorld, 3, &vecJointOrigin );

		Vector2D vecPanelPos;
		ComputePanelPosition( vecJointOrigin, &vecPanelPos );

		char pJointName[512];
		if ( nJointIndex >= 0 )
		{
			Q_snprintf( pJointName, sizeof(pJointName), "%d : %s", nJointIndex, pJoint->GetName() );
		}
		else
		{
			Q_snprintf( pJointName, sizeof(pJointName), "%s", pJoint->GetName() );
		}
		g_pMatSystemSurface->DrawColoredText( m_hFont, vecPanelPos.x + 5, vecPanelPos.y, 255, 255, 255, 255, pJointName );
	}

	int nCount = pDag->GetChildCount();
	for ( int i = 0; i < nCount; ++i )
	{
		CDmeDag *pChild = pDag->GetChild(i);
		if ( !pChild )
			continue;

		DrawJointNames( pRoot, pChild, jointToWorld );
	}
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnSmoothShade()
{
	if ( m_pShadingMenu->IsChecked( m_nMenuSmoothShade ) )
	{
		m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_SMOOTH );
	}
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnFlatShade()
{
	if ( m_pShadingMenu->IsChecked( m_nMenuFlatShade ) )
	{
		m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_FLAT );
	}
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnWireframe()
{
	if ( m_pShadingMenu->IsChecked( m_nMenuWireframe ) )
	{
		m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_WIREFRAME );
	}
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnBoundingBox()
{
	if ( m_pShadingMenu->IsChecked( m_nMenuBoundingBox ) )
	{
		m_pDrawSettings->SetDrawType( CDmeDrawSettings::DRAW_BOUNDINGBOX );
	}
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnNormals()
{
	m_pDrawSettings->SetNormals( m_pShadingMenu->IsChecked( m_nMenuNormals ) );
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnWireframeOnShaded()
{
	m_pDrawSettings->SetWireframeOnShaded( m_pShadingMenu->IsChecked( m_nMenuWireframeOnShaded ) );
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnBackfaceCulling()
{
	m_pDrawSettings->SetBackfaceCulling( m_pShadingMenu->IsChecked( m_nMenuBackfaceCulling ) );
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnXRay()
{
	m_pDrawSettings->SetXRay( m_pShadingMenu->IsChecked( m_nMenuXRay ) );
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnGrayShade()
{
	m_pDrawSettings->SetGrayShade( m_pShadingMenu->IsChecked( m_nMenuGrayShade ) );
	UpdateMenu();
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnFrame()
{
	if ( !m_hDag )
		return;

	float flRadius;
	Vector vecCenter, vecWorldCenter;
	m_hDag->GetBoundingSphere( vecCenter, flRadius );

	matrix3x4_t dmeToEngine;
	CDmeDag::DmeToEngineMatrix( dmeToEngine );
	VectorTransform( vecCenter, dmeToEngine, vecWorldCenter );
	LookAt( vecWorldCenter, flRadius );
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::PerformLayout()
{
	BaseClass::PerformLayout();

	if ( m_pMenuBar->IsVisible() )
	{
		int iWidth;
		int iHeight;
		GetSize( iWidth, iHeight );

		int iMenuWidth;	// Unused
		int iMenuHeight;
		m_pMenuBar->GetSize( iMenuWidth, iMenuHeight );
		m_pMenuBar->SetSize( iWidth, iMenuHeight );
	}
}


//-----------------------------------------------------------------------------
// paint it!
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::Paint()
{
	if ( m_hCurrentAnimation.Get() )
	{
		DmeTime_t currentTime( Plat_FloatTime() - m_flStartTime );
		if ( m_hCurrentAnimation->GetDuration() != DMETIME_ZERO )
		{
			currentTime = currentTime % m_hCurrentAnimation->GetDuration();
		}
		else
		{
			currentTime = DMETIME_ZERO;
		}
		currentTime += m_hCurrentAnimation->GetStartTime();
		DmeTime_t mediaTime = m_hCurrentAnimation->ToChildMediaTime( currentTime, true );

		int nChannelCount = m_hCurrentAnimation->m_Channels.Count();
		for ( int i = 0; i < nChannelCount; ++i )
		{
			m_hCurrentAnimation->m_Channels[i]->SetCurrentTime( mediaTime );
		}
	}

	if ( m_hCurrentVertexAnimation.Get() )
	{
		DmeTime_t currentTime( Plat_FloatTime() - m_flStartTime );
		currentTime = currentTime % m_hCurrentVertexAnimation->GetDuration();
		currentTime += m_hCurrentVertexAnimation->GetStartTime();
		DmeTime_t mediaTime = m_hCurrentVertexAnimation->ToChildMediaTime( currentTime, true );

		int nChannelCount = m_hCurrentVertexAnimation->m_Channels.Count();
		for ( int i = 0; i < nChannelCount; ++i )
		{
			m_hCurrentVertexAnimation->m_Channels[i]->SetCurrentTime( mediaTime );
		}
	}

	// FIXME: Shouldn't this happen at the application level?
	// run the machinery - apply, resolve, dependencies, operate, resolve
	{
		CDisableUndoScopeGuard guard;
		g_pDmElementFramework->SetOperators( m_operators );
		g_pDmElementFramework->Operate( true );
	}

	// allow elements and attributes to be edited again
	g_pDmElementFramework->BeginEdit();

	BaseClass::Paint();

	// Overlay the joint names
	if ( m_bDrawJointNames && m_hDag )
	{
		matrix3x4_t modelToWorld;
		CDmeDag::DmeToEngineMatrix( modelToWorld );
		DrawJointNames( m_hDag, m_hDag, modelToWorld );
	}
}


//-----------------------------------------------------------------------------
// Indicate we should draw joint names
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::DrawJointNames( bool bDrawJointNames )
{
	m_bDrawJointNames = bDrawJointNames;
}


//-----------------------------------------------------------------------------
// Indicate we should draw joints
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::DrawJoints( bool bDrawJoint )
{
	m_bDrawJoints = bDrawJoint;
}


//-----------------------------------------------------------------------------
// Indicate we should draw the grid
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::DrawGrid( bool bDrawGrid )
{
	m_bDrawGrid = bDrawGrid;
}


//-----------------------------------------------------------------------------
// paint it!
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnPaint3D()
{
	CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
	ITexture *pLocalCube = pRenderContext->GetLocalCubemap();
	if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
	{
		pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
	}
	else
	{
		pRenderContext->BindLocalCubemap( m_DefaultHDREnvCubemap );
	}

	if ( m_bDrawGrid )
	{
		BaseClass::DrawGrid();
	}

	if ( m_bDrawJoints )
	{
		CDmeJoint::DrawJointHierarchy( true );
	}

	pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
	CDmeDag::DrawUsingEngineCoordinates( true );
	m_pDrawSettings->DrawDag( m_hDag );
	CDmeDag::DrawUsingEngineCoordinates( false );

	pRenderContext->Flush();
	pRenderContext->BindLocalCubemap( pLocalCube );
}


//-----------------------------------------------------------------------------
// input
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnMouseDoublePressed( vgui::MouseCode code )
{
	OnFrame();

	BaseClass::OnMouseDoublePressed( code );
}


//-----------------------------------------------------------------------------
// TODO: Have a whole groovy keybinding thingy like SFM
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::OnKeyCodePressed( vgui::KeyCode code )
{
	BaseClass::OnKeyCodePressed( code );

	if ( code == KEY_F )
	{
		OnFrame();
	}
}


//-----------------------------------------------------------------------------
// Rebuilds the list of operators
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::RebuildOperatorList( )
{
	m_operators.RemoveAll();

	if ( m_hCurrentAnimation.Get() )
	{
		int nChannelCount = m_hCurrentAnimation->m_Channels.Count();
		for ( int i = 0; i < nChannelCount; ++i )
		{
			m_hCurrentAnimation->m_Channels[i]->SetMode( CM_PLAY );
			m_operators.AddToTail( m_hCurrentAnimation->m_Channels[i] );
		}
	}

	if ( m_hCurrentVertexAnimation.Get() )
	{
		int nChannelCount = m_hCurrentVertexAnimation->m_Channels.Count();
		for ( int i = 0; i < nChannelCount; ++i )
		{
			m_hCurrentVertexAnimation->m_Channels[i]->SetMode( CM_PLAY );
			m_operators.AddToTail( m_hCurrentVertexAnimation->m_Channels[i] );
		}
	}

	m_flStartTime = Plat_FloatTime();
}

//-----------------------------------------------------------------------------
// Select animation by index
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::SelectAnimation( int nIndex )
{
	m_hCurrentAnimation = NULL;
	if ( m_hAnimationList.Get() && ( nIndex >= 0 ) )
	{
		// FIXME: How is this actually going to work?
		m_hCurrentAnimation = m_hAnimationList->GetAnimation( nIndex );
	}
	RebuildOperatorList();
}

void CDmeDagRenderPanel::SelectVertexAnimation( int nIndex )
{
	m_hCurrentVertexAnimation = NULL;
	if ( m_hVertexAnimationList.Get() && ( nIndex >= 0 ) )
	{
		// FIXME: How is this actually going to work?
		m_hCurrentVertexAnimation = m_hVertexAnimationList->GetAnimation( nIndex );
	}
	RebuildOperatorList();
}


//-----------------------------------------------------------------------------
// Select animation by name
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::SelectAnimation( const char *pAnimName )
{
	if ( !pAnimName[0] )
	{
		SelectAnimation( -1 );
		return;
	}

	if ( m_hAnimationList )
	{
		int nIndex = m_hAnimationList->FindAnimation( pAnimName );
		if ( nIndex >= 0 )
		{
			SelectAnimation( nIndex );
		}
	}
}

void CDmeDagRenderPanel::SelectVertexAnimation( const char *pAnimName )
{
	if ( !pAnimName[0] )
	{
		SelectVertexAnimation( -1 );
		return;
	}

	if ( m_hVertexAnimationList )
	{
		int nIndex = m_hVertexAnimationList->FindAnimation( pAnimName );
		if ( nIndex >= 0 )
		{
			SelectVertexAnimation( nIndex );
		}
	}
}


//-----------------------------------------------------------------------------
// Sets animation
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::SetAnimationList( CDmeAnimationList *pAnimationList )
{
	m_hAnimationList = pAnimationList;
	int nCount = pAnimationList ? pAnimationList->GetAnimationCount() : 0;
	if ( nCount == 0 )
	{
		m_hCurrentAnimation = NULL;
		return;
	}

	SelectAnimation( 0 );
}


void CDmeDagRenderPanel::SetVertexAnimationList( CDmeAnimationList *pAnimationList )
{
	m_hVertexAnimationList = pAnimationList;
	int nCount = pAnimationList ? pAnimationList->GetAnimationCount() : 0;
	if ( nCount == 0 )
	{
		m_hCurrentVertexAnimation = NULL;
		return;
	}

	SelectVertexAnimation( 0 );
}


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDagRenderPanel::UpdateMenu()
{
	switch ( m_pDrawSettings->GetDrawType() )
	{
	case CDmeDrawSettings::DRAW_FLAT:
		m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, true );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, false );
		break;
	case CDmeDrawSettings::DRAW_WIREFRAME:
		m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, true );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, false );
		break;
	case CDmeDrawSettings::DRAW_BOUNDINGBOX:
		m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, true );
		break;
	default:
		m_pShadingMenu->SetMenuItemChecked( m_nMenuSmoothShade, true );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuFlatShade, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframe, false );
		m_pShadingMenu->SetMenuItemChecked( m_nMenuBoundingBox, false );
		break;
	}

	m_pShadingMenu->SetMenuItemChecked( m_nMenuNormals, m_pDrawSettings->GetNormals() );
	m_pShadingMenu->SetMenuItemChecked( m_nMenuWireframeOnShaded, m_pDrawSettings->GetWireframeOnShaded() );
	m_pShadingMenu->SetMenuItemChecked( m_nMenuBackfaceCulling, m_pDrawSettings->GetBackfaceCulling() );
	m_pShadingMenu->SetMenuItemChecked( m_nMenuXRay, m_pDrawSettings->GetXRay() );
	m_pShadingMenu->SetMenuItemChecked( m_nMenuGrayShade, m_pDrawSettings->GetGrayShade() );
}