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

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


BEGIN_MESSAGE_MAP(TargetWin, RMWin)
	//{{AFX_MSG_MAP(TargetWin)
	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)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

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

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

BOOL TargetWin::CreateScene()
{
	HRESULT r;

	// ------- MESH --------
	d3drm->CreateMeshBuilder( &targetbuilder );
	r=targetbuilder->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( targetbuilder, D3DVALUE(0.75) );

    // --------- TARGET ANIMATION ÀÍÈÌÀÖÈß ÌÈØÅÍÈ ----------
    LPDIRECT3DRMANIMATION animation;
    d3drm->CreateAnimation( &animation );
    animation->SetOptions(  D3DRMANIMATION_SPLINEPOSITION |
            D3DRMANIMATION_CLOSED |
            D3DRMANIMATION_POSITION );
    animation->AddPositionKey( D3DVALUE(0),
            D3DVALUE(-20), D3DVALUE(0), D3DVALUE(-20) );
    animation->AddPositionKey( D3DVALUE(12),
            D3DVALUE(0), D3DVALUE(15), D3DVALUE(0) );
    animation->AddPositionKey( D3DVALUE(24),
            D3DVALUE(20), D3DVALUE(0), D3DVALUE(-20) );
    animation->AddPositionKey( D3DVALUE(35),
            D3DVALUE(0), D3DVALUE(0), D3DVALUE(0) );
    animation->AddPositionKey( D3DVALUE(49),
            D3DVALUE(20), D3DVALUE(0), D3DVALUE(20) );
    animation->AddPositionKey( D3DVALUE(65),
            D3DVALUE(0), D3DVALUE(15), D3DVALUE(0) );
    animation->AddPositionKey( D3DVALUE(74),
            D3DVALUE(-20), D3DVALUE(0), D3DVALUE(20) );
    animation->AddPositionKey( D3DVALUE(85),
            D3DVALUE(0), D3DVALUE(0), D3DVALUE(0) );
    animation->AddPositionKey( D3DVALUE(99),
            D3DVALUE(-20), D3DVALUE(0), D3DVALUE(-20) );

    // ---------- TARGET FRAME ÔÐÅÉÌ ÌÈØÅÍÈ --------
    LPDIRECT3DRMFRAME targetframe;
    d3drm->CreateFrame( scene, &targetframe );
    animation->SetFrame( targetframe );
    targetframe->AddVisual( targetbuilder );
    targetframe->AddMoveCallback( MoveTarget, animation );

//    targetbuilder->Release();
//    targetbuilder=0;

	// ------- MESH --------
	d3drm->CreateMeshBuilder( &meshbuilder );
	r=meshbuilder->Load( meshname1, NULL, D3DRMLOAD_FROMFILE, NULL, NULL );
	if (r!=D3DRM_OK)
	{
		CString msg;
		msg.Format( "Failed to load file '%s'\n", meshname1 );
		AfxMessageBox( msg );
		return FALSE;
	}
    meshbuilder->SetColorRGB(
            D3DVALUE(.67), D3DVALUE(.82), D3DVALUE(.94) );
    meshbuilder->SetQuality( D3DRMRENDER_FLAT );
    ScaleMesh( meshbuilder, D3DVALUE(7) );

    // ------- MISSILE FRAMES ÔÐÅÉÌÛ ðåàêòèâíîãî ñíàðÿäà ------
    for (int i=0;i<5;i++)
    {
        for (int j=0;j<3;j++)
        {
            LPDIRECT3DRMFRAME meshframe;
            d3drm->CreateFrame( scene, &meshframe );

            meshframe->SetPosition( scene,
                    D3DVALUE((i-2)*8),
                    D3DVALUE(-12),
                    D3DVALUE((j-1)*8) );
            meshframe->AddVisual( meshbuilder );
            meshframe->AddMoveCallback( OrientFrame, targetframe );

            meshframe->Release();
            meshframe=0;
        }
    }

	// ---------AMBIENT LIGHT--------
	LPDIRECT3DRMLIGHT alight;
	d3drm->CreateLightRGB( D3DRMLIGHT_AMBIENT,
			D3DVALUE(1.00), D3DVALUE(1.00), D3DVALUE(1.00), 
			&alight);

	// ---------DIRECTIONAL LIGHT--------
	LPDIRECT3DRMLIGHT dlight;
	d3drm->CreateLightRGB( D3DRMLIGHT_DIRECTIONAL,
			D3DVALUE(0.5), D3DVALUE(0.5), D3DVALUE(0.5), 
			&dlight);

    LPDIRECT3DRMFRAME lightframe;
    d3drm->CreateFrame( scene, &lightframe );
    lightframe->AddLight( dlight );
    lightframe->AddLight( alight );
    lightframe->SetOrientation( scene,
            D3DVALUE(0), D3DVALUE(-1), D3DVALUE(0),
            D3DVALUE(0), D3DVALUE(0), D3DVALUE(1));
    alight->Release();
    alight=0;
    dlight->Release();
    dlight=0;
    lightframe->Release();
    lightframe=0;

    //------ CAMERA ÊÀÌÅÐÀ ----------
    LPDIRECT3DRMFRAME cameradummy;
    d3drm->CreateFrame( scene, &cameradummy );
    cameradummy->SetRotation( scene,
            D3DVALUE(0), D3DVALUE(1), D3DVALUE(0),
            D3DVALUE(.01) );
    d3drm->CreateFrame( cameradummy, &camera );
    camera->SetPosition( scene,
            D3DVALUE(0), D3DVALUE(0), D3DVALUE(-50));
    d3drm->CreateViewport( device, camera, 0, 0,
            device->GetWidth(), device->GetHeight(),
            &viewport);


	return TRUE;
}

