#define STRICT

// Includes standard Windows
#include <windows.h>
#include <windowsx.h>
#include <time.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <stdio.h>

// Includes D3D
#define  D3D_OVERLOADS
#include <ddraw.h>
#include <d3d.h>
#include <d3dx.h>

// Includes utilitaires D3D
#include "d3dmath.h"
#include "d3dutil.h"
#include "D3DEnum.h"

// Ids Resources
#include "resource.h"

// Constantes
#include "const.h"

// Types
#include "types.h"

// Variables globales projet
#include "vars.h"

// Prototypes fonctions autres modules
#include "proto.h"

// Macros
#include "macros.h"

void vDemo(void)
{
    struct DateStamp sDS1, sDS2;

    vTrace(GetCatalogStr(hCat, MSG_0684, "TimeDemo 1 - \"Georges's special cheat code\""));

    // Supprimer les objets
    vDeleteObjects();

    // Réinitialiser la direction de la caméra
    Target = D3DVECTOR(0., 0., 0.);

    // Initialiser les matrices view, proj, world
    hrInitWorld(NULL);

    // Créer les  triangles, en material 0 (blanc)
    for (float fZ = -3.; fZ <= 3.; fZ += 0.5)
    {
        D3DVECTOR   v1 = D3DVECTOR( -1. + sin(fZ),    -1. + sin(fZ),    fZ);   // u : 0    v : 0
        D3DVECTOR   v2 = D3DVECTOR(  1. + sin(fZ),    -1. + sin(fZ),    fZ);   // u : 255  v : 0
        D3DVECTOR   v3 = D3DVECTOR(  1. + sin(fZ),     1. + sin(fZ),    fZ);   // u : 255  v : 255
        D3DVECTOR   v4 = D3DVECTOR( -1. + sin(fZ),     1. + sin(fZ),    fZ);   // u : 0    v : 255
        int         i1 = iMakeVertex(v1, XDC_FORCENEW);
        int         i2 = iMakeVertex(v2, XDC_FORCENEW);
        int         i3 = iMakeVertex(v3, XDC_FORCENEW);
        int         i4 = iMakeVertex(v4, XDC_FORCENEW);

        int t1 = iMakeTriangle(i1, i2, i3, 0); bSetUV(t1, 0, 0, 127, 0, 127, 127);
        int t2 = iMakeTriangle(i1, i3, i4, 0); bSetUV(t2, 0, 0, 127, 127, 0, 127);
    }

    // Forcer le texturage du material 0
    Materials[0].bTextured = TRUE;
    strcpy(Materials[0].sTexName, "wall.ppm");

    // Référencer le matériau avec sa texture
    vXRefMaterials2Textures();

    // Redessiner la scène 2D complète
	vForce2DRefresh(XDC_MODE_COMPLET);

    // Mémoriser l'horodate courante avant animation
    DateStamp(&sDS1);

    // Faire tourner la caméra autour du point de visée
    for (float fAlpha = 0 ; fAlpha < 5. * g_PI ; fAlpha += g_PI / 90.)
    {

        Observer.x = 9. * sin(fAlpha); // / 1.5);
        Observer.z = 9. * cos(fAlpha);
        Observer.y = -2. + 2. * cos(3. * fAlpha);

		D3DUtil_SetViewMatrix(matView,
				  Observer,	// From
                  Target,	// To
				  Target);

		// Redessiner la scène 3D
	    vForce3DRefresh(XDC_MODE_COMPLET);

        // Redessiner la scène 2D en ne forçant que le refresh caméra / curseurs
    	vForce2DRefresh(XDC_MODE_PARTIEL);
    }

    // Récupérer l'horodate courante après animation et afficher le temps écoulé pendant
    DateStamp(&sDS2);
    if (sDS2.ds_Tick < sDS1.ds_Tick) sDS2.ds_Tick += 3000;
    float fElapsed = (sDS2.ds_Tick - sDS1.ds_Tick) / 50.;
    int iNumFrames = (int) ((5. * g_PI) / (g_PI / 90.)),
        iNumFPS = (int ) (iNumFrames / fElapsed);

    vTrace(GetCatalogStr(hCat, MSG_0686, "Temps écoulé : %f s pour %d frames, soit %d fps"), fElapsed, iNumFrames, iNumFPS);
}
