function handleError(error) {
	alert(error);
}

/*
 * helpers
 */
function getElement(id) {
	var element;

	if(document.getElementById) {
		element = document.getElementById(id);
	} else if(document.all) {
		element = document.all[id];
	} else {
		handleError("Browser error - Unable to get element." + document)
	}
	return element;
}

function getSingleDomByHTML(htmlCode) {
	var domObject;
	
	var tmpContainer = document.createElement("div");
	tmpContainer.innerHTML = htmlCode; 
					
	if(tmpContainer.childNodes.length > 0){
		domObject = tmpContainer.firstChild;	
	}
	
	return domObject;
}

function appendAfter(currentNode, newNode) {
	if(currentNode && newNode) {
		if (currentNode.parentNode){
			if (currentNode.nextSibling) {
				currentNode.parentNode.insertBefore(newNode, currentNode.nextSibling);
			} else {
				currentNode.parentNode.appendChild(newNode);
			}
		}
	}
}

function arrayContains(array, element) {
	for (var i = 0; i < array.length; i++) {
		if (array[i] == element) {
			return true;
		}
	}
	return false;
}

function getOffsetLeft(element){
	var result = 0;
	if (element.offsetParent){
		while (element.offsetParent){
			result += element.offsetLeft
			element = element.offsetParent;
		}
	} else if (element.x) {
		result += element.x;
	}
	return result;
} 

function getOffsetTop(element){
	var result = 0;
	if (element.offsetParent){
		while (element.offsetParent){
			result += element.offsetTop;
			element = element.offsetParent;
		}
	}
	else if (element.y) {
		result += element.y;
	}
	return result;
}

function getTopMarginPx(element) {
	var result;	
	if(element) {
		result = getCurrentStyle(element, "margin");		
		if(! result) {
			result = getCurrentStyle(element, "marginTop");
		}		
		if(! result) {
			result = getCurrentStyle(element, "margin-top");
		}

		if(! result) {
			if(element.style.margin) {
				result = element.style.margin;
			}			
			if(element.style.marginTop) {
				result = element.style.marginTop;
			}
		}
	}	
	if(result && result.length > 0) {
		var pxPos = result.indexOf("px");
		if(pxPos > 0) {
			result = result.substring(0,pxPos);
		}
	} else {
		result = 0;
	}	
	return result;	
}

function getCurrentStyle(element, prop) {
	if (!element || !prop) return;		
	if (document.currentStyle) {
		return element.currentStyle[prop];
	} else if (document.defaultView.getComputedStyle) {
		return document.defaultView.getComputedStyle(element, null)[prop];
	} else if (window.getComputedStyle) {
		return window.getComputedStyle(element, null)[prop];
	} 
	return;
}

function arrayContains(array, element) {
	for (var i = 0; i < array.length; i++) {
		if (array[i] == element) {
			return true;
		}
	}
	return false;
}

function removeFromArray(array, element) {
	if(array && element) {		
		var index = array.indexOf(element);
		while(index > -1) {
			array.splice(index, 1);
			index = array.indexOf(element);
		}		
	}
}

/*
 * end helpers
 */


/**
 * setClass
 * 
 * Sets the css class of an biscuit by the biscuit’s id
 * @param id id of the element to set the class
 * @param className name of the biscuit style class to set
 */
function setClass(id, className) {
	var element = getElement(id);
	if(element) {
		element.className = className;
/*
	Other ways to set the class
	element.class = className;
 	element.setAttribute("class", className);
	element.setAttribute("className", className); 
*/
	}
}

function swapClass(id, classOne, classTwo) {
	var element = getElement(id);
	
	if(element.className.indexOf(classOne) >= 0) {
		element.className = element.className.replace(classOne,classTwo);
	} else if(element.className.indexOf(classTwo) >= 0) {
		element.className = element.className.replace(classTwo,classOne);
	} else {
		if(element.className.length > 0) {
			element.className = element.className + " " + classOne;
		} else {
			element.className = classOne;
		}
	}
}

function toggleClass(id, className) {
	var element = getElement(id);
	
	if(element && className) {	
		if(element.className.indexOf(className) >= 0) {
			element.className = element.className.replace(className,"");
		} else {
			if(element.className.length > 0) {
				element.className = element.className + " " + className;
			} else {
				element.className = className;
			}
		}
	}
}

