/*
* This file is part of 3DzzD http://dzzd.net/.
*
* Released under LGPL
*
* 3DzzD is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 3DzzD is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with 3DzzD.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2005 - 2009 Bruno Augier
*/

import net.dzzd.utils.Log;
 
import net.dzzd.access.*;
import net.dzzd.DzzDApplet;
import net.dzzd.*;
import net.dzzd.utils.io.*;

import java.awt.event.KeyEvent;
import java.awt.event.*;

import java.awt.*;
import java.net.*;
import java.awt.image.*;

import java.awt.Button;

import java.util.*;


/**
 * Viewer3D
 *
 * Simple Web 3D Applet Viewer for 3DS file
 * 
 * @author Bruno Augier
 * @website: http://dzzd.net/
 * @version 1.00 2008/07/03
 */
public final class Viewer3D extends DzzDApplet
{		
	public static final long serialVersionUID = 0x00000001;
	private int nbStart=0;
	
	IScene3DRender scene3DRender;
	Scene3DRenderCallBackExamine mainSceneHandler;
	
	private String model1Base="DEFAULT/";			//Default 3D model directory
	private String model1File="DEFAULT.3DS";		//Default 3D model files
	private String cameraName="Camera01";
	private int bgColor=0x000000;					//Default background color
	
	private int cameraFov=45;			//Default cameraFov
	private int cameraZ=-100;			//Default cameraZ
	

	private int loadProgress3D=0;	//Progress of 3D download
	private int maxProgress3D=0;	//Max progress of 3D download for multiple files
	private int loadProgressIMG=0;	//Progress of 3D download
	private int maxProgressIMG=0;	//Progress of 3D download for multiple files
	
	private boolean loading=true;	//still loading flag ?
	
	/**
	 * Init Method called by the browser
	 * there we replace default value by applet param tag value
	 */	

	public void init()
	{
		System.out.println("Init : "+Thread.currentThread());
		super.init();
		DzzD.extensionBaseURL=this.getBaseURL()+"/LIB/";
		
		if(this.getParameter("MODELFILENAME")!=null)
		{
			this.model1Base="./";
			this.model1File=this.getParameter("MODELFILENAME");
		}
		
		if(this.getParameter("MODELFILEPATH")!=null)
			this.model1Base=this.getParameter("MODELFILEPATH");
				
		if(this.getParameter("CAMERANAME")!=null)
			this.cameraName=this.getParameter("CAMERANAME");
			
		if(this.getParameter("CAMERAFOV")!=null)
		{
			try
			{
				this.cameraFov=Integer.parseInt(this.getParameter("CAMERAFOV"),10);
			}
			catch(NumberFormatException nfe)
			{
				Log.log("Invalid camera fov value CAMERAFOV="+this.getParameter("CAMERAFOV"));
			}
			
		}			

		if(this.getParameter("CAMERAZ")!=null)
		{
			try
			{
				this.cameraZ=Integer.parseInt(this.getParameter("CAMERAZ"),10);
			}
			catch(NumberFormatException nfe)
			{
				Log.log("Invalid camera z value CAMERAZ="+this.getParameter("CAMERAZ"));
			}
			
		}						

		if(this.getParameter("BGCOLOR")!=null)
		{
			try
			{
				this.bgColor=Integer.parseInt(this.getParameter("BGCOLOR"),16);
			}
			catch(NumberFormatException nfe)
			{
				Log.log("Invalid background color value BGCOLOR="+this.getParameter("BGCOLOR"));
			}
			
		}
		
	
								
		
		
		this.setBackground(new Color(this.bgColor));
		
		this.load3D();
	}
	

	public void start()
	{
		System.out.println("Start : "+Thread.currentThread());
		super.start();
		if(this.nbStart++==0)			
			this.show3D();	
		this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
	}
	

	/**
	 * Destroy Method called by the browser
	 * There we stop Scene3DRender 
	 */
	public void destroy()
	{
		System.out.println("Destroy : "+Thread.currentThread());
		if(this.scene3DRender!=null)
			this.scene3DRender.stop();
		this.scene3DRender=null;
	}
	
	/**
	 * Main thread
	 */	
	public void run()
	{		
		//this.load3D();
		this.loading=false;
		
	}
	
	/**
	 * Load 3D file and create the main Scene3DRender
	 */	
	public void load3D()
	{
    	this.scene3DRender=DzzD.newScene3DRender();
    	IScene3D s=this.scene3DRender.getScene3D();
		IScene3DLoader s1=DzzD.newScene3DLoader();
		String loadFile=this.getBaseURL()+this.model1Base+this.model1File;
		Log.log("Load 3ds "+loadFile);
		s1.loadScene3D(this.getBaseURL()+this.model1Base,this.model1File);
		s.setScene3DLoader(s1);	
		do
		{
			this.loadProgress3D=0;
			this.loadProgressIMG=0;
			this.maxProgressIMG=0;
			this.maxProgress3D=0;

			s.updateMonitoredSceneObjects();
			if(s.getNbMonitoredSceneObject()!=0)
			{
				IMonitoredSceneObject m=s.getMonitoredSceneObject(0);
				if(m instanceof IScene3DLoader)
				{
					this.loadProgress3D+=(m.getProgress()*100)/m.getMaximumProgress();
					this.maxProgress3D+=100;
				}
				if(m instanceof ITexture)
				{
					this.loadProgressIMG+=(m.getProgress()*100)/m.getMaximumProgress();
					this.maxProgressIMG+=100;
				}
				
			}
			DzzD.sleep(100);
		}
		while(s.getNbMonitoredSceneObject()!=0);	

	}
		
	/**
	 * Initialise some value in the Scene3DRender before showing it
	 */
	public void show3D()
	{
		IRender3D r=this.scene3DRender.getRender3D();
		if(this.mainSceneHandler==null)
		{
			
			IScene3D s=this.scene3DRender.getScene3D();
			s.setBackgroundColor(this.bgColor);	
			
			//IPoint3D lRot=s.getLight3DById(0).getRotation();
		//	lRot.set(-Math.PI*0.12,0,0.00);
			
			r.setSize(this.getWidth(),this.getHeight(),1);
			if(s.getCamera3DByName(this.cameraName)!=null)
			{
				s.getCamera3DByName(this.cameraName).setParent(null);
				s.setCurrentCamera3DByName(cameraName);
			}
			else
			{
				ICamera3D c=s.getCurrentCamera3D();
				c.getPosition().setZ(this.cameraZ);
				c.setFOV(this.cameraFov);
				
			}
			 
			
			ICamera3D c=s.getCurrentCamera3D();
			//c.getPosition().setZ(-200);
			
			c.setZMin(0.1);
			c.setZoomY(((double)r.getWidth())/((double)r.getHeight()));	
			r.setScreenUpdateEnabled(true);
			r.getCanvas().setVisible(true);
			
			this.mainSceneHandler=new Scene3DRenderCallBackExamine();	
			this.scene3DRender.setScene3DRenderCallBack(this.mainSceneHandler);
		}
		
		this.add(r.getCanvas());
		r.getCanvas().requestFocus();
		this.scene3DRender.start();			
	}
	
	public void paint(Graphics g)
	{

	}
	

	
	public void update(Graphics g)
	{
	
		
	}		
	
}
