/**
 * scroller.js
 * 
 * @description		 Image scrolling gallery
 * @author     		 Darko Loncar <loncarster@gmail.com>
 * @copyright  		 2009-2010 Darko Loncar
 * @version    		 0.4
 *
 * Update 31.05.2010 - 0.4
 * - Better event handling, image id's not needed, all HTML inner javascript not needed anymore script compacting. 
 * - Removed getEventId function. Hard coded element ID's' are no longer necessary in image list
 * - Removed Javascript opacity in favour of CSS 3.
 * - Item selection works in W3C browsers
 * - Loading screen beta now active for main images
 *
 * Update 10.05.2010 - 0.3
 * - Bugfixes, speed improvements, script compacting, work on easier script setup, added test "loading" screen
 *
 * Update 09.05.2010 - 0.2
 * - Bugfixes, script compacting
*/

// Settings ! Make sure that width and height of thumbnails are correct. Width and thumbs_shown actually determines width of whole scroller
var thumb_width = 110; // Thumbnail width + little extra horizontal spacing (8px) + borders (6px)
var thumb_height = 100;
var image_max_width = 512;
var image_max_height = 384;
var thumb_shown = 5;
var speed = 64;

// Main elements
var scroller_element = 'scroller';
var uelm = 0;
var lelm = 0;
var images = 0;

// Global Vars
var scrolling_active = false;
var end_pos = 0;
var thumb_number = 0;
var thumb_step = 0;
var scroller_width = 0;
var selected = new Object; // Holds selected img thumbnail object

// On HTML load setup
window.onload = function() { 

	// Get main elements
	var elm = document.getElementById(scroller_element);
	var lelm = elm.getElementsByTagName("li");
	var images = elm.getElementsByTagName('img');
	var links = elm.getElementsByTagName('a');

	uelm = elm.getElementsByTagName("ul")[0];

	// Get number thumbs
	thumb_number = images.length;

	// Pre-calculate scroller width
	scroller_width = thumb_width * thumb_number;

	// Pre-calculate pixel step needed to achieve desired speed
	thumb_step = thumb_width * thumb_shown;

	// On-the-fly wrapper elements styling
	elm.style.cssText = 'overflow: hidden; height: 100px; width:'+thumb_step +'px';
	uelm.style.cssText = 'position: relative; display: block; padding: 0px; margin: 0px; top: 0px; left: 0px; overflow: hidden; width:'+scroller_width+'px; height:'+thumb_height+'px';

	// List items styling
	for (var x=0; x<thumb_number; x++){
		lelm[x].style.cssText = 'float: left; text-align: center; width:'+thumb_width+'px; height:'+thumb_height+'px';				
		}

	// Set click events on scroll buttons		
	if(window.addEventListener){
		document.getElementById('left').addEventListener('mousedown', function() { scroll('left') }, true)
		document.getElementById('right').addEventListener('mousedown', function() { scroll('right') }, true)
		}
	else {
		document.getElementById('left').attachEvent('onmousedown', function() { scroll('left') })
		document.getElementById('right').attachEvent('onmousedown', function() { scroll('right') })
		}

	// Set thumbnails events and style
	for (var x = 0; x < thumb_number; x++) 
		{
		if (window.addEventListener) // W3C - FF, Chrome, Safari, Opera style
			{ 
			// Opacity events for thumbs (We use "this" keyword since it's faster than determining event source )
			images[x].addEventListener('mouseover', function() { 

					if (!(this.className == 'selected')) // Do not dim thumbnail on mouseover if it's a selected
						{
						changeOpac(this, 0.6) 
						}

					}, false);


			images[x].addEventListener('mouseout', function() { changeOpac(this, 1) }, false)

			// Set events for thumbnail click
			links[x].addEventListener('click', function(e) { 

					// Show image in display DIV
					show_image(this.href);

					// Change class name of selected object. Save object in global var
					selected.className = null; // Reset previously selected thumb
					this.firstChild.className = "selected"; // Set selected CSS class to newly selected object
					selected = this.firstChild; // Save selected thumb

					changeOpac(this.firstChild, 1)

					// Prevent the default browser action for links (W3C)
					if ( e && e.preventDefault )
					e.preventDefault();

					}, false);
			}
		else // Same thing but IE version
			{
			// Opacity events for thumbs IE (In developement)

			// Set events for thumbnail click
			links[x].attachEvent('onclick', function(e) { 

					// Get event source for IE (Slower but IE sucks and we can't use "this" keyword)
					e = e || event; 
					href = (e.srcElement || e.target).parentNode.href;
					img_obj = e.srcElement;

					// Change class name of selected object. Save object in global var
					selected.className = null;	
					img_obj.className = "selected";
					selected = img_obj;

					// Show image in display
					show_image(href); 

					// Prevent the default browser action for links (IE)
					window.event.returnValue = false;
					return false; 
					});
			}			
		} // End event setting loop
	} // End onload