function toggle(id) {	
	toggleClass(id, "hidden");
}

function replaceClass(id, oldClass, newClass) {
	var element = getElement(id);
	
	if(element.className.indexOf(oldClass) >= 0) {
		element.className = element.className.replace(oldClass,newClass);
	}
}

function addClass (id, className) {
	var element = getElement(id);
	var curr = element.className;
	if (!new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i").test(curr)) {
		element.className = curr + ((curr.length > 0) ? " " : "") + className;
	}
}

function removeClass(id, className) {
	var element = getElement(id);
	if (className) {
		element.className = element.className.replace(className, "");
	} else {
		element.className = "";
		element.removeAttribute("class");
	}
}

function hide(id) {
	addClass(id, "hidden");
}

function show(id) {
	removeClass(id, "hidden");
}

function setPageWidth(width) {
	if(width) {
		document.body.style.width = width;
		document.body.firstChild.style.width = width;
	}
}

function setCookie(cookieName, cookieValue, expiredays) {
	var exdate = new Date();
	exdate.setDate(exdate.getDate() + expiredays);
	document.cookie = cookieName + "=" + escape(cookieValue) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}

function getCookie(cookieName) {
	if (document.cookie.length > 0)
	{
		var cookieStart = document.cookie.indexOf(cookieName + "=");
		if (cookieStart != -1)
		{ 
			cookieStart = cookieStart + cookieName.length + 1; 
			var cookieEnd = document.cookie.indexOf(";",cookieStart);
			if (cookieEnd == -1) 
				cookieEnd = document.cookie.length;
			
			return unescape(document.cookie.substring( cookieStart, cookieEnd ));
		} 
	}
	return "";
}

function deleteCookie( cookieName ) {
	if ( getCookie( cookieName ) ) {
		document.cookie = cookieName + '=; expires=Thu, 01-Jan-70 00:00:01 GMT;';
	}
}

function setVariable( varName, varValue ) {
	eval(varName + "='"+varValue+"';");
}

 
/**
 *setContent
 * 
 * Sets the content of a placeholder biscuit(id) by the id of an other biscuit (src_id) which contains the data to insert.
 * @param id id of the element to set the content
 * @param srcId id of the content containing biscuit
 */
function setContent(id, srcId) {
	var contentElement = getElement(srcId);
	var targetElement = getElement(id);
	
	if(contentElement && targetElement) {
		targetElement.innerHTML = contentElement.innerHTML;
	}
}

function getURLParam(pName){
	var result = "";
	var strHref = window.location.href;
	
	if ( strHref.indexOf("?") > -1 ) {
		var strQueryString = strHref.substr(strHref.indexOf("?") + 1);
		var aQueryString = strQueryString.split("&");
		for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
			if (aQueryString[iParam].indexOf(pName + "=") == 0 ) {
				var aParam = aQueryString[iParam].split("=");
				result = aParam[1];
				
				var sqPos = result.indexOf("#");
				if(sqPos > -1 ) {					
					result = result.substring(0, sqPos);					
				}				
				break;
			}
		}
	}
	return unescape(result);
}

