/*
  SAPO Carrossel - v2.0.1

  Author: David Oliveira <david -dot- oliveira -at- co -dot- sapo -dot- pt>
 */

var
	carrossel2Inited = 0,
	carrossel2CurId = 0,
	carrossels = new Array();


// Carrossel2 object

function Carrossel2 ( ) {

	// Some settings

	this.pageItems		= 3;
	this.slideItems		= 3;
	this.speed		= 3;
	this.frameTime		= 33;

	// Internal stuff

	this.pos		= 0;
	this.items		= 0;
	this.itemDims		= null;
	this.element		= null;
	this.top		= 0;
	this.left		= 0;
}


// Detect all the UL's with carousel-list as class name and turn it on a carousel

function initCarrossel2 ( ) {

	var
		listEl = "ul",
		listEls = document.getElementsByTagName(listEl),
		lists = new Array(),
		id = carrossel2CurId++;

	if ( carrossel2Inited++ ) return;


	// Copy list array

	for ( var x = 0 ; x < listEls.length ; x++ )
		if ( listEls[x].className.match(/carrossel\b/) )
			lists[lists.length] = listEls[x];


	// For each...

	for ( var x = 0 ; (list = lists[x]) != null ; x++ )
		initCarrossel2List(id,list);

}


// Initialize a carrossel unordered list

function initCarrossel2List ( id, ul ) {

	var
		car = getCarrossel2ListProps(ul),
		navBtns = findCarrossel2NavButtons(ul),
		scrollNav = findCarrossel2ScrollNav(ul),
		carDiv = document.createElement("DIV");

	// Read carrossel parameters

	readCarrossel2Pars(car,ul);

	// Fix some things.. If number of items < page items, page items will be number of items

	if ( car.items < car.pageItems )
		car.pageItems = car.items;


	// Add this to carrossel array

	carrossels.push(car);

	// Set some elements on carrossel

	car.navButtons = navBtns;
	car.scrollNav = scrollNav;
	car.parentDIV = carDiv;

	// Create carrossel div

	carDiv.className = "carrossel-div";
	carDiv.style.overflow = 'hidden';
	carDiv.style.zIndex = 0;
	carDiv.style.position = 'absolute';
	carDiv.style.width = car.itemDims.w+'px';
	carDiv.style.height = (car.itemDims.h * car.pageItems)+'px';

	// Replace list with carrossel div

	ul.parentNode.replaceChild(carDiv,ul);
	carDiv.appendChild(ul);

	// Set navigation button handlers and create page indicators

	addCarrossel2NavHandlers(id,navBtns);
	addCarrossel2PageIndicators(id,scrollNav);

	// Update arrows status

	updateCarrossel2ArrowsStatus(id);

	// Show carrossel

	ul.style.visibility = 'visible';

}


// Read carrossel parameters

function readCarrossel2Pars ( car, ul ) {

	var
		propStr = ul.className;
		pSets = propStr.split(' '),
		allowedProps = { pageItems: 1, slideItems: 1, speed: 1, frameTime: 1 };

	for ( var x = 1 ; x < pSets.length ; x ++ ) {
		var
			pSet = pSets[x].split('='),
			prop = pSet[0];

		if ( allowedProps[prop] )
			car[prop] = pSet[1];
	}


}

// Go to carrossel previous item

function gotoCarrossel2Prev ( id ) {

	var
		car = carrossels[id],
		toPos = car.pos-car.slideItems;

	if ( toPos != car.pos )
		gotoCarrossel2Pos(id,toPos);

}


// Go to carrossel next item

function gotoCarrossel2Next ( id ) {

	var
		car = carrossels[id],
		toPos = car.pos+car.slideItems;

	gotoCarrossel2Pos(id,toPos);

}

// Slide carrossel to position

function slideCarrossel2Pos (id) {

	var
		car = carrossels[id],
		dest = (car.pos * car.itemDims.h),
		dist = dest - car.top,
		step = dist / car.speed;

	// Remove focus from buttons

	clearSelection();

	// Set margin

	car.top += step;
	car.element.style.marginTop = (0-parseInt(car.top))+"px";

	// Selaunch slide method or if we are at the end.. correct some values

	if ( Math.abs(step) > 0.1 )
		setTimeout("slideCarrossel2Pos("+id+")",car.frameTime);
	else {
		car.top = dest;
		car.element.style.marginTop = (0-parseInt(car.top))+"px";
		onCarrossel2SlideEnd(id);
	}

}


// Fire this function when carrossel slide ends

function onCarrossel2SlideEnd ( id ) {

	// Update arrows status

	updateCarrossel2ArrowsStatus(id);

	// Update page indicators

	updateCarrossel2PageIndicators(id);

}


// Go to carrossel item

function gotoCarrossel2Pos ( id, pos ) {

	var
		car = carrossels[id];

	// Correct some positions

	if ( pos < 0 )				pos = 0;
	if ( pos > car.items-car.pageItems )	pos = car.items-car.pageItems;
	if ( pos == car.pos )			return 0;

	car.pos = pos;
	slideCarrossel2Pos(id);

}


