/*  *********************************
 *  
 *  RIJKSMUSEUM BESTANDSCATALOGUS
 *  Statische catalogus - mei 2008
 *  
 *  Fabrique Communicatie & Design
 *  
 *  Script voor object navigatie in bestandscatalogus
 *  V0.1 - 080503 - JVI
 *  V0.2 - 080531 - JVI
 *  
 *  ./_js/objectnavigator.js
 *  
 *
 */

/*  DISPATCH: GRACEFULLY ATTACH FUNCTIONS TO DOM ELEMENT EVENTS
 *
 */



function dispatch(targetElement, eventName, handlerName) {
	if (targetElement.addEventListener) {
		targetElement.addEventListener(eventName, function(e) {
			return targetElement[handlerName](e);
		}, false);
	} else if (targetElement.attachEvent) {
		targetElement.attachEvent("on" + eventName, function(e) {
			return targetElement[handlerName](e);
		});
	} else {
		var originalHandler = targetElement["on" + eventName];
		if (originalHandler) {
			targetElement["on" + eventName] = function(e) {
				originalHandler(e);
				return targetElement[handlerName](e);
			};
		} else {
			targetElement["on" + eventName] = targetElement[handlerName];
		}
	}
}

/*
 * JS ENHANCEMENTS INIT
 * 
 */
function jsEnhancementInit() {
	// Set a 'js-enabled' class on the body element.
	var bodyElem = document.getElementsByTagName("body")[0];
	if (!hasClassName(bodyElem, 'js-enabled')) {
		addClassName(bodyElem, 'js-enabled');
	}
}

/*
 * NAVIGATOR GLOBALS
 * 
 */
var objNavStep = 450; // Number of pixels to move list by.
var objNavMax = 6; // Maximum number of items on one line.

/*
 * NAVIGATOR INIT
 * 
 */
function navigatorInit() {
	// Get all object navigators and attach enhancements.
	var navCounter = 1; // Keep track of number of navigators
	while (catNavigator = document
			.getElementById('cat-navigator-' + navCounter)) {
		// Enhance navigator with arrows.
		enhanceNavigator(catNavigator, navCounter);
		navCounter++;
	}
}

/*
 * ENHANCE A SINGLE OBJECT NAVIGATOR
 * 
 */
function enhanceNavigator(objectNavigator, objectNavigatorNo) {
	// Check whether navigator has more than 6 items.
	var objNavigatorItems = objectNavigator.getElementsByTagName('li');
	var objNavigatorTotal = objNavigatorItems.length;
	if (objNavigatorTotal < 7)
		return;

	// Store number of objects and initial position as a property for quick
	// reference.
	objectNavigator.total = objNavigatorTotal;
	objectNavigator.position = 0;

	// Set enhanced view class on parent element of list.
	var objNavigatorParent = objNavigatorItems[0].parentNode.parentNode;
	addClassName(objNavigatorParent, 'with-arrows');
	// console.log('En we hebben een enhanced view!');

	// Build next and previous links and inject in DOM.
	var prevNavLink = document.createElement("a");
	prevNavLink.id = "cat-controls-prev-" + objectNavigatorNo;
	prevNavLink.className = "cat-controls-prev";
	prevNavLink.title = "Show previous work of art";
	prevNavLink.href = "javascript:void(null);";

	var prevNavText = document.createTextNode("previous");
	prevNavLink.appendChild(prevNavText);

	var nextNavLink = document.createElement("a");
	nextNavLink.id = "cat-controls-next-" + objectNavigatorNo;
	nextNavLink.className = "cat-controls-next";
	nextNavLink.title = "Show next work of art";
	nextNavLink.href = "javascript:void(null);";

	var nextNavText = document.createTextNode("next");
	nextNavLink.appendChild(nextNavText);

	// Attach events.
	prevNavLink.targetClickHandler = moveSliderLeft;
	dispatch(prevNavLink, "click", "targetClickHandler");
	nextNavLink.targetClickHandler = moveSliderRight;
	dispatch(nextNavLink, "click", "targetClickHandler");

	// Inject in page.
	objNavigatorParent.parentNode.appendChild(prevNavLink);
	objNavigatorParent.parentNode.appendChild(nextNavLink);

	// Show only 'next' arrow.
	addClassName(document.getElementById("cat-controls-prev-"
			+ objectNavigatorNo), 'hidden');
}

