//----------------------------------------------------------------------------------------------
// scene replay just simple title sequence coded by acid/z51 (jizz take a rest fella)
//----------------------------------------------------------------------------------------------
// this file is part of source code from intertia³ demo (c)zone51 `2000
//----------------------------------------------------------------------------------------------

#define  D3D_OVERLOADS
#include "directgem.h"
#include "enum.h"
#include "FlowerEfx.h"
#include "texturemenager.h"
#include "extrastuff.h"

static	gem_Scene				scene;

static	D3DLVERTEX				FxPlain[2601];
static	WORD					FxPlainInd[15606];

static	LPDIRECTDRAWSURFACE7	text = NULL;
static	LPDIRECTDRAWSURFACE7	zbuffer = NULL;
static	D3DVIEWPORT7			view;


HRESULT fxInit_FlowerEfx( LPDIRECT3DDEVICE7 pd3dDevice )
{	

	LPDIRECTDRAWSURFACE7	surf;	

	DDSURFACEDESC2			ddsd;
	LPDIRECTDRAW7			pDD;
	HRESULT					hr;

	// create a texture buffer 	

	ddsd.dwSize = sizeof( ddsd );
	pd3dDevice->GetRenderTarget( &surf );
	surf->GetSurfaceDesc( &ddsd );
	surf->GetDDInterface( (LPVOID*)&pDD );

	ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
	ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE;
	ddsd.dwHeight	= 256;
	ddsd.dwWidth	= 256;

	view.dwWidth	= ddsd.dwWidth;
	view.dwHeight	= ddsd.dwHeight;
	view.dwX		= 0;
	view.dwY		= 0;
    view.dvMaxZ     = 1.0f;
	view.dvMinZ		= 0.0f;	

	hr = pDD->CreateSurface( &ddsd, &text, 0 );	

	pd3dDevice->GetRenderTarget( &surf );

	DDSCAPS2			ddcaps = { DDSCAPS_ZBUFFER };

	hr = surf->GetAttachedSurface( &ddcaps, &zbuffer );

	surf->Release();
	
	zbuffer->GetSurfaceDesc( &ddsd );

	ddsd.dwWidth	= 256;
	ddsd.dwHeight	= 256;

	zbuffer->Release();

	ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;

	hr = pDD->CreateSurface( &ddsd, &zbuffer, 0 );
	text->AddAttachedSurface( zbuffer );	

	//********************************************

	gem_Mesh*			mesh;
	gem_Material*		mat;
	gem_Camera*			cam;

	LoadTexture( "data\\textures\\flower.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\base.jpg", pd3dDevice );

	scene.SetViewport( 1.0f, 1e12, 0.75f );
	scene.Load( "data\\scenes\\flower.3ds" );
	scene.SetFlags( NULL );	
	scene.Init( pd3dDevice );	
	
	scene.SetActiveCamera( "Camera02" );			

	mat = new gem_Material( "data\\textures\\flower.jpg", &scene );		
	mesh = (gem_Mesh*)scene.FindObject( "Object06" );
	mesh->SetMaterial( mat );

	mat = new gem_Material( "data\\textures\\base.jpg", &scene );		
	mesh = (gem_Mesh*)scene.FindObject( "Object02" );
	mesh->SetMaterial( mat );
	//ApplySphereMap( mesh->pMeshVertexTab, mesh->dwVertexCount, pd3dDevice );

	cam = (gem_Camera*)scene.FindObject( "Camera01" );
	cam->aspect = 1.0f;

	D3DLVERTEX			Plain[4];

	Plain[0] = D3DLVERTEX( D3DVECTOR(-8, -0.5, -8 ), 0x30FFFFFF, 0, 0, 0 );
	Plain[1] = D3DLVERTEX( D3DVECTOR( 8, -0.5, -8 ), 0x30FFFFFF, 0, 1, 0 );
	Plain[2] = D3DLVERTEX( D3DVECTOR(-8, -0.5,  8 ), 0x30FFFFFF, 0, 0, 1 );
	Plain[3] = D3DLVERTEX( D3DVECTOR( 8, -0.5,  8 ), 0x30FFFFFF, 0, 1, 1 );	

	CreatePlain( 50, 50, FxPlain, FxPlainInd, Plain );

	return S_OK;
}


