#include <AfxWin.h>
#include <AfxExt.h>
#define INITGUID
#include <ddraw.h>
#include <d3d.h>
#include <d3drm.h>
#include <d3drmwin.h>
#include "SpotWin.h"
#include "resource.h"

#pragma comment (lib,"ddraw.lib")
#pragma comment (lib,"d3drm.lib")


BEGIN_MESSAGE_MAP(SpotWin, RMWin)
	//{{AFX_MSG_MAP(SpotWin)
	ON_COMMAND(ID_RENDER_WIREFRAME, OnRenderWireframe)
	ON_COMMAND(ID_RENDER_FLAT, OnRenderFlat)
	ON_COMMAND(ID_RENDER_GOURAUD, OnRenderGouraud)
	ON_UPDATE_COMMAND_UI(ID_RENDER_FLAT, OnUpdateRenderFlat)
	ON_UPDATE_COMMAND_UI(ID_RENDER_GOURAUD, OnUpdateRenderGouraud)
	ON_UPDATE_COMMAND_UI(ID_RENDER_WIREFRAME, OnUpdateRenderWireframe)
	ON_COMMAND(ID_BEAM_NARROW, OnBeamNarrow)
	ON_COMMAND(ID_BEAM_NORMAL, OnBeamNormal)
	ON_COMMAND(ID_BEAM_WIDE, OnBeamWide)
	ON_UPDATE_COMMAND_UI(ID_BEAM_NARROW, OnUpdateBeamNarrow)
	ON_UPDATE_COMMAND_UI(ID_BEAM_NORMAL, OnUpdateBeamNormal)
	ON_UPDATE_COMMAND_UI(ID_BEAM_WIDE, OnUpdateBeamWide)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

char meshname[]="D:\\mssdk\\samples\\Multimedia\\D3DRM\\media\\sphere4.x";

SpotWin::SpotWin()
{
	meshbuilder=0;
}

BOOL SpotWin::CreateScene()
{
	HRESULT r;
	// ------- MESH --------
	d3drm->CreateMeshBuilder( &meshbuilder );
	r=meshbuilder->Load( meshname, NULL, D3DRMLOAD_FROMFILE, NULL, NULL );
	if (r!=D3DRM_OK)
	{
		CString msg;
		msg.Format( "Failed to load file '%s'\n", meshname );
		AfxMessageBox( msg );
		return FALSE;
	}
	//ScaleMesh( meshbuilder, D3DVALUE(25) );

    meshbuilder->SetColorRGB(D3DVALUE(1.0), D3DVALUE(0.0), D3DVALUE(0.0) );
    meshbuilder->CreateMesh( &mesh1 );
    meshbuilder->SetColorRGB(D3DVALUE(0.0), D3DVALUE(1.0), D3DVALUE(0.0) );
    meshbuilder->CreateMesh( &mesh2 );
    meshbuilder->SetColorRGB(D3DVALUE(0.0), D3DVALUE(0.0), D3DVALUE(1.0) );
    meshbuilder->CreateMesh( &mesh3 );
    meshbuilder->Release();
    meshbuilder=0;

    //----- MESH FRAMES ÔÐÅÉÌÛ ÑÅÒÎÊ --------
    LPDIRECT3DRMFRAME frame1;
    d3drm->CreateFrame( scene, &frame1 );
    frame1->SetPosition( scene,
            D3DVALUE(-2), D3DVALUE(0), D3DVALUE(0) );
    frame1->AddVisual( mesh1 );
    frame1->Release();
    frame1=0;

    LPDIRECT3DRMFRAME frame2;
    d3drm->CreateFrame( scene, &frame2 );
    frame2->SetPosition(scene,
            D3DVALUE(2), D3DVALUE(0), D3DVALUE(0) );
    frame2->AddVisual( mesh2 );
    frame2->Release();
    frame2=0;

    LPDIRECT3DRMFRAME frame3;
    d3drm->CreateFrame( scene, &frame3 );
    frame3->SetPosition(scene,
            D3DVALUE(0), D3DVALUE(0), D3DVALUE(2) );
    frame3->AddVisual( mesh3 );
    frame3->Release();
    frame3=0;


	// ---------SPOT LIGHT--------
	d3drm->CreateLightRGB( D3DRMLIGHT_SPOT,
			D3DVALUE(1.00), D3DVALUE(1.00), D3DVALUE(0.50), 
			&spotlight);
	OnBeamNormal();

	LPDIRECT3DRMFRAME slightframe;
	d3drm->CreateFrame( scene, &slightframe );
	slightframe->AddLight( spotlight );
	slightframe->SetPosition ( scene, 
			D3DVALUE(0),D3DVALUE(10),D3DVALUE(-10) );
	slightframe->SetOrientation( scene, 
			D3DVALUE(0), D3DVALUE(-10), D3DVALUE(10),
			D3DVALUE(0), D3DVALUE(1), D3DVALUE(0));
	slightframe->AddMoveCallback( MoveLight, NULL );
	slightframe->Release();
	slightframe=0;

	//------ CAMERA-----------
	d3drm->CreateFrame( scene, &camera );
    camera->SetPosition( scene,
            D3DVALUE(0), D3DVALUE(6), D3DVALUE(-6) );
    camera->SetOrientation( scene,
            D3DVALUE(0), D3DVALUE(-1), D3DVALUE(1.1),
            D3DVALUE(0), D3DVALUE(1), D3DVALUE(0) );
	d3drm->CreateViewport( device, camera, 0, 0,	
			device->GetWidth(), device->GetHeight(), 
			&viewport);

	return TRUE;
}