/*
 * HELPERS: MOVE SLIDER LEFT OR RIGHT
 * 
 */
function moveSliderLeft() {
	// Fetch parent objectNavigator.
	var objNavigatorId = this.id.replace("controls-prev", "navigator");
	var objNavigator = document.getElementById(objNavigatorId);

	// Check if we can move left at all.
	if (objNavigator.position == 0)
		return;

	// Set new target for slider.
	objNavigator.position++;

	// Disable left arrow if there's no image right of new position.
	if (objNavigator.position == 0) {
		addClassName(this, 'hidden');
	}

	// Enable right arrow if there are images left of new position.
	if (objNavigator.position > objNavMax - objNavigator.total) {
		var objNavNextId = this.id.replace("controls-prev", "controls-next");
		delClassName(document.getElementById(objNavNextId), 'hidden');
	}

	// Move slider.
	var objNavigatorList = objNavigator.getElementsByTagName("ul")[0];
	objNavigatorList.style.left = (objNavigator.position * objNavStep) + "px";
}

function moveSliderRight() {
	// Fetch parent objectNavigator.
	var objNavigatorId = this.id.replace("controls-next", "navigator");
	var objNavigator = document.getElementById(objNavigatorId);

	// Check if we can move right at all.
	if ((objNavigator.position * 6) == objNavMax - objNavigator.total)
		return;

	// Set new target for slider.
	objNavigator.position--;

	// Disable right arrow if there's no image right of new position.
	if ((objNavigator.position * 6) == objNavMax - objNavigator.total) {
		addClassName(this, 'hidden');
	}

	// Enable left arrow if there are images left of new position.
	if (objNavigator.position < 0) {
		var objNavPrevId = this.id.replace("controls-next", "controls-prev");
		delClassName(document.getElementById(objNavPrevId), 'hidden');
	}

	// Move slider.
	var objNavigatorList = objNavigator.getElementsByTagName("ul")[0];
	objNavigatorList.style.left = (objNavigator.position * objNavStep) + "px";
}

function moveSlider(objectNavigator) {
	// Compare current and target positions.

	// If less than 2 pixels, fix into position.

	// Otherwise, calculate new motion step.

	// And move slider to new position.

	// If current and target positions differ, recursively move again.

}

/*
 * CONTENT TAB SWITCHER
 * 
 */
function tabSwitcherInit() {
	// Get content tabs and blocks and attach enhancements.
	var catTabParent = document.getElementById("catalogus-tabs");
	if (!catTabParent)
		return;
 
	var catTabs = catTabParent.getElementsByTagName("li");
	for ( var i = 0; i < catTabs.length; i++) {
		// Disable content for all but first tab
		var catTabId = catTabs[i].id;
		var contentTab = document.getElementById(catTabId.replace("tab",
				"content"));
		if (i > 0 && !hasClassName(catTabs[i], "artist"))
			{
				contentTab.style.display = "none";
			}
		// Attach click event on link in tab.
		var catTabLink = catTabs[i].getElementsByTagName("a")[0];
		catTabLink.targetClickHandler = showTab;
		dispatch(catTabLink, "click", "targetClickHandler");
	}
}

/*
 * HELPERS: SHOW ONE TAB
 * 
 */
function showTab(e) {
	showTabFromId(this.parentNode.id);

	// If possible, blur the activated link.
	if (this.blur)
		this.blur();

	// Prevent default event from happening.
	e = (e) ? e : ((event) ? event : null);

	if (e && e.returnValue) {
		// Set non-standard property for IE.
		e.returnValue = false;
	} else if (e && e.preventDefault) {
		// Method for our Gecko friends.
		e.preventDefault();
	} else {
		// Classic return false for older browsers.
		return false;
	}
}

function showTabFromId(tabId) {
	// Get content tabs and blocks and attach enhancements.
	var catTabs = document.getElementById("catalogus-tabs")
			.getElementsByTagName("li");
	for ( var i = 0; i < catTabs.length; i++) {
		// Disable all tabs
		var catTabId = catTabs[i].id;
		var contentTab = document.getElementById(catTabId.replace("tab",
				"content"));
		if (!hasClassName(catTabs[i], "artist")) {
			catTabs[i].className = "";
			contentTab.style.display = "none";
		}
	}

	var showTab = document.getElementById(tabId);
	var showContentTab = document.getElementById(tabId
			.replace("tab", "content"));
	addClassName(showTab, "selected");
	showContentTab.style.display = "";

	return false;
}

