/**
 * This piece of code provides the functionality to select different tabs in the product_overview box.
 * It also adds the animation to the list of tabs.
 */

/**
 * Configuration variabeles
 */
var po_scrollStep = 200; // One click of the button moves the tabbar by scrollStep pixels
var po_duration = 200; // Duration of the animations in ms

/* Add an event handler to the onload event calling the initialization function */
po_addEventHandler(window, 'load', po_init);

/* Horizontal position of the tabbar */
var po_tabBarPosition = 0;

/* Currently selected tab */
var po_currentTab = 0;

/* All tabs */
var po_tabs = [];
var po_tabBodies = [];

/* Handle to the animation timer. */
var po_timerid;

/**
 * Initialization
 */
function po_init()  {

	var productOverview = document.getElementById('productoverviewbox');

    if(!productOverview) {
        
        return;
    }

	var uls = productOverview.getElementsByTagName('UL');

	tabBar = uls[0];

	/* Minimum position of the left edge of the tabbar */
	var po_min = 670-tabBar.offsetWidth;

	/* Maximum position of the left edge of the tabbar */
	var po_max = 0; 

	/* Add event handlers to the more and less button */
	moreButton = document.getElementById('more_button');
	lessButton = document.getElementById('less_button');

	po_addEventHandler(moreButton, 'click', po_scrollRight);
	po_addEventHandler(lessButton, 'click', po_scrollLeft);

	/* Find all the tabs */
	var tabs = tabBar.getElementsByTagName('LI');

	for(i=0; i<tabs.length; i++) {
		po_tabs.push(tabs[i]);
		
		/* Attach onclick handlers */
		po_addEventHandler(tabs[i], 'click', po_changeTab);
	}

	/* Find all the tab-bodies */
	po_tabBodies = po_getElementsByClassName(productOverview, 'tabBody');

	/**
	 * Scroll the tab bar to the right.
	 * hide/show buttons accordingly
	 */
	function po_scrollRight() {

		var prevTabBarPosition = po_tabBarPosition;
		po_tabBarPosition -= po_scrollStep;

		/* Show less button */
		if(po_tabBarPosition < po_max) {

			lessButton.style.display = 'block';

			po_animate(

				lessButton.style.opacity-0, 1, po_duration,

				function(value) {
					lessButton.style.opacity = value;
				}, null
			);
		}

		/* Hide more button */
		if(po_tabBarPosition <= po_min) {

			po_tabBarPosition = po_min;

			po_animate(

				moreButton.style.opacity-0, 0, po_duration,

				function(value) {
					moreButton.style.opacity = value;
				},

				function(value) {
					moreButton.style.display = 'none';
				}
			);
		}

		po_animate(
			prevTabBarPosition,
			po_tabBarPosition,
			po_duration,
			function(value) { 
				tabBar.style.left = value +'px';
			}, null
		);
	}

	/**
	 * Scroll the tab bar to the left.
	 * hide/show buttons accordingly
	 */
	function po_scrollLeft() {

		var prevTabBarPosition = po_tabBarPosition;
		po_tabBarPosition += po_scrollStep;

		/* Show more button */
		if(po_tabBarPosition > po_min) {

			moreButton.style.display = 'block';

			po_animate(
				moreButton.style.opacity-0, 1, po_duration,
				function(value) {
					moreButton.style.opacity = value;
				}, null
			);
		}

		/* Hide less button */
		if(po_tabBarPosition >= po_max) {

			po_tabBarPosition = po_max;

			po_animate(
				lessButton.style.opacity-0, 0, po_duration,
				function(value) {
					lessButton.style.opacity = value;
				},
				function(value) {
					lessButton.style.display = 'none';
				}
			);
		}

		po_animate(
			prevTabBarPosition,
			po_tabBarPosition,
			po_duration,
			function(value) { 
				tabBar.style.left = value +'px';
			}, null
		);
	}

	function po_changeTab(e) {

		if(!e) e = window.event;
		
		var target;
		if(e.target) target = e.target;
		else if(e.srcElement) target = e.srcElement;

		// Hide all other tabs and show the new tab
		for(i=0; i<po_tabs.length; i++) {

			if(po_tabs[i] == target) {

				po_tabs[i].className = 'selected';

				if(po_tabBodies[i]) {
					po_tabBodies[i].style.display = 'block';
					po_tabBodies[i].className = 'tabBody selected';
				}
			} else {

				po_tabs[i].className = '';

				if(po_tabBodies[i]) {
					po_tabBodies[i].style.display = 'none';
					po_tabBodies[i].className = 'tabBody';
				}
			}
		}

		return false;
	}

}

