// JavaScript Document

// Object movements
// Designed by Philippe Forget
// Version 1.0.20080131

// Pan an object to a new position with a translation value that can be defined as an absolute target position
function panTo(object,translation,isTargetPosition,time,interval){
	// Get the actual position of the object
	object.actualPosition = new Point((getNumericValue(object.style.left)==null) ? 0 : getNumericValue(object.style.left),(getNumericValue(object.style.top)==null) ? 0 : getNumericValue(object.style.top));

	//alert("actual: ("+object.actualPosition.x+","+object.actualPosition.y+")")
	
	// Redefine the translation value if it is an absolute target rosition
	if(isTargetPosition){
		translation = translation.substract(object.actualPosition);
	}

	// Define the translation steps
	var translationPart = translation.divide(new Point((time/interval),(time/interval)));
	translationPart.ceil();
	
	// Set the translation interval
	if (object.timeout){clearTimeout(object.timeout);object.timeout=null;}
	object.timeout = setTimeout(function(){slide(object,translationPart,object.actualPosition.add(translation),interval);},interval);

}

// Move an object to a position defined by a translation value
function slide(object,translation,targetPosition,interval){
	
	// Clear the interval when the object has reached target position
	if(object.actualPosition.x != targetPosition.x || object.actualPosition.y != targetPosition.y){
		
		// Define the new position to be applied to the object
		var newPosition = object.actualPosition.add(translation);
		
		// Check not to exceed target position
		// Left Down
		if(translation.x >= 0 && translation.y >= 0){
			if(newPosition.x > targetPosition.x){
				newPosition.x = targetPosition.x;
			}
			if(newPosition.y > targetPosition.y){
				newPosition.y = targetPosition.y;
			}
		}
		// Left Up
		else if(translation.x >= 0 && translation.y < 0){
			if(newPosition.x > targetPosition.x){
				newPosition.x = targetPosition.x;
			}
			if(newPosition.y < targetPosition.y){
				newPosition.y = targetPosition.y;
			}
		}
		// Right Down
		else if(translation.x < 0 && translation.y >= 0){
			if(newPosition.x < targetPosition.x){
				newPosition.x = targetPosition.x;
			}
			if(newPosition.y > targetPosition.y){
				newPosition.y = targetPosition.y;
			}
		}
		// Right Up
		else if(translation.x < 0 && translation.y < 0){
			if(newPosition.x < targetPosition.x){
				newPosition.x = targetPosition.x;
			}
			if(newPosition.y < targetPosition.y){
				newPosition.y = targetPosition.y;
			}
		}
	
		// Change position of the object
		object.style.left = newPosition.x + "px";
		object.style.top = newPosition.y + "px";
		object.actualPosition = newPosition;
		
		if (object.timeout){clearTimeout(object.timeout);object.timeout=null;}
		object.timeout = setTimeout(function(){slide(object,translation,targetPosition,interval);},interval);
		
	}
	
}

// Create a point value with X and Y coordinates
function Point(pX,pY){
	this.x = pX;
	this.y = pY;
	
	this.add = PointAdd;
	this.substract = PointSubstract;
	this.divide = PointDivide;
	this.round = PointRound;
	this.ceil = PointCeil;
	
	this.clone = PointClone;
}

// Create a new point adding the value of the current point to the value passed in parameter
function PointAdd(point){
	var newPosition = new Point(this.x,this.y);
	newPosition.x = newPosition.x + point.x;
	newPosition.y = newPosition.y + point.y;
	return newPosition;
}

// Create a new point substracting the value passed in parameter to the value of the current point
function PointSubstract(point){
	var newPosition = new Point(this.x,this.y);
	newPosition.x = newPosition.x - point.x;
	newPosition.y = newPosition.y - point.y;
	return newPosition;
}

// Create a new point dividing the values of the actual point by the values passed in parameter
function PointDivide(point,roundedValues){
	roundedValues = roundedValues || false;
	var newPosition = new Point(this.x,this.y);
	newPosition.x = newPosition.x / point.x;
	newPosition.y = newPosition.y / point.y;
	if (roundedValues){newPosition.round()}
	return newPosition;
}

// Clone the values of a point into a new point
function PointClone(){
	var newPosition = new Point(this.x,this.y);
	return newPosition;
}

function PointRound(){
	this.x = Math.round(this.x);
	this.y = Math.round(this.y);
}

function PointCeil(){
	this.x = Math.ceil(this.x);
	this.y = Math.ceil(this.y);
}

function getNumericValue(value){
	value = value.replace(/(\d+)\D*/gi,"$1");
	return (value=="") ? null : parseInt(value);
}

// Prototype capitalization fonction to String
String.prototype.capitalize = function(){return this.replace(/\w+/g,function(a){return a.charAt(0).toUpperCase()+a.substr(1).toLowerCase();});};

document.getElementsByClassName = function(clsName){
    var retVal = new Array();
    var elements = document.getElementsByTagName("*");
    for(var i = 0;i < elements.length;i++){
        if(elements[i].className.indexOf(" ") >= 0){
            var classes = elements[i].className.split(" ");
            for(var j = 0;j < classes.length;j++){
                if(classes[j] == clsName)
                    retVal.push(elements[i]);
            }
        }
        else if(elements[i].className == clsName)
            retVal.push(elements[i]);
    }
    return retVal;
}

// Prototype parse method to boolean
Boolean.parse = function(value){
  if (typeof(value)=='string'){
    return (value.toLowerCase()=='true');
  }
  return value?true:false;
}

function setStyle(object, style){for (var propertyName in style) {object.style[propertyName] = style[propertyName];}}

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof(window.onload) != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}