/*
 * ENTRY TEXT FOLDIN / FOLDOUT SWITCHER
 * 
 */
function entryFoldInit() {
	// Get content tabs and blocks and attach enhancements.
	var entryShort = document.getElementById("entry-short");
	if (!entryShort)
		return;

	// Build folding link.
	var entryParent = entryShort.parentNode;
	if (hasClassName(entryParent, "artist")) {
		var artistLong = document.getElementById("contentDivmain")
				.getElementsByTagName("h2")[0].innerHTML
		var artistShort = artistLong.split("(");
		// var objectTitle = artistShort[0];
		var entryCloseText = "Collapse extended biography";
	} else {
		// var objectTitle =
		// document.getElementById("contentDivside").getElementsByTagName("p")[1].innerHTML;
		var entryCloseText = "Collapse extended entry";
	}

	var entrySibling = document.getElementById("entry-sibling");
	var entryFoldLink = document.createElement("a");
	entryFoldLink.id = "entry-foldlink";
	entryFoldLink.className = "foldin";
	entryFoldLink.href = "javascript:void(null);";
	entryFoldLink.foldoutText = "More on this object";
	entryFoldLink.foldinText = entryCloseText;
	entryFoldLink.targetClickHandler = toggleEntry;
	dispatch(entryFoldLink, "click", "targetClickHandler");

	var entryFoldPar = document.createElement("p");
	entryFoldPar.id = "morelink-object";
	entryFoldPar.className = "morelink";
	entryFoldPar.appendChild(entryFoldLink);

	entryParent.insertBefore(entryFoldPar, entrySibling);

	toggleEntryById("entry-foldlink");
}

function toggleEntryById(foldLinkId) {
	var entryFoldLink = document.getElementById(foldLinkId);
	var entryExtended = document.getElementById("entry-extended");
	var entryShort = document.getElementById("entry-short");
	if (!entryExtended || !entryFoldLink)
		return;
	if (entryExtended.style.display == "none") {
		entryExtended.style.display = "";
		if (entryShort)
			entryShort.style.display = "none";
		entryFoldLink.className = "foldin";
		entryFoldLink.innerHTML = entryFoldLink.foldinText;
	} else {
		entryExtended.style.display = "none";
		if (entryShort)
			entryShort.style.display = "";
		entryFoldLink.className = "foldout";
		entryFoldLink.innerHTML = entryFoldLink.foldoutText;
	}

	if (entryFoldLink.blur)
		entryFoldLink.blur();
}

function toggleEntry() {
	toggleEntryById(this.id);
}

/*
 * OBJECT IMAGE SET NAVIGATOR
 * 
 */