void TargetWin::OnRenderWireframe() 
{
	if (meshbuilder)
		meshbuilder->SetQuality( D3DRMRENDER_WIREFRAME );
}

void TargetWin::OnRenderFlat() 
{
	if (meshbuilder)
		meshbuilder->SetQuality( D3DRMRENDER_FLAT );
}

void TargetWin::OnRenderGouraud() 
{
	if (meshbuilder)
		meshbuilder->SetQuality( D3DRMRENDER_GOURAUD );
}

void TargetWin::OnUpdateRenderWireframe(CCmdUI* pCmdUI) 
{
	if (meshbuilder)
	{
		D3DRMRENDERQUALITY meshquality = meshbuilder->GetQuality();
		pCmdUI->SetCheck( meshquality==D3DRMRENDER_WIREFRAME );
	}
}

void TargetWin::OnUpdateRenderFlat(CCmdUI* pCmdUI) 
{
	if (meshbuilder)
	{
		D3DRMRENDERQUALITY meshquality = meshbuilder->GetQuality();
		pCmdUI->SetCheck( meshquality==D3DRMRENDER_FLAT );
	}
}

void TargetWin::OnUpdateRenderGouraud(CCmdUI* pCmdUI) 
{
	if (meshbuilder)
	{
		D3DRMRENDERQUALITY meshquality = meshbuilder->GetQuality();
		pCmdUI->SetCheck( meshquality==D3DRMRENDER_GOURAUD );
	}
}

void TargetWin::MoveTarget(LPDIRECT3DRMFRAME, void* p, D3DVALUE)
{
    LPDIRECT3DRMANIMATION animation=(LPDIRECT3DRMANIMATION)p;
    static D3DVALUE time;
    time+=D3DVALUE(.5);
    animation->SetTime( time );
}

void TargetWin::OrientFrame(LPDIRECT3DRMFRAME frame, void* p, D3DVALUE)
{
    LPDIRECT3DRMFRAME targetframe=(LPDIRECT3DRMFRAME)p;
    LPDIRECT3DRMFRAME scene;
    frame->GetScene( &scene );
    frame->LookAt( targetframe, scene, (D3DRMFRAMECONSTRAINT)0 );
}
