/**
Copyright kujjuk - 2010
Tous droits de reproduction réservés
*/


//------------------------------------------------------------------------------
//-----------------------------CONSTRUCTOR--------------------------------------
//------------------------------------------------------------------------------
// this.nbFrame 						nombre total d'images pour le 360°
// this.kujjukImage						objet contenant l'image ( objet <image /> )
// this.startWithAnimation = true;		Annimation au début du chargement
// this.imgPath							Path to the image

// this.randomMode							Premiere image choisie aleatoirement

function Kujjuk360(nbFrames,kujjukImage,imgPath, imgName ,nbTurnToDo,firstFrame,itemMinimumSpeed,initialSpeed, inertie,accelerationFunction){
	// attributs
	this.nbFrames = nbFrames;
	this.speed = initialSpeed;
	this.actualPosition = 0;
	if(accelerationFunction==null)
	 accelerationFunction= Kujjuk_basicDeceleration;
	 
	this.accelerationFunction = accelerationFunction
	this.imgName = imgName;
	this.kujjukImage = kujjukImage;
	this.imgPath = imgPath;
	this.startFrame = firstFrame;
	this.acivateThrow = inertie;
	this.nbTurnToDo = nbTurnToDo;
	this.time = 0;
	this.lastTime = 0;
	this.READY = false;
	// INITIALISATION des paramentres
	// array contenant les image et les infos
	this.lArray = new Array();
	this.cFrame = -2;
	// constante : nombre de pixel requis en deplacement pour faire tourner d'un cran l'objet
	this.CONS_vitRotMov = 10;
	
	//compteur utilisé pour savoir quand on doit passer à l'image suivante
	this.pas = 0;
	// position precedente
	this.prevX = 0;
	this.imagesloaded=0;
	this.currentFrame = 0;
	this.prevX = 0;
	this._dragElement;
	this._oldZIndex = 0;
	this.mouseIsDown = false;
	this.Minimum_Speed = itemMinimumSpeed;
	this._dragElement = null;
	this.turnNumber = 0;
	this.hasBeenClicked = false;
	
	
	this.zoomActivated = false;
	this.activateZoom 				= Kujjuk_activateZoom;
	// callback
	this.horizontalCallback 		= new Array();
	this.readyCallback				= new Array();
	this.addHorizontalListener 		= Kujjuk_addHorizontalListener;
	this.addCompleteListener 		= Kujjuk_addCompleteListener;
	this.notifyListener 		= Kujjuk_notifyListener;
	
	//methodes
	// les evennements ne sont pas enregistré ici!
	this.OnMouseDown 		= Kujjuk_OnMouseDown;
	this.OnMouseUp 			= Kujjuk_OnMouseUp;
	this.OnMouseMove 		= Kujjuk_OnMouseMove;
	this.startLoading 		= Kujjuk_preloader;
	this.imageLoaded 		= Kujjuk_imageLoaded;
	this.setNextFrame 		= Kujjuk_setNextFrame;
	this.setPrevFrame 		= Kujjuk_setPrevFrame;
	this.setFrame 			= Kujjuk_setFrame;
	this.OnTouchStart 		= Kujjuk_OnTouchStart;
	this.OnTouchEnd 		= Kujjuk_OnTouchEnd;
	this.OnTouchMove 		= Kujjuk_OnTouchMove;
	this.OnMouseOut 		= Kujjuk_OnMouseOut;
	this.onTimerTick 		= Kujjuk_onTimerTick;
	// initialisation
	this.verticalMode 		= Kujjuk_verticalMode
	this.horizontalMode 	= Kujjuk_horizontalMode 
	this.loadVertical 		= Kujjuk_loadVertical 
	
	
	//this.preloader();
	//this.animateOneRotation();
	
	//permet de retrouver cet objet via l'imagen notament ds la gestion d'evennements.
	kujjukImage.controler = this;
	
	
	
	this.kujjukImage.onmousedown = this.OnMouseDown;
    this.kujjukImage.onmouseup = this.OnMouseUp;
    this.kujjukImage.onmouseout = this.OnMouseOut;
    this.kujjukImage.ontouchstart = this.OnTouchStart;
    this.kujjukImage.ontouchend = this.OnTouchEnd;
    this.kujjukImage.onmousemove = this.OnMouseMove;
    return this;
}