HRESULT fxFrameMove_FlowerEfx( LPDIRECT3DDEVICE7 pd3dDevice, LPSYNCINFO sync )
{
	//*******************************************************************
	D3DMATERIAL7 mtrl;
	ZeroMemory( &mtrl, sizeof(mtrl) );
    mtrl.ambient.r = 1.0f;
    mtrl.ambient.g = 1.0f;
    mtrl.ambient.b = 1.0f;
	mtrl.diffuse.r = 1.0f;
	mtrl.diffuse.g = 1.0f;
	mtrl.diffuse.b = 1.0f;
	mtrl.diffuse.a = 0.25f;    
	pd3dDevice->SetMaterial( &mtrl );
	
    pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0x00808080 );
	//******************************************************************	

	FLOAT			fTimeKey = sync->fTimeKey;
	FLOAT			frame = 450*fTimeKey/20.0f;	
	
	scene.Transform( frame );		

	//FLOAT _sin = (FLOAT)sin( fTimeKey );
	//FLOAT _cos = (FLOAT)cos( fTimeKey );		
	
	FLOAT	angle1, angle2;	
	FLOAT	x1, z1;
	DWORD	ind, i, j;

	for( angle1 = 1, i = 2 ; i<50 ; i++, angle1 += 3.1415f/48.0f )
		for( angle2 = 1, j = 2 ; j<50 ; j++, angle2 += 3.1415f/48.0f )
		{	
			ind = i*51 + j;
			x1 = FxPlain[ind].x*2.5f; //+ fTimeKey;
			z1 = FxPlain[ind].z*2.5f; //+ fTimeKey;

			FxPlain[ind].y = -0.5 + 0.95f*sinf( sqrt( x1*x1 + z1*z1 ) - fTimeKey*2.0f );		

			//FxPlain[ind].z = 20 - 2*cos( sqrt( coeff1*x1*x1 + coeff2*y1*y1 ) );
			
		}	
		
	return S_OK;
}


HRESULT fxRender_FlowerEfx( LPDIRECT3DDEVICE7 pd3dDevice )
{
	LPDIRECTDRAWSURFACE7	target;	
	D3DVIEWPORT7			viewPort;	

	pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC );	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAXANISOTROPY, 2 );	

	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, D3DWRAPCOORD_0 | D3DWRAPCOORD_1 ); 		

	pd3dDevice->GetViewport( &viewPort );
	pd3dDevice->GetRenderTarget( &target );
	
	pd3dDevice->SetRenderTarget( text, 0 );
	pd3dDevice->SetViewport( &view );
	pd3dDevice->Clear( 1UL, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x0, 1.0f, 0L );	

	scene.SetActiveCamera( "Camera01" );			
	scene.Render();	

	pd3dDevice->SetTexture( 0, NULL );

	pd3dDevice->SetRenderTarget( target, 0 );
	pd3dDevice->SetViewport( &viewPort );
	pd3dDevice->Clear( 1UL, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0x0, 1.0f, 0 );	

	scene.SetActiveCamera( "Camera02" );			
	scene.Render();	

	pd3dDevice->BeginScene();
	pd3dDevice->SetTexture( 0, text );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, FxPlain, 2601, FxPlainInd, 15606, NULL );		
	pd3dDevice->SetTexture( 0, NULL );
	pd3dDevice->EndScene();

	return S_OK;
}

#define SAFE_RELEASE( obj ) \
	 if( obj ) obj->Release()

VOID fxDelete_FlowerEfx( LPDIRECT3DDEVICE7 pd3dDevice )
{	
}