// Scroller function
function scroll(direction) {
	if (!(scrolling_active==true)) {
		var start_pos = parseInt(getLeftPos(uelm));

		if (direction == 'left') {
			if (!(start_pos == 0)) {
				end_pos = start_pos + thumb_step;
				scrolling = setInterval(function() { 		
					var left_pos = parseInt(getLeftPos(uelm));
					var travel_left = Math.abs(end_pos - left_pos);
					if (travel_left < speed) { 
						uelm.style.left = left_pos + travel_left + 'px'; 
						clearInterval(scrolling);
						scrolling_active = false;		
						}
					else {uelm.style.left = left_pos + speed + 'px';}																				
					}, 40);
				scrolling_active = true;
				}
			}
		if (direction == 'right') {
			if (!((scroller_width) - Math.abs(start_pos) <= thumb_step)) {
				end_pos = start_pos - (thumb_step);
				scrolling = setInterval(function() 
					{ 
					var left_pos = parseInt(getLeftPos(uelm));
					var travel_left = Math.abs(end_pos - left_pos);
					if (travel_left < speed) { 
						uelm.style.left = left_pos - travel_left + 'px'; 
						clearInterval(scrolling);
						scrolling_active = false;					
						}
					else { uelm.style.left = left_pos - speed + 'px'; }			
					}, 40); 
				scrolling_active = true;				
				}
			}
		}
	}

function getLeftPos(el) {
	if (el.currentStyle)
	var st = el.currentStyle['left'];
	else if (window.getComputedStyle)       
	var st = document.defaultView.getComputedStyle(el, null).getPropertyValue('left');
	return st;
	}                                                     

function show_image(href)
	{
	// Get main image display element
	var main_img = document.getElementById('main_scroller_image');

	// Opera has a habbit to pull images from cache. In that case. onload event sometimes won't happen and we can't rely on it
	// We are checking if image is already completed, and if it is, then show it immediately. Else attach load event and display
	// loading progress bar

	// Pre load requested image
	var loader_image = new Image();
	loader_image.src = href;

	if (loader_image.complete == true)
		{
		// Display image directly if it's cached
		main_img.src = loader_image.src;
		}
	else
		{
		// Display "loading" image
		main_img.src='images/loader.gif';

		// Wait for image loading to complete and display it
		if(window.addEventListener){
			loader_image.addEventListener ('load', function() { main_img.src = loader_image.src; }, true);
			}
		else {
			loader_image.attachEvent ('onload', function() { main_img.src = loader_image.src; });
			}
		}	
		main_img.setAttribute("height", image_max_height); // resize image to proper height TODO: Better image scaling
	}

// Changes opacity
function changeOpac(obj, opacity) 
      {
      	obj.style.opacity = opacity;
      	obj.style.MozOpacity = opacity;
      	obj.style.KhtmlOpacity = opacity;
      }