/************************************************************************************************************************************************************************
																					Functions
*************************************************************************************************************************************************************************/

function Kujjuk_addCompleteListener(callback){
	if(kujjukIndexOf(this.readyCallback,callback) != -1){
		return;}
	this.readyCallback.push( callback);
}
function Kujjuk_addHorizontalListener(callback){
	if(kujjukIndexOf(this.horizontalCallback,callback) != -1)
		return
	this.horizontalCallback.push(callback);
}
function Kujjuk_notifyListener(listener){
		for (indexCallback in listener)
	{
		listener[indexCallback](this);
		
	}
}

function Kujjuk_activateZoom( zoomAnchorId){

			
	kujjukImageHolder = getDocument().getElementById(idZoomHolder);
	
	if(kujjukImageHolder == null)
		kujjukImageHolder = Kujjuk_create_zoom()
		
	kujjukZoomImage = getDocument().getElementById(idZoomImage);
	if(kujjukZoomImage == null)
		kujjukZoomImage = Kujjuk_create_imageHolder();
		
	var selecteur = getDocument().getElementById(idSelecteurImage)
	if(selecteur == null)
		selecteur = Kujjuk_create_selecteur();
		
	kujjukSelecteur = new Kujjuk_reticule (selecteur , kujjukZoomImage ,kujjukImageHolder,getDocument().getElementById("kujjukWaitingItem"),getDocument().getElementById(zoomAnchorId));
	
	//kujjukSelecteur.zoomedHolder .style.visibility = "visible";
	//kujjukSelecteur.zoomedHolder .style.display = "block";
	
	if(kujjukSelecteur == null)
		return alert("No img has an id="+idSelecteurImage)
	zoomKujjukOn = true;
	this.zoomActivated = true;
	
}


/************************************
				Preload
************************************/


function Kujjuk_preloader(aditionnalAdress){	
	for(var k=0;k<this.nbFrames;k++){
		var indexL = k+1;
		this.lArray[k] = new Image();
		this.lArray[k].controler = this;
		this.lArray[k].onLoad=this.imageLoaded();
		if(aditionnalAdress == null )
			this.lArray[k].src = this.imgPath+this.imgName +indexL+'.jpg';
		else
			this.lArray[k].src = this.imgPath+this.imgName +aditionnalAdress+indexL+'.jpg';
			
		this.lArray[k].loaded = false;
	}
	
	this.kujjukImage.src = this.lArray[0].src;
	
}	
function testKujjuk360(kujjuk360Item){
	if(kujjuk360Item.READY == true)
	return;
if(kujjuk360Item.imagesloaded == kujjuk360Item.nbFrames && kujjuk360Item.startWithAnimation != 0)
		kujjuk360Item.setFrame(kujjuk360Item.startFrame);
		if(kujjuk360Item.imagesloaded == kujjuk360Item.nbFrames){
				kujjuk360Item.READY = true;
				kujjuk360Item.notifyListener(kujjuk360Item.readyCallback);
				kujjuk360Item.notifyListener(kujjuk360Item.horizontalCallback);
			}
}