function setImageSource(id, source) {
	if(id && source) {	
		var element = getElement(id);
		
		if(element && typeof element != 'undefined') {
			var elTagName = getTagName(element);
			if(elTagName == 'IMG') {
				if(element.src && element.src.length > 0) {
					//check if image will be converted with ic
					if(element.src.indexOf("/img/ic?") > -1 && element.src.indexOf("url=") > -1) {
						//current image is trancoded by ic - so replace url to image						
						source = escape(source);
						source = source.replace(/\//g,"%2F"); 
						
						var newSource = element.src.replace(/url=[^&]+/, "url="+source);
						element.src = newSource;						
					} else {
						element.src = source;
					}
				} else {
					//image has no source yet
					element.src = source;
				}				
			}
		}	
	}
}

function removeElement(id) {
	if(id) {
		var element = getElement(id);
		if(element && typeof element != 'undefined' && element.parentNode) {
			var parentElement = element.parentNode;			
			parentElement.removeChild(element);
		}		
	}
}

function goToAnchor(anchor) {
	if(anchor) {
		var myHref = document.location.href;
		
		if(anchor.indexOf("#") != 0) {
			anchor = "#" + anchor;
		}
		
		if(myHref.indexOf("#") != -1) {
			//replace #...
			myHref = myHref.replace(/#\w*/g,anchor); 
			document.location.href = myHref;
		} else {
			var newLocation = myHref + anchor;
			document.location.href = newLocation;
		}		
	}
}

function goToLink(link) {
	if(link) {
		document.location.href = link;
	}
}

function hideToolbar() {
	if(window.scrollTo) {
		window.scrollTo(0, 1);		
	}
}

function getXHRObject() {
	var xhr = null;
	if (window.XMLHttpRequest) {
		xhr = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		try {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} catch(e) {
			try {
				xhr = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				try {
					xhr = new ActiveXObject("Msxml2.XMLHTTP.4.0");
				} catch(e) {
					try {
						xhr = new ActiveXObject("Msxml2.XMLHTTP.5.0");
					} catch(e) {
						handleError("Error - ActiveX component not found")
						xhr = null;
					}
				}
			}
		}
	} else {
		//device does not provide a xmlhttprequest object
		handleError("Device is not ajax capable");
	}
	return xhr;
}

function getRemoteContent(id, page) {
	getRemoteContentInt(id, page, false);
}

function appendRemoteContent(id, page) {
	getRemoteContentInt(id, page, true);
}


/*
 * remote content loading
 */
function getRemoteContentInt(id, page, append) {
	var xhr = getXHRObject(); 
	var curElement = id;
	
	if(page.indexOf("/") != 0) {
		page = "/"+page;
	}
	
	//disable javascript display detection
	if(page.indexOf("?") >= 0) {
		page = page + "&";
	} else {
		page = page + "?";
	}
	page = page + "disablejsd=true";
	
	xhr.open('get',"/nbinternal/nbajax"+page, true);
	if(xhr.setRequestHeader) {
		xhr.setRequestHeader("Cache-Control", "no-transform");
	}
	//with response handler
	if(append) {
		xhr.onreadystatechange = function() { setappendRemoteContent(xhr, curElement); };
	} else {
		xhr.onreadystatechange  = function() { setRemoteContent(xhr, curElement); };
	}	
	xhr.send(null);
}

function getRemoteBiscuit(id, page, biscuitid, loadcontent) {
	getRemoteBiscuitInt(id, page, biscuitid, loadcontent, false);
}

function appendRemoteBiscuit(id, page, biscuitid, loadcontent) {
	getRemoteBiscuitInt(id, page, biscuitid, loadcontent, true);
}

function getRemoteBiscuitInt(id, page, biscuitid, loadcontent, append) {
	var xhr = getXHRObject(); 
	var curElement = id;

	if(page.indexOf("/") != 0) {
		page = "/"+page;
	}

	if(page.indexOf("?") >= 0) {
		page = page + "&";
	} else {
		page = page + "?";
	}
	page = page + "nbbiscuitid=" + biscuitid;
	
	if(loadcontent && loadcontent == '1') {
		page = page + "&nbloadcontent=1";
	}

	//disable javascript display detection
	page = page + "&disablejsd=true";

	xhr.open('get',"/nbinternal/nbajax"+page, true);	
	if(xhr.setRequestHeader) {
		xhr.setRequestHeader("Cache-Control", "no-transform");
	}
	//with response handler
	if(append) {
		xhr.onreadystatechange = function() { setappendRemoteContent(xhr, curElement) };
	} else {
		xhr.onreadystatechange = function() { setRemoteContent(xhr, curElement); };
	}
	
	xhr.send(null);
}
 
function setRemoteContent(xhr, curElement) {
	if(xhr && xhr.readyState == 4){
		if (xhr.status == 200 || xhr.status == 304) {
			var response = xhr.responseText;	
			var element = getElement(curElement);
			element.innerHTML = response;
		}
	}
}

function setappendRemoteContent(xhr, curElement) {
	if(xhr && xhr.readyState == 4){
		if (xhr.status == 200 || xhr.status == 304) {			
			var response = xhr.responseText;
			var element = getElement(curElement);
			element.innerHTML = element.innerHTML + response;
		}
	}
}


/*
 * Image zoom functions
 */
function zoomIn(id, zoomFactor) {
	var element = getElement(id);
	
	if(element && typeof element != 'undefined' && zoomFactor ) {
		var elTagName = getTagName(element);
		if(elTagName == 'IMG') {
			var currentWidth = element.width;
			var currentHeight = element.height;
			
			//zoom factor must be a string due to nokia series 60 js interpreter issue with float parameters
			var zoomFactorFloat = parseFloat(zoomFactor);
			
			var newWidth = parseInt(currentWidth*zoomFactorFloat);
			var newHeight = parseInt(currentHeight*zoomFactorFloat);
			
			element.style.width = newWidth+"px";
			element.style.height = newHeight+"px";
			element.width = newWidth;
			element.height = newHeight;					
		}		
	}
}

function zoomOut(id, zoomFactor) {
	var element = getElement(id);
	
	if(element && typeof element != 'undefined' && zoomFactor) {
		var elTagName = getTagName(element);
		if(elTagName == 'IMG') {
			var currentWidth = element.width;
			var currentHeight = element.height;
			
			//zoom factor must be a string due to nokia series 60 js interpreter issue with float parameters
			var zoomFactorFloat = parseFloat(zoomFactor);
			
			var newWidth = parseInt(currentWidth/zoomFactorFloat);
			var newHeight = parseInt(currentHeight/zoomFactorFloat);
								
			element.style.width = newWidth+"px";
			element.style.height = newHeight+"px";
			element.width = newWidth;
			element.height = newHeight;					
		}		
	}
}

var imgSwap = new Array();

function zoomSwap(id, zoomFactor) {
	var element = getElement(id);
	
	if(element && typeof element != 'undefined' && zoomFactor) {
		var elTagName = getTagName(element);
		if(elTagName == 'IMG') {
			if(imgSwap[id] == true) {
				zoomOut(id, zoomFactor);
				imgSwap[id] = false;
			} else {
				zoomIn(id, zoomFactor);
				imgSwap[id] = true;
			}			
		}
	}
}

/*
 * set and get value functions for form scripting
 */
function setValue(id, value) {
	var element = getElement(id);	
	setValueInt(element, value);
}

function setValueFrom(id, from) {
	var element = getElement(id);
	var fromElement = getElement(from);
		
	if(element && fromElement) {
		var elTagName = getTagName(element);
		
		//get the from value
		var fromValue = getValue(fromElement)	
				
		//set the value
		setValueInt(element, fromValue)
	}
}

function getValue(element) {
	var result = "";	
	if(element) {
		var elTagName = getTagName(element);		
		if(elTagName && (elTagName == 'INPUT' || elTagName == 'SELECT')) {
			result = element.value;
		} else {
			result = element.innerHTML;
		}
	}	
	return result;
}

function setValueInt(element, value) {
	if(element) {
		var elTagName = getTagName(element);		
		if(elTagName && (elTagName == 'INPUT' || elTagName == 'SELECT')) {
			element.value = value;
		} else {
			element.innerHTML = value;
		}
	}	
}

function getTagName(element) {
	var tagName;
	if(element) {
		tagName = element.tagName;
		if(! tagName) tagName = element.nodeName;
		if(tagName.toUpperCase) {
			tagName = tagName.toUpperCase();
		}
	}
	return tagName;
}

/*
 * Timout and interval actions
 */
var nbIntervals = new Array();
function addInterval(name, time, method) {	
	var newInterval = window.setInterval(method, time);	
	nbIntervals[name] = newInterval;
}
function removeInterval(name) {
	var tmpInterval = nbIntervals[name];
	if(tmpInterval) {		
		window.clearInterval(tmpInterval);
		nbIntervals[name] = null;
	}
}

var nbTimeouts = new Array();
function addTimeout(name, time, method) {	
	var newTimeout = window.setTimeout(method, time);	
	nbTimeouts[name] = newTimeout;
}
function removeTimeout(name) {
	var tmpTimeout = nbTimeouts[name];
	if(tmpTimeout) {		
		window.clearTimeout(tmpTimeout);
		nbTimeouts[name] = null;
	}
}


/*
 * sliding transition (Mode1)
 */
var loadedContainers = new Array();
var activeContainer;
var lockReplaceContainer = false;
var preparedBodyToScroll = false;
var movingSpeed = 20;
var moveInterval = 0;
var locationMonitor;
var hashPrefix = "#__";


var containerHistoryStack = new Array();

function prepareToMoveContainer() {
	if(! preparedBodyToScroll) {
		document.body.style.overflowX = "hidden";
				
		var headElement = document.getElementsByTagName("head")[0];
		var metaElement = document.createElement("meta");
		metaElement.name = "viewport";
		metaElement.content = "initial-scale=1.0;";		
		headElement.appendChild(metaElement);
		
		//start anchor controller
		enableLocationMonitor();
		
		preparedBodyToScroll = true;
	}
}

function checkLocation() {
	var currentAnchor = window.location.hash;	
	if(currentAnchor != hashPrefix+activeContainer) {		
		disableLocationMonitor();
		replaceActiveWithLoadedContainer(currentAnchor.substring(hashPrefix.length));
	}
}

function enableLocationMonitor() {
	if(! locationMonitor) {
		locationMonitor = window.setInterval(checkLocation, 300);
	}
}
function disableLocationMonitor() {
	window.clearInterval(locationMonitor);
	locationMonitor = null;
}

function replaceActiveWithLoadedContainer(newContainer) {
	if(arrayContains(loadedContainers, newContainer)) {	
		if(! lockReplaceContainer) { //only do this when replace is not in progress
			//shows previous active container
			var currentContainerId = activeContainer;
			var previousContainerId = newContainer;
			
			var index = containerHistoryStack.indexOf(newContainer);
            var backwards = index != -1;
            if (backwards) {
                containerHistoryStack.splice(index, containerHistoryStack.length);
            }
			
			if(currentContainerId && previousContainerId) {
				var currentContainer = getElement(currentContainerId);
				var previousContainer = getElement(previousContainerId);
				
				if(currentContainer && previousContainer) {
					//prepare to move
					prepareNewContainer(previousContainer, currentContainer, backwards);
					
					//move
					moveContainer(currentContainer, previousContainer, backwards);
					
					if(! backwards) {
						if(activeContainer) {
							//add last active value to history
							containerHistoryStack.push(activeContainer);
						}
					}
					
					//update values
					activeContainer = previousContainerId;
					goToAnchor(hashPrefix+activeContainer);
					hideToolbar();
					enableLocationMonitor();
				}
			}	
		}
	}	
}

function replaceContainerBackwards(id, page, containerToLoad) {
	replaceContainerInt(id, page, containerToLoad, true);
}

function replaceContainer(id, page, containerToLoad) {
	replaceContainerInt(id, page, containerToLoad, false);
}

function replaceContainerInt(id, page, containerToLoad, backwards) {
	if(! lockReplaceContainer) {
		if(id && page && containerToLoad) {
			if(!activeContainer || activeContainer == id) {
				prepareToMoveContainer();
				
				var containerKey = containerToLoad;
				
				if(!activeContainer || containerKey != activeContainer) {//container not the active one
					lockReplaceContainer = true; // block for more calls
										
					//check if container has been loaded
					if(arrayContains(loadedContainers, containerKey)) {
						//container is hidden on page
						var newContainer = getElement(containerKey);
						var element = getElement(id);
									
						if(newContainer && element) {
							//prepare container
							prepareNewContainer(newContainer, element, backwards);	
			
							//move container
							moveContainer(element, newContainer, backwards);
							
							if(activeContainer) {
								//add last active value to history
								containerHistoryStack.push(activeContainer);
							}
							
							disableLocationMonitor();
							activeContainer = containerKey;
							goToAnchor(hashPrefix+activeContainer);
							hideToolbar();
							enableLocationMonitor();
						} else {
							lockReplaceContainer = false; //error -> release lock
						}
						
						
					} else {
						var xhr = getXHRObject(); 
						
						//load remote content						
						if(page.indexOf("/") != 0) {
							page = "/"+page;
						}
					
						if(page.indexOf("?") >= 0) {
							page = page + "&";
						} else {
							page = page + "?";
						}
						page = page + "nbbiscuitid=" + containerToLoad + "&nbloadcontent=0";
						//disable javascript display detection
						page = page + "&disablejsd=true";
						
						xhr.open('get',"/nbinternal/nbajax"+page, true);	
						if(xhr.setRequestHeader) {
							xhr.setRequestHeader("Cache-Control", "no-transform");
						}
						
						xhr.onreadystatechange = function() { loadedContainer(xhr, id, containerKey, backwards) };
						xhr.send(null);	
					}			
				}
			}
		}
	}
}

function containerBack() {
	if(! lockReplaceContainer) { //only do this when replace is not in progress
		//shows previous active container
		var currentContainerId = activeContainer;
		var previousContainerId = containerHistoryStack.pop();
		
		if(currentContainerId && previousContainerId) {
			var currentContainer = getElement(currentContainerId);
			var previousContainer = getElement(previousContainerId);
			
			if(currentContainer && previousContainer) {
				//prepare to move
				prepareNewContainer(previousContainer, currentContainer, true);
				
				//move
				moveContainer(currentContainer, previousContainer, true);
				
				//update values
				disableLocationMonitor();
				activeContainer = previousContainerId;
				goToAnchor(hashPrefix+activeContainer);
				hideToolbar();
				enableLocationMonitor();
			}
		}	
	}
}

function loadedContainer(xhr, curElement, containerKey, backwards) {
	if(xhr && xhr.readyState == 4){
		if (xhr.status == 200 || xhr.status == 304) {
			var response = xhr.responseText;			
			var element = getElement(curElement);
			
			//create new element
			var newContainer = getSingleDomByHTML(response);
			newContainer.style.display = "none";
					
			if(newContainer) {
  				//container loaded
  				
  				//add to loadedContainers
  				loadedContainers.push(containerKey);
  				
  				//set old container position to absolute  				
  				var currentX = getOffsetTop(element);
				var oldContainerMarginTop = getTopMarginPx(element);
				if(oldContainerMarginTop > 0 && currentX >= oldContainerMarginTop) {
					currentX = currentX - oldContainerMarginTop;
				}
  				
				var currentWidth = element.offsetWidth;
				element.style.top = currentX+"px";
				element.style.width = currentWidth + "px";
				element.style.position = "absolute";
				
				prepareNewContainer(newContainer, element, backwards);		
				
				moveContainer(element, newContainer, backwards);
								
				//set the active element
				if(!activeContainer) {
					//add the replaced container to the hidden elements
					if(element.id) {
						loadedContainers.push(element.id);
					}
				} else {
					//add last active value to history
					containerHistoryStack.push(activeContainer);
				}
				
				disableLocationMonitor();
				activeContainer = containerKey;
				goToAnchor(hashPrefix+activeContainer);
				hideToolbar();
				enableLocationMonitor();
			} else {
				lockReplaceContainer = false; //error -> release lock
			}					
		} else {
			lockReplaceContainer = false; //error -> release lock
		}
	}
}

function prepareNewContainer(newContainer, oldContainer, backwards) {
	//set position of new element
	if(newContainer && oldContainer) {
		var currentWidth = oldContainer.offsetWidth;
		
		newContainer.style.position = "absolute";
		newContainer.style.width = currentWidth + "px";
		newContainer.style.display = "block";
		
		if(backwards) {
			newContainer.style.left = "-100%";
		} else {
			newContainer.style.left = "100%";
		}	
		
		oldContainer.parentNode.appendChild(newContainer);
		
		var currentX = getOffsetTop(oldContainer);		
		var newContainerMarginTop = getTopMarginPx(newContainer);
		if(newContainerMarginTop > 0 && currentX >= newContainerMarginTop) {
			currentX = currentX - newContainerMarginTop;
		}
		
		newContainer.style.top = currentX+"px";	
	}
}

function moveContainer(from, to, backwards)
{        
	var useTranslate = false;
	if(window && "onwebkitanimationend" in window) {
		useTranslate = true;
		movingSpeed = 10;
	}
	
    var percent = 100;
    move();
    var tmpTimer = setInterval(move, moveInterval);

    function move()
    {
        var lastRun = false;
		
		percent -= movingSpeed;
        if (percent < 1)
        {
            percent = 0;
            clearInterval(tmpTimer);
            from.style.display = "none";
            lockReplaceContainer = false; //everything is done -> release lock
			
			if(useTranslate) {
				to.style.left = "0%";
				to.style.webkitTransform = '';
				lastRun = true;
			}
        }
    	
    	var FromValue = (backwards ? 100-percent : percent-100) + "%";
    	var ToValue = (backwards ? -percent : percent) + "%";
    	
    	if(useTranslate) {
    		from.style.webkitTransform = 'translate(' + FromValue + ', 0px)';
    		if(! lastRun) {
				to.style.webkitTransform = 'translate(' + FromValue + ', 0px)';
			}
    	} else {
        	from.style.left = FromValue; 
        	to.style.left = ToValue;
    	} 
    }
}

function setActiveContainer(containerId) {
	if(containerId && getElement(containerId)) {
		disableLocationMonitor();
		activeContainer = containerId;
		loadedContainers.push(containerId);
		goToAnchor(hashPrefix+activeContainer);
		hideToolbar();
		enableLocationMonitor();
	}
}

function replaceActiveContainer(page, containerToLoad) {
	if(activeContainer) {
		replaceContainer(activeContainer, page, containerToLoad);
	}
}

function replaceActiveContainerBackwards(page, containerToLoad) {
	if(activeContainer) {
		replaceContainerBackwards(activeContainer, page, containerToLoad);
	}
}

function removeContainer(containerId) {
	if(arrayContains(loadedContainers, containerId) && activeContainer != containerId && !lockReplaceContainer) {
		var container = getElement(containerId);
		
		if(container) {
			//remove from page
			container.parentNode.removeChild(container);
		}
		
		//remove from loaded containers
		removeFromArray(loadedContainers, containerId);
		
		//remove from history
		removeFromArray(containerHistoryStack, containerId);
	}
}
/*
 * Transition end
 */

/*
 * Image fading - Mode 1
 */
var activeImages = new Array();
var fadingImages = new Array();
var availableImages = new Array();
var activeFadings = new Array();

function addFadingImage(faderIdentifier, firstImage, page, remoteimageId) {
	if(fadingImages[faderIdentifier]) {
		firstImage = faderIdentifier + firstImage
	}
	
	//get the first image && parent
	var rootimage = getElement(firstImage);	

	if(faderIdentifier && rootimage && firstImage && page && remoteimageId) {
		if(!fadingImages[faderIdentifier]) {
			var firstImageId = faderIdentifier + firstImage;
			
			//set the active image
			activeImages[faderIdentifier] = firstImageId;
			
			fadingImages[faderIdentifier] = new Array();
			fadingImages[faderIdentifier].push(firstImageId);
			
			availableImages[faderIdentifier] = new Array();
			availableImages[faderIdentifier].push(firstImageId);
			
			rootimage.id = firstImageId;
		}
		
		//load image from remote page			
		var xhr = getXHRObject(); 						
		//load remote content						
		if(page.indexOf("/") != 0) {
			page = "/"+page;
		}
	
		if(page.indexOf("?") >= 0) {
			page = page + "&";
		} else {
			page = page + "?";
		}
		page = page + "nbbiscuitid=" + remoteimageId + "&nbloadcontent=0";
		//disable javascript display detection
		page = page + "&disablejsd=true";
		
		xhr.open('get',"/nbinternal/nbajax"+page, true);
		
		if(xhr.setRequestHeader) {
			xhr.setRequestHeader("Cache-Control", "no-transform");
		}
		xhr.onreadystatechange = function() { remoteImageLoaded(xhr, faderIdentifier, rootimage, remoteimageId); };
		xhr.send(null);	
		
		//add to available images
		if(fadingImages[faderIdentifier]) {
			fadingImages[faderIdentifier].push(faderIdentifier+remoteimageId);
		}
	}	
}

function remoteImageLoaded(xhr, faderIdentifier, rootimage, remoteimageId) {
	//create remote image dom object
	if(xhr && xhr.readyState == 4){
		if (xhr.status == 200 || xhr.status == 304) {
			var response = xhr.responseText;			
						
			//create new element
			var domImage = getSingleDomByHTML(response);

			if(domImage){
				var elTagName = getTagName(domImage);
				
				if(elTagName == "IMG") {
					//prepare remote image
					domImage.style.visibility = "hidden";
					domImage.style.position = "absolute";
					setOpacity(domImage, 0);
					
					domImage.style.top = getOffsetTop(rootimage) + "px";
					domImage.style.left = getOffsetLeft(rootimage) + "px";
					domImage.style.width = rootimage.offsetWidth + "px";
					domImage.style.height = rootimage.offsetHeight + "px";
					
					domImage.id = faderIdentifier + remoteimageId;
					
					//append remote image to container
					var imageContainer = rootimage.parentNode;					
					if(imageContainer) {						
						//add to position
						imageContainer.appendChild(domImage);						
						availableImages[faderIdentifier].push(faderIdentifier + remoteimageId);
					}
				}
			}
		}
	}
}


function fadeToNextImage(identifier) {
	//get current active image	
	var imagesArray = fadingImages[identifier];
	var activeImage = activeImages[identifier];
	var nextImageId = getNextFromArray(imagesArray, activeImage, identifier);
	fadeImageInt(identifier, nextImageId);		
}

function fadeToPreviousImage(identifier) {
	//get current active image	
	var imagesArray = fadingImages[identifier];
	var activeImage = activeImages[identifier];
	var nextImageId = getPreviousFromArray(imagesArray, activeImage, identifier);
	fadeImageInt(identifier, nextImageId);	
}

function fadeToImage(identifier, remoteImageId) {
	var imagesArray = fadingImages[identifier];
	var activeImage = activeImages[identifier];
	var nextImageId = identifier + remoteImageId;
	fadeImageInt(identifier, nextImageId);
}

function fadeImageInt(identifier, nextImageId) {
	if(! activeFadings[identifier]) {
		activeFadings[identifier] = true;
		var activeImage = activeImages[identifier];
		var imagesArray = fadingImages[identifier];
		
		if(activeImage != nextImageId) {		
			if(activeImage && imagesArray) {
				if(nextImageId) {
					var nextImage = getElement(nextImageId);
					
					if(nextImage) {			
						//fade images
						nextImage.style.visibility = "visible";
						
						fadeIn(nextImageId, 0, identifier);
						fadeOut(activeImage, 100);
					} else {
						activeFadings[identifier] = false;
					}
				} else {
					activeFadings[identifier] = false;
				}		
			} else {
				activeFadings[identifier] = false;
			}
		} else {
			activeFadings[identifier] = false;
		}	
	}
}

function setOpacity(obj, opacity) {
	opacity = (opacity == 100)?99.999:opacity;  
	obj.style.filter = "alpha(opacity:"+opacity+")";
	obj.style.KHTMLOpacity = opacity/100;
	obj.style.MozOpacity = opacity/100;
	obj.style.opacity = opacity/100;
}

function fadeIn(objId,opacity,identifier) {
	var obj = getElement(objId);	
	if (opacity <= 100) {
		setOpacity(obj, opacity);
		opacity += 10;
		window.setTimeout("fadeIn('"+objId+"',"+opacity+",'"+identifier+"')", 80);
	} else {
		//set active
		activeImages[identifier] = objId;
		activeFadings[identifier] = false;
	}
}

function fadeOut(objId,opacity) {
	var obj = getElement(objId);	
	if (opacity >= 0) {
		setOpacity(obj, opacity);
		opacity -= 10;
		window.setTimeout("fadeOut('"+objId+"',"+opacity+")", 80);
	} else {
		//hide old image - visibility: hidden
		obj.style.visibility = "hidden";
	}
}

function getNextFromArray(array, current, faderIdentifier) {
	var next;
	if(array && current) {
		for(var i = 0; i < array.length; i++) {
			var tmp = array[i];
			if(current == tmp) {
				if(i == array.length - 1) {
					return array[0];
				} else {					
					if(arrayContains(availableImages[faderIdentifier], array[i+1])) {
						return array[i+1];
					} else {
						return getNextFromArray(array, array[i+1], faderIdentifier); //get next after current
					}
				}
			}
		}
	}	
	return next;
}

function getPreviousFromArray(array, current, faderIdentifier) {	
	var previous;	
	if(array && current) {
		for(var i = 0; i < array.length; i++) {
			var tmp = array[i];
			if(current == tmp) {
				if(i == 0) {
					return array[array.length - 1];
				} else {					
					if(arrayContains(availableImages[faderIdentifier], previous)) {
						return previous;
					} else {
						return getPreviousFromArray(array, previous, faderIdentifier); //get previous
					}
				}
			} else {
				previous = array[i];
			}
		}
	}	
	return previous;	
}