/* Mood Board */
/* dims whole section upon hover. fades in the current image under the mouse */
/* MJF 23/10/2010 */

// Mouseenter and mouseleave cross-browser, without event bubbling
// http://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/
var xb ={
	evtHash: [],
	ieGetUniqueID: function(_elem){
		if (_elem===window){return 'theWindow';}
		else if (_elem===document){return 'theDocument';}
		else {return _elem.uniqueID;}
	},

	addEvent: function(_elem, _evtName, _fn, _useCapture){
		if (typeof _elem.addEventListener != 'undefined'){
			if (_evtName=='mouseenter')
				{_elem.addEventListener('mouseover', xb.mouseEnter(_fn), _useCapture);}
			else if (_evtName=='mouseleave')
				{_elem.addEventListener('mouseout', xb.mouseEnter(_fn), _useCapture);} 
			else
				{_elem.addEventListener(_evtName, _fn, _useCapture);}
		}else if (typeof _elem.attachEvent != 'undefined'){
			var key = '{FNKEY::obj_' + xb.ieGetUniqueID(_elem) + '::evt_' + _evtName + '::fn_' + _fn + '}';
			var f = xb.evtHash[key];
			if (typeof f != 'undefined'){return;}
			f = function(){_fn.call(_elem);};
			xb.evtHash[key] = f;
			_elem.attachEvent('on' + _evtName, f);
			// attach unload event to the window to clean up possibly IE memory leaks
			window.attachEvent('onunload', function(){
				_elem.detachEvent('on' + _evtName, f);
			});
			key = null;
			//f = null;   /* DON'T null this out, or we won't be able to detach it */
		}
		else
			{_elem['on' + _evtName] = _fn;}
	},	

	removeEvent: function(_elem, _evtName, _fn, _useCapture){
		if (typeof _elem.removeEventListener != 'undefined')
			{_elem.removeEventListener(_evtName, _fn, _useCapture);}
		else if (typeof _elem.detachEvent != 'undefined'){
			var key = '{FNKEY::obj_' + xb.ieGetUniqueID(_elem) + '::evt' + _evtName + '::fn_' + _fn + '}';
			var f = xb.evtHash[key];
			if (typeof f != 'undefined'){
				_elem.detachEvent('on' + _evtName, f);
				delete xb.evtHash[key];
			}
			key = null;
			//f = null;   /* DON'T null this out, or we won't be able to detach it */
		}
	},
	
	mouseEnter: function(_pFn){
		return function(_evt){
			var relTarget = _evt.relatedTarget;				
			if (this==relTarget || xb.isAChildOf(this, relTarget))
				{return;}
			_pFn.call(this, _evt);
		};
	},
	
	isAChildOf: function(_parent, _child){
		if (_parent==_child){return false;}
		while (_child && _child != _parent)
			{_child = _child.parentNode;}
		return _child==_parent;
	}
};


var s0dHTML,
    s0d,
    S=null,
    boardObj,
    lis=[],
    lisLen,
    firstRun=true,
    exiting=false;

function resetAll(){
  clearInterval(S);
  var i=lisLen;
  while (i--){
    lis[i].className="";
  }
  boardObj.className="";
  s0d.innerHTML=s0dHTML;
}

function fadeBoardOut(){
  // decreases opacity on each call via CSS
  switch (boardObj.className){
    case ""         :
    case "fade100"  : boardObj.className="fade85"; break;
    case "fade85"   : boardObj.className="fade70"; break;
    case "fade70"   : boardObj.className="fade55"; clearInterval(S);
  }
}

function enter(e){
  // run reset once to prevent IE back-button hissy fits
  if (firstRun){
    resetAll();
    firstRun=false;
  }else{
    clearInterval(S);
  }
  fadeBoardOut();
  S=setInterval(fadeBoardOut,50);
}

function fadeBoardIn(){
  // increases opacity on each call via CSS
  switch (boardObj.className){
    case "fade55" : boardObj.className="fade70"; break;
    case "fade70" : boardObj.className="fade85"; break;
    case "fade85" : resetAll();
  }
}

function leave(e){
  clearInterval(S);
  fadeBoardIn();
  S=setInterval(fadeBoardIn,50);
}

function splitAltText(s){
  // expects alt text string format "Description text: Price text"
  // returns inline HTML string.
  var colonPos=s.lastIndexOf(':');
  return s.slice(0,colonPos)+"<em>"+s.slice(colonPos+2)+"</em>";
}

// show single image on hover / focus
function showLi(){
  if (exiting){return}
  // replace description
  s0d.innerHTML=splitAltText(this.getElementsByTagName('img')[0].alt);
  // show via css
  this.parentNode.className="fade100";
}

function fadeLi(){
  // reset opacity class
  this.parentNode.className="";
  // reset original instruction
  s0d.innerHTML=s0dHTML;
}

function imageClicked(){
  exiting=true;
  resetAll();
  // reset original instruction
  //s0d.innerHTML=s0dHTML;
}

/* author: Simon Willisons - http://simonwillison.net/2004/May/26/addLoadEvent/ */
function addLoadEvent(f){var o=window.onload;if(typeof window.onload!='function'){window.onload=f;}else{window.onload=function(){if(o){o();}f();};}}

addLoadEvent(function(){
  // check description object exists
  s0d=document.getElementById('s0d');
  if (s0d){
    // store original description in a global
    s0dHTML=s0d.innerHTML;
    // set boarb object as a global
    boardObj = document.getElementById('board');
    // check board exists
    if (boardObj){
      // apply mouse enter leave to whole board (div container) has to be on div, not ul, for IEv6
      xb.addEvent(boardObj, 'mouseenter', enter, false);
      xb.addEvent(boardObj, 'mouseleave', leave, false);
      boardObj.className="";
      // set lis global (re-used for looping)
      lis=boardObj.getElementsByTagName('li');
      // check lis exists
      if (lis){
        // set list length as a global (used, and reused, for faster looping)
        lisLen=lis.length;
        // first li is the original description so skip
        for (var i=1;i<lisLen;i++){
          lis[i].className="";
          lis[i].getElementsByTagName('a')[0].onmouseover=showLi;
          lis[i].getElementsByTagName('a')[0].onfocus=showLi;
          lis[i].getElementsByTagName('a')[0].onmouseout=fadeLi;
          lis[i].getElementsByTagName('a')[0].onblur=fadeLi;
          lis[i].getElementsByTagName('a')[0].onclick=imageClicked;
        }
      }
    }
  }
});