/**
 * Meant to be called from outside to select the tab based on the content of the tab (ie: the product name)
 * @param content The HTML content of the tab
 */
function po_selectTab(content) {

	// Hide all other tabs and show the new tab
	for(i=0; i<po_tabs.length; i++) {

		if(po_tabs[i].innerHTML.toLowerCase() == content.toLowerCase()) {

			po_tabs[i].className = 'selected';

			if(po_tabBodies[i]) {

				po_tabBodies[i].style.display = 'block';
				po_tabBodies[i].className = 'tabBody selected';
			}

		} else {

			po_tabs[i].className = '';

			if(po_tabBodies[i]) {

				po_tabBodies[i].style.display = 'none';
				po_tabBodies[i].className = 'tabBody';
			}
		}
	}
}

/**
 * Animate a variabele given a timespan and two extremes.
 * At each frame the callback function will be called with the interpolated variable.
 * Framerate will be about 30fps.
 * @param start The starting value of the variabele to interpolate (t=0)
 * @param target The target value of the variabele (t=timespan)
 * @param duration Duration of the animation in miliseconds.
 * @param callback The callback function that will be called at each frame.
 * @param final_callback Callback function that is called when the animation is finished.
 */
function po_animate(start, target, duration, callback, final_callback) {

	var position = 0;
	var fps = 30;

	// Stop previous animation	
	// clearTimeout(po_timerid);

	/* Begin new one */
	var po_timerid = setTimeout(po_interpolate, 1000/fps);

	/**
	 * Interpolate the variabele and call the callback function
	 */
	function po_interpolate() {

		/* Check if target has been reached */
		if(position >= 1) {

			position = 1;
			callback(target);

			if(final_callback) {

				final_callback(target);
            }

		} else {

			position += 1/(duration/fps);

			/* Easing function */
			var p = 0.5 * (1-Math.cos(position*Math.PI));

			callback( start + (target-start)*p );

			po_timerid = setTimeout(po_interpolate, 1000/fps);
		}
	}
}

/**
 * Cross browser event handling: attach an eventhandler.
 * @param element The element to attach the event to.
 * @param e The name of the event
 * @param callback The callback function that handles the event
 */
function po_addEventHandler(element, e, callback) {

	if(element.attachEvent) {

		element.attachEvent('on'+ e, callback);

	} else if(element.addEventListener) {

		element.addEventListener(e, callback, false);

	}
}

/**
 * Cross browser event handling: remove an eventhandler.
 * @param element The element to remove the event from.
 * @param e The name of the event
 * @param callback The callback function that handles the event
 */
function po_removeEventHandler(element, e, callback) {

	if(element.detachEvent) {

		element.detachEvent('on'+ e, callback);

	} else if(element.removeEventListener) {

		element.removeEventListener(e, callback, false);

	}
}

/**
 * Finds all child elements with the given classname
 * @param root The elements that are returned will be children of this root element
 * @param className The classname to look for
 * @return Array All child elements with the given classname
 */
function po_getElementsByClassName(root, className) {

	var list = [];

	var elements = root.getElementsByTagName('*');

	for(i=0; i<elements.length; i++) {

		var element = elements[i];

		if( (' '+ element.className +' ').indexOf(' '+ className +' ') != -1 ) {
		
            list.push(element);

        }
	}

	return list;
}