function imageNavInit() {
	
	var imageNavBox = document.getElementById("cat-object");
	if (!imageNavBox)
		return;

	// Set up image thumbnail navigation.
	var imageNav = document.createElement("ul");
	imageNav.className = "clearfix";
	imageNav.id = "image-navigator";

	// Fetch thumb of base object image
	var imageNavThumb = imageNavBox.getElementsByTagName("img")[0]
			.cloneNode(false);
	imageNavThumb.width = "56";
	imageNavThumb.height = "40";

	// Build first list item in navigator.
	var imageNavItem = document.createElement("li");
	imageNavItem.id = "imgnav-cat-object";
	imageNavItem.className = "selected";
	imageNavItem.targetClickHandler = imageNavShow;
	dispatch(imageNavItem, "click", "targetClickHandler");
	imageNavItem.targetMouseoverHandler = imageNavMouseover;
	dispatch(imageNavItem, "mouseover", "targetMouseoverHandler");
	imageNavItem.targetMouseoutHandler = imageNavMouseout;
	dispatch(imageNavItem, "mouseout", "targetMouseoutHandler");

	// Build feature text
	var featuretext = document.createElement('p');
	featuretext.appendChild(document
			.createTextNode('Check medium large image of this artwork'));

	imageNavItem.appendChild(featuretext);
	imageNavItem.appendChild(imageNavThumb);
	imageNavItem.style.zIndex = 1001;
	imageNav.appendChild(imageNavItem);

	imageNavItem = imageNavThumb = null;

	// console.log(imageNav.innerHTML);
	// Fetch details and append to navigator list.
	var imageNavCntr = 1;
	var itemZIndex = 1000;
	while (imageObject = document.getElementById("cat-detail-" + imageNavCntr)) {
		if (!imageObject)
			break;

		// Set position and visibility.
		imageObject.style.position = "absolute";
		imageObject.style.left = "0";
		imageObject.style.top = "0";
		imageObject.style.visibility = "hidden";

		// Fetch thumb of detail image
		imageNavThumb = imageObject.getElementsByTagName("img")[0]
				.cloneNode(false);
		imageNavThumb.width = "56";
		imageNavThumb.height = "40";

		// Build detail list item in navigator.
		imageNavItem = document.createElement("li");
		imageNavItem.id = "imgnav-cat-detail-" + imageNavCntr;
		imageNavItem.targetClickHandler = imageNavShow;
		dispatch(imageNavItem, "click", "targetClickHandler");
		imageNavItem.targetMouseoverHandler = imageNavMouseover;
		dispatch(imageNavItem, "mouseover", "targetMouseoverHandler");
		imageNavItem.targetMouseoutHandler = imageNavMouseout;
		dispatch(imageNavItem, "mouseout", "targetMouseoutHandler");

		// Build feature text
		var featuretext = document.createElement('p');
		featuretext.appendChild(document
				.createTextNode('Check medium large image of this artwork'));

		imageNavItem.appendChild(imageNavThumb);
		imageNavItem.appendChild(featuretext);
		imageNavItem.style.zIndex = itemZIndex--;
		imageNav.appendChild(imageNavItem);

		// Increase counter for the next iteration
		imageNavCntr++;
		imageNavItem = imageNavThumb = null;
	}

	if (imageNavCntr > 1) {
		// Only insert image navigator when we actually have detail images...
		// console.log(imageNav.innerHTML);
		imageNavBox.parentNode.appendChild(imageNav);
	}
}

function imageNavMouseover() {
	if (!hasClassName(this, "hover")) {
		addClassName(this, "hover");
	}
}

function imageNavMouseout() {
	delClassName(this, "hover");
}

function imageNavShow() {
	imageNavShowById(this.id)
}

function imageNavShowById(imageNavId) {
	var imageObjectId = imageNavId.substring(7);
	imageNavClear();

	if (imageNavId.indexOf("object") == -1) {
		// Switch on a detail
		document.getElementById(imageObjectId).style.visibility = "visible";
	}
	// Switch back to base view
	document.getElementById(imageNavId).className = "selected";

	if (imageObjectId == "cat-object") {
		document.getElementById("cat-detail-0").style.visibility = "visible";
	}
}

function imageNavClear() {
	var imageNavItems = document.getElementById("image-navigator")
			.getElementsByTagName("li");
	for (i = 0; i < imageNavItems.length; i++) {
		imageNavItems[i].className = "";
		if (i > 0) {
			var imageObjectId = imageNavItems[i].id.substring(7);
			document.getElementById(imageObjectId).style.visibility = "hidden";
		}
	}
	
	document.getElementById("cat-detail-0").style.visibility = "hidden";
}

/*
 * HELPERS
 * 
 */
function hasClassName(elem, thisClass) {
	return (elem.className.indexOf(thisClass) > -1);
}

function addClassName(elem, thisClass) {
	var elemClass = elem.className;
	if (elemClass.length > 0) {
		elemClass += " ";
	}
	elem.className = elemClass + thisClass;
	return elem;
}

function delClassName(elem, thisClass) {
	if (!hasClassName(elem, thisClass))
		return;

	var thisChunks = elem.className.split(thisClass);
	elem.className = thisChunks[0] + thisChunks[1].substring(1);
	return elem;
}

/*
 * ATTACH INIT ROUTINES TO WINDOW.ONLOAD
 * 
 */
window.targetEnhancementHandler = jsEnhancementInit;
dispatch(window, "load", "targetEnhancementHandler");

window.targetNavigatorHandler = navigatorInit;
dispatch(window, "load", "targetNavigatorHandler");

window.targetTabSwitcherHandler = tabSwitcherInit;
dispatch(window, "load", "targetTabSwitcherHandler");

window.targetEntryFoldHandler = entryFoldInit;
dispatch(window, "load", "targetEntryFoldHandler");

window.targetImageNavigatorHandler = imageNavInit;
dispatch(window, "load", "targetImageNavigatorHandler");


