import net.dzzd.utils.Log;
import net.dzzd.access.*;
import net.dzzd.DzzDApplet;
import net.dzzd.*;
import net.dzzd.utils.io.*;

import java.awt.*;
import java.awt.event.KeyEvent;



public class Exemple extends DzzDApplet implements Runnable,IScene3DRenderCallBack
{
	
	/**
	 *IScene3DRender et un objet qui rend automatiquement une scene3d sur un render3d 
	 * et qui appel des fonctions d'evenement à chaque étapes
	 */
	IScene3DRender scene3DRender;
	
	public void init()
	{
		
	}
	
	
	public void start()
	{
		/**
		 * On crer un  nouveau Thread 
		 *  => ceci appelera la methode run() (dans un nouveau Thread)
		 */
		Thread t=new Thread(this);
		t.start();
		
	}
	
	
	public void paint(Graphics g)
	{
		
	}
	
	public void update(Graphics g)
	{
		
	}
	
	
	public void run()
	{
		this.scene3DRender=DzzD.newScene3DRender();
		    	    	
		/**
		 * On charge un objet
		 */
		IScene3DLoader scene1=DzzD.newScene3DLoader();
		scene1.loadScene3D(this.getBaseURL()+"/TERRE/","MODELE.3DS");
		
		while(!scene1.getFinished())
		{
			DzzD.sleep(1000);
			Log.log("Loading "+scene1.getProgress()+"%");
		}
		
		/**
		 * on ajoute l'objet à la scene
		 */
		 IScene3D s=this.scene3DRender.getScene3D();
		 s.setScene3DLoader(scene1);
		 
		 s.setBackgroundColor(0x005500);	//on fixe la couleur du fond
		
		/**
		 * on fixe la classe qui contient les methode d'evenements
		 * (ici un appel à render3DstartCallBack est fait)
		 * puis ensuite les autres methodes à chaque rendu
		 */
		this.scene3DRender.setScene3DRenderCallBack(this);
		
		
		IRender3D r=this.scene3DRender.getRender3D();
		
		//On fixe la taille de la zone de rendu
		r.setSize(this.getWidth(),this.getHeight());
		
		//On ajoute la zone de rendu à l'applet
		this.setLayout(null);
		this.add(r.getCanvas());
		
		//On essai de lui donner le focus
		r.getCanvas().requestFocus();
		
		
		//On recupere la camera en cours
		ICamera3D c=s.getCurrentCamera3D();
		
		// on la recule pour voir l'objet
		c.getPosition().setZ(-200);
		
		/**
		 * pour obtenir un ratio correct on fixe le zoom en Y
		 *  de la camera en fonction des dimension de la zone de rendu
		 */
		 c.setZoomY(((double)r.getWidth())/((double)r.getHeight()));	
		
		r.setScreenUpdateEnabled(true);	//on autorise le rendu
		r.getCanvas().setVisible(true); //o rend visible la zone de rendu

		
		
		// On demarre le rendu automatique
		this.scene3DRender.start();			

	}
	
	
	/**
	 * Les méthodes ci-dessous sont des evenement qui seront appelés automatiquement
	 */ 
	 
	 
	/**
	 * Methode appelée une seule fois au démarrage
	 */ 
	public void render3DstartCallBack(IScene3DRender r){}
	
	/**
	 * Methode appelé à chaque fin de rendu quand un objet
	 *  est entrain de charger (streamming)
	 */
	public void render3DSceneObjectMonitor(IScene3DRender r){}
	
	
	/**
	 * Methode appelée à chaque début d'un nouveau rendu
	 */
	public void render3DStart(IScene3DRender r){}
	
	
	/**
	 * Methode appelée à chaque rendu quand la scene est dasn l'espace "Monde"
	 */
	public void render3DWorldSpace(IScene3DRender r)
	{
		/**
		 * Ici on peu par exemple tourner 
		 *  l'objet "Sphere01" autour de son pivot
		 *  si l'utilisateur appuye sur une touche
		 */
		
		/**
		 * on recupere un objet qui nous permettra de connaitre
		 * l'etat des touches clavier et de la souris
		 *
		 */
		IDirectInput di=r.getRender3D().getDirectInput();
		
		double rotation=0;
		if(di.isKey(KeyEvent.VK_LEFT))
			rotation=0.1; 
			
		if(di.isKey(KeyEvent.VK_RIGHT))
			rotation=-0.1; 
		
		
		IMesh3D m=r.getScene3D().getMesh3DByName("Sphere01");
		if(m!=null)
		{
			double ry=m.getRotation().getY();
			m.getRotation().setY(ry+rotation);		 		
		}
		 
		 
		/**
		 * on on peu déplacer la camera
		 */ 
		ICamera3D camera=r.getScene3D().getCurrentCamera3D();
		
		double deplace=0;
		if(di.isKey(KeyEvent.VK_UP))
			deplace=1; 
			
		if(di.isKey(KeyEvent.VK_DOWN))
			deplace=-1; 
			
		double z=camera.getPosition().getZ();
		camera.getPosition().setZ(z+deplace);
		
		 
		 
	}
	
	/**
	 * Methode appelée à chaque rendu quand la scene est dasn l'espace "Camera"
	 */	
	public void render3DCameraSpace(IScene3DRender r)
	{
	}
	
	/**
	 * Methode appelée à chaque rendu juste avant que l'image soit mise à jour
	 */
	public void render3DPixelsUpdate(IScene3DRender r)
	{
	}
	
	/**
	 * Methode appelée à chaque rendu juste avant que l'image soit mise à jour
	 */	
	public void render3DPixelsUpdated(IScene3DRender r)
	{
	}	
	
	/**
	 * Methode appelée à chaque fin de rendu
	 */	
	public void render3DEnd(IScene3DRender r)
	{
	}
	
	/**
	 * Methode appelée si le Render3D a été modifié (hardware/software
	 */	
	public void render3DSwitched(IScene3DRender r)
	{
	}		

	
	
}