function Kujjuk_imageLoaded(){// on est sur l'objet DOM windows et pas ni l'image ni cet objet.... 
	// obligation de retrouver et de tracer chaque image pour savoir si elle à été chargé
	actualLoadingItem.imagesloaded +=1;
	testKujjuk360(actualLoadingItem);
	return;
	
	
	if(listKujjukVisio.length == 1){
			listKujjukVisio[0].imagesloaded +=1;
		testKujjuk360(listKujjukVisio[0]);
		
		return; 
		}
			// ne fonctionne pas sous IE ...
	for (indexKujjuk360 in listKujjukVisio)
	{
		
		var kujjuk360Item = listKujjukVisio[indexKujjuk360];
		kujjuk360Item.imagesloaded =0;
		for (indexImageLoading in listKujjukVisio[indexKujjuk360].lArray)
		{
			var mImage = kujjuk360Item.lArray[indexImageLoading];
			if(mImage.complete){
				kujjuk360Item.imagesloaded +=1;
				
			}
		}
		testKujjuk360(kujjuk360Item);
//console.log( kujjuk360Item.imagesloaded);

	}
}


function Kujjuk_setFrame(num){
	this.currentFrame = num;
	if(this.currentFrame>= this.lArray.length)
		this.currentFrame = 0
	//console.log(this.lArray[this.currentFrame], this.currentFrame);
	if(this.lArray[this.currentFrame] != null)
		this.kujjukImage.src = this.lArray[this.currentFrame].src;
}			
function Kujjuk_setNextFrame(){
	this.currentFrame = this.currentFrame+1;
	if(this.currentFrame>= this.lArray.length){
		this.currentFrame = 0
		this.turnNumber -=1;
		}
	this.setFrame(this.currentFrame)
	//this.kujjukImage.src = this.lArray[this.currentFrame].src;
}
function Kujjuk_setPrevFrame(){
	this.currentFrame = this.currentFrame-1;
	if(this.currentFrame< 0)
		this.currentFrame = this.lArray.length-1
		
	else if(this.currentFrame ==0){
		
		this.turnNumber +=1;
	}
		
	this.setFrame(this.currentFrame)
	//this.kujjukImage.src = this.lArray[this.currentFrame].src;
}





/************************************
			Methodes
************************************/
// ces fonctions ne sont pas appelé directement mais plutot par l'intermediaire de l'objet qui les contient.

// pour Iphone
function Kujjuk_OnTouchStart(e){
	e.clientX  = e.touches[0].clientX;
	e.clientY  = e.touches[0].clientY;
	e.target.controler.OnMouseDown(e);
		
	e.target.ontouchmove = e.target.controler.OnTouchMove;

}
// pour Iphone
function Kujjuk_OnTouchMove(e){
	e.clientX  = e.touches[0].clientX;
	e.clientY  = e.touches[0].clientY;
	e.target.controler.OnMouseMove(e);
		
	
    	e.preventDefault();
}
// pour Iphone
function Kujjuk_OnTouchEnd(e){
	Kujjuk_OnMouseUp(e);
    	e.target.ontouchmove = null;

}



// appelé dans l'image et pas dans l'objet Kujjuk360

function Kujjuk_OnMouseDown(e, otherTarget){
	e = Kujjuk_getMousePositionInEvent(e);
	hideZoom(e);
    var target = null;
    if(otherTarget == null)
    target = e.target != null ? e.target : e.srcElement;
   	else
   	target = otherTarget;
   	
    with(target){
    	if(controler.startWithAnimation >-2)
    		controler.startWithAnimation = 0;
    	else if(controler.startWithAnimation == -2)
    		controler.startWithAnimation = -3;
    	controler.mouseIsDown = true;
    	controler.hasBeenClicked = true;
        controler.prevX = e.posX;
        //controler.speed = 0;
		controler.lastSpeedMouse = 0;
		controler.lastTime = controler.time;
        controler.startFrame=controler.currentFrame;
        controler._oldZIndex = target.style.zIndex;
        controler._dragElement = target;
	    getDocument().body.focus();
        onselectstart = function () { return false; };
        ondragstart = function() { return false; };
        return false;
    }
}
function Kujjuk_OnMouseMove(e){

	e = Kujjuk_getMousePositionInEvent(e);
		//console.log(e.target);
	
    with(e.target){
    	if(!controler.mouseIsDown)
    	Kujjuk_actualizeZoom(e,controler);
    if(controler._dragElement==e.target){
	//console.log(controler);
    	var d = e.posX - controler.prevX;
    	 with(controler){
    	//if(speed<0)
    	//	pas += d
    	//else
    		pas -= d
			time+=1;
			lastSpeedMouse = d/(time-lastTime);//+speed/2;
    		speed = lastSpeedMouse; //(d*2/3+controler.speed/3)/CONS_vitRotMov;
			lastTime = time;
    		//controler.speed = controler.accelerationFunction(controler.speed,controler.currentFrame, controler.Minimum_Speed)
    		if(Math.abs(pas)>CONS_vitRotMov){
    			//if(this.acivateThrow)
    			if(pas>0)
					setNextFrame()
				else
					setPrevFrame()
    			pas = 0;
    			
    		}
    		
    	 }
    	controler.prevX = e.posX;
	}   
		
    }
    
}