// Add navigation button handlers to carrossel

function addCarrossel2NavHandlers ( id, nav ) {

	var
		prev = ($(nav).select('[class="prev"]'))[0],
		next = ($(nav).select('[class="next"]'))[0];

	// Add button onClick event handlers

	prev.onclick = function(){gotoCarrossel2Prev(id)};
	next.onclick = function(){gotoCarrossel2Next(id)};

	// Show buttons

	nav.className = "navButtons loaded";

}


// Add page indicators to carrossel

function addCarrossel2PageIndicators ( id ) {

	var
		car = carrossels[id],
		scrollNav = car.scrollNav,
		pages, list;


	// Calculate page number

	pages = ((car.items-car.pageItems) / car.slideItems)+1;
	if ( pages > parseInt(pages) )
		pages = parseInt(pages)+1;

	// Add a list with indicators

	list = document.createElement("UL");
	if ( pages > 1 ) {
		for ( var x = 1 ; x <= pages ; x++ ) {
			var li = document.createElement("LI");

			li.id = 'pi-'+id+'-'+x;
			li.innerHTML = "&nbsp;";
			if ( x == 1 )
				li.className = 'active';
				li.onclick = function ( ) {
					var
						idParts = this.id.split('-'),
						pos = (idParts[2]-1)*car.slideItems;

					gotoCarrossel2Pos(id,pos);
			};

			list.appendChild(li);
		}
	}

	scrollNav.appendChild(list);
	scrollNav.style.display = 'block';

}


// Update carrossel page indicators

function updateCarrossel2PageIndicators ( id ) {

	var
		car = carrossels[id],
		pages,
		curPage  = (car.pos / car.slideItems)+1;

	// Calculate page number  

	pages = ((car.items-car.pageItems) / car.slideItems)+1;
//	pages = car.items / car.pageItems;
	if ( pages > parseInt(pages) )
		pages = parseInt(pages) + 1;
	if ( curPage > parseInt(curPage) )
		curPage = parseInt(curPage) + 1;

	// Remove actives and just put current page as active

	if ( car.scrollNav != null ) {
		for ( var x = 1 ; x <= pages ; x++ )
			document.getElementById('pi-'+id+'-'+x).className = '';
		document.getElementById('pi-'+id+'-'+curPage).className = 'active';
	}


}


// Update carrossel arrows status (active/inactive)

function updateCarrossel2ArrowsStatus ( id ) {

	var
		car = carrossels[id],
		navButtons = car.navButtons,
		prev = ($(navButtons).select('[class="prev"]'))[0],
		next = ($(navButtons).select('[class="next"]'))[0];

	prev.id = car.pos ? "" : "prev-inactive";
	next.id = (car.pos < car.items-car.pageItems) ? "" : "next-inactive";

}




// Find carrossel navigation buttons 

function findCarrossel2NavButtons ( ul ) {

	var
		curNavButtons = ($(ul.parentNode.parentNode).select('[class="navButtons"]'))[0];

	return curNavButtons;

}


// Find carrossel place for page indicators

function findCarrossel2ScrollNav ( ul ) {

	var
		curScrollNav = ($(ul.parentNode.parentNode).select('[class="scroll-nav"]'))[0];

	return curScrollNav;

}


// Get carrossel list properties (number of items, item dimensions, .. )

function getCarrossel2ListProps ( ul ) {

	var
		itemEl = "li",
		p = new Carrossel2();


	// Initialize dimensions

	p.itemDims = { w: 0, h: 0 };

	// Set element

	p.element = ul;

	// Find a list item

	for ( var x = 0 ; x < ul.childNodes.length ; x++ ) {
		if ( ul.childNodes[x].nodeName.toLowerCase() == itemEl ) {
			var
				liDims = getCarrossel2ItemDim(ul.childNodes[x]);
			p.itemDims.w += liDims.w;
			p.itemDims.h += liDims.h;
			p.items++;
		}
	}

	// Get average item dimension

	p.itemDims.w = p.itemDims.w / p.items;
	p.itemDims.h = p.itemDims.h / p.items;

	return p;

}

// Get a carrossel item dimensions

function getCarrossel2ItemDim ( li ) {

	var
		d = { w: 0, h: 0 };

	d.w = li.offsetWidth;
	d.h = li.offsetHeight;

	return d;

}


// Clear document selection

function clearSelection() {

	var
		sel;

	if ( document.selection && document.selection.empty )
		document.selection.empty();
	else if ( window.getSelection && (sel = window.getSelection()) && sel.removeAllRanges )
		sel.removeAllRanges();

}

// Register init event to fire onLoad or 5 seconds after now

if ( document.all )
	attachEvent("onload", initCarrossel2);
else
	window.addEventListener("load", initCarrossel2, false);