void SpotWin::MoveLight(LPDIRECT3DRMFRAME lightframe, void*, D3DVALUE)
{
	// move the spotlight over the meshes
	static const D3DVALUE LIM = D3DVALUE(0.3);
	static D3DVALUE xi = D3DVALUE(0.01);
	static D3DVALUE yi = D3DVALUE(0.005);
	static D3DVALUE x, y;
	if (x<-LIM || x>LIM)
		xi=-xi;
	if (y<-LIM || y>LIM)
		yi=-yi;
	x+=xi;
	y+=yi;
	lightframe->SetOrientation( NULL, 
		x, y-1, D3DVALUE(1),
		D3DVALUE(0), D3DVALUE(1), D3DVALUE(0));
}

void SpotWin::OnRenderWireframe() 
{
	if (meshbuilder)
		meshbuilder->SetQuality( D3DRMRENDER_WIREFRAME );
    mesh1->SetGroupQuality( 0, D3DRMRENDER_WIREFRAME );
    mesh2->SetGroupQuality( 0, D3DRMRENDER_WIREFRAME );
    mesh3->SetGroupQuality( 0, D3DRMRENDER_WIREFRAME );
}

void SpotWin::OnRenderFlat() 
{
	if (meshbuilder)
		meshbuilder->SetQuality( D3DRMRENDER_FLAT );
    mesh1->SetGroupQuality( 0, D3DRMRENDER_FLAT );
    mesh2->SetGroupQuality( 0, D3DRMRENDER_FLAT );
    mesh3->SetGroupQuality( 0, D3DRMRENDER_FLAT );
}

void SpotWin::OnRenderGouraud() 
{
	if (meshbuilder)
		meshbuilder->SetQuality( D3DRMRENDER_GOURAUD );
    mesh1->SetGroupQuality( 0, D3DRMRENDER_GOURAUD );
    mesh2->SetGroupQuality( 0, D3DRMRENDER_GOURAUD );
    mesh3->SetGroupQuality( 0, D3DRMRENDER_GOURAUD );
}

void SpotWin::OnUpdateRenderWireframe(CCmdUI* pCmdUI) 
{
	if (meshbuilder)
	{
		D3DRMRENDERQUALITY meshquality = meshbuilder->GetQuality();
		pCmdUI->SetCheck( meshquality==D3DRMRENDER_WIREFRAME );
	}
    D3DRMRENDERQUALITY quality=mesh1->GetGroupQuality( 0 );
    pCmdUI->SetCheck( quality==D3DRMRENDER_WIREFRAME );
}

void SpotWin::OnUpdateRenderFlat(CCmdUI* pCmdUI) 
{
	if (meshbuilder)
	{
		D3DRMRENDERQUALITY meshquality = meshbuilder->GetQuality();
		pCmdUI->SetCheck( meshquality==D3DRMRENDER_FLAT );
	}
    D3DRMRENDERQUALITY quality=mesh1->GetGroupQuality( 0 );
    pCmdUI->SetCheck( quality==D3DRMRENDER_FLAT );
}

void SpotWin::OnUpdateRenderGouraud(CCmdUI* pCmdUI) 
{
	if (meshbuilder)
	{
		D3DRMRENDERQUALITY meshquality = meshbuilder->GetQuality();
		pCmdUI->SetCheck( meshquality==D3DRMRENDER_GOURAUD );
	}
    D3DRMRENDERQUALITY quality=mesh1->GetGroupQuality( 0 );
    pCmdUI->SetCheck( quality==D3DRMRENDER_GOURAUD );
}

void SpotWin::OnBeamNarrow() 
{
	// TODO: Add your command handler code here
    spotlight->SetUmbra( D3DVALUE(0.1) );
    spotlight->SetPenumbra( D3DVALUE(0.2) );
    beamwidth=BEAM_NARROW;
	
}

void SpotWin::OnBeamNormal() 
{
	// TODO: Add your command handler code here
    spotlight->SetUmbra( D3DVALUE(0.2) );
    spotlight->SetPenumbra( D3DVALUE(0.4) );
    beamwidth=BEAM_NORMAL;
	
}

void SpotWin::OnBeamWide() 
{
	// TODO: Add your command handler code here
    spotlight->SetUmbra( D3DVALUE(0.4) );
    spotlight->SetPenumbra( D3DVALUE(0.8) );
    beamwidth=BEAM_WIDE;
	
}

void SpotWin::OnUpdateBeamNarrow(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    pCmdUI->SetCheck( beamwidth==BEAM_NARROW );	
}

void SpotWin::OnUpdateBeamNormal(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    pCmdUI->SetCheck( beamwidth==BEAM_NORMAL );	
}

void SpotWin::OnUpdateBeamWide(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
    pCmdUI->SetCheck( beamwidth==BEAM_WIDE );	
}