function Kujjuk_OnMouseUp(e){
	e = Kujjuk_getMousePositionInEvent(e);
	//console.log(e.target)
	if(e.target.controler == null)
	return e;
	
	with(e.target.controler){
	    if (_dragElement != null){
	    	
	    	if(!acivateThrow || Math.abs(speed)<=Minimum_Speed || lastSpeedMouse == 0)
	    		speed = 0;
    		mouseIsDown = false;
	        _dragElement.style.zIndex = _oldZIndex;
	        onmousemove = null;
	        onselectstart = null;
	        _dragElement.ondragstart = null;     
	       	_dragElement = null;
			Kujjuk_actualizeZoom(e,e.target.controler);
	    }
	}
	return e;
}	
function Kujjuk_OnMouseOut(e){
	e = Kujjuk_OnMouseUp(e)
	if(Kujjuk_isOver(e,this)){
	hideZoom(e);
	
	}
	
}

function Kujjuk_onTimerTick(){
if(!this.READY)
return;

this.time+=1;
	if(this.mouseIsDown || kujjukZoomVisible)
		return;
	
	if(!this.hasBeenClicked && this.nbTurnToDo!= null  && Math.abs(this.nbTurnToDo)<Math.abs(this.turnNumber))
	return;
	
		if(Math.abs(this.actualPosition)>=10){
				if(this.speed<0)
					this.setNextFrame()
				else
					this.setPrevFrame()
			
				this.actualPosition = 0;
		}
		this.actualPosition+=this.speed;
		if(this.accelerationFunction != null)
			this.speed = this.accelerationFunction(this.speed,this.currentFrame, this.Minimum_Speed);
}
//------------------------------------------------------------------------------
//------------------vertical Selection------------------------------------------
//------------------------------------------------------------------------------

// to handle vertical Mode
function Kujjuk_verticalMode (){
}
// to handle horizontal Mode
function Kujjuk_horizontalMode (){
}


// to handle horizontal Mode
function Kujjuk_loadVertical (cb){
	setHorizontalCallback(cb)
}
//------------------------------------------------------------------------------
//------------------Function that compute the deceleration in the object--------
//------------------------------------------------------------------------------

// fonction spéciale, appelé à chaque tick du timer PAR l'objet Kujjuk360 pour controller l'evolution de la vitesse.
// en appelant une autre fonction  on change le comportement de l'objet...
// itemMinimumSpeed est la vitesse minnimum conseillé.
function Kujjuk_basicDeceleration (itemSpeed,frameNumber, itemMinimumSpeed){
	if(itemSpeed == 0)
		return 0;
		if(frameNumber == 0 && (Math.abs(itemSpeed)-itemMinimumSpeed)<0.01)
			return 0;
	return itemSpeed += (Math.abs(itemSpeed)/itemSpeed) * (itemMinimumSpeed - Math.abs(itemSpeed))/100;
	
}


