/*  *********************************
 *  
 *  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";

}

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";
    }
  }
}


/*  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");

