///	<summary>This file serves as a library of classes for DHTML behavior.</summary>

/*
		Class EventHelper
		
			AddEvent (adds an event listener to an element)
			RemoveEvent (removes an event listener to prevent memory leaks)
			CancelDefault (cancels the default action of an element)
			CancelClickSafari (cancels the default action for Safari)
			
		Class DomHelper
		
			GetElementsByClassName (gets elements by one or more class names)
			NewWindowLinks (adds warning message for rel="pdf" and rel="external" links)
			NewWin (opens new window with chrome)
			PdfWin (opens new window without toolbar, for pdfs)
			Popup (pops up window with specified dimensions)
			SpawnHovers (assigns "on" class to arguments when other arguments are hovered)
			AscendDom (traces up the dom tree to find a specific element type ancestor)
			ActivateElement
			DeactivateElement
			
		Class SupportTest
			Various object and browser tests
*/



/*
		Class:		EventHelper
		Desc:			This class is for event handling helper functions
		Requires:	Does not require any other classes
		Author:		Eric Shepherd (specific functions by other authors as noted)
		Date:			May 2006
*/

if (typeof EventHelper == 'undefined') var EventHelper = new Object();

if (!EventHelper.aeOL) EventHelper.aeOL = [];

/*
		AddEvent Manager (c) 2005 Angus Turnbull http://www.twinhelix.com
		Free usage permitted as long as this credit notice remains intact.
*/
/*
		Use:			EventHelper.AddEvent(element, 'event', functionToRun, false);
							'event' is 'click', not 'onclick', 'mouseover', not 'onmouseover'.
		
		Example (no parameters to pass)
			EventHelper.AddEvent(window, 'load', init, false);
			
		Example (passing parameters)
			EventHelper.AddEvent(button, 'click', ptr = function(e) { animate(with, some, params); }, false);
*/

EventHelper.AddEvent = function(obj, type, fn, b) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}
EventHelper.RemoveEvent = function(o, n, f, l)
 {
  var d = 'removeEventListener', t, a, i, j, s;
  if (o[d] && !l) return o[d](n, f, false);
  if (!o.aE || !EventHelper.aeOL[o.aE]) return;
  t = EventHelper.aeOL[o.aE][n];
  i = t.length;
  while (i--)
  {
   a = t[i];
   j = a.length;
   s = 0;
   while (j--)
   {
    if (a[j] == f) s = 1;
    if (s) a[j] = a[j + 1];
   }
   if (s) { a.length--; break }
  }
 }
 

/*
		EventHelper.CancelDefault()
		
		Cancels a default event cross-browser
		For when return false isn't enough
*/

EventHelper.CancelDefault = function(e)
{
	if (window.event) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	}
	if (e && e.stopPropagation && e.preventDefault) {
		e.stopPropagation();
		e.preventDefault();
	}
}


/*
		EventHelper.CancelClickSafari()
		
		This is more verbose than just setting return false for Safari in 
		every function call, but in case we ever need to do anything 
		else for Safari, it can be put here.
*/

EventHelper.CancelClickSafari = function() 
{
	return false;
}



/*
		Class:		DomHelper
		Desc:			This class is for helper functions for DOM scripting. When directly 
							related to events, function should go in EventHelper. Other DOM 
							functions go here.
		Requires:	Requires EventHelper
		Author:		Various - see individual methods
		Date:			May 2006
*/

//var DomHelper = function() {
//}

if (typeof DomHelper == 'undefined') var DomHelper = new Object();

DomHelper._activeClass = 'active';
DomHelper._inactiveClass = 'inactive';
DomHelper._innerTag = 'span';

/*
getElementsByClassName

Copyright (c) 2006 Stuart Colville
http://muffinresearch.co.uk/archives/2006/04/29/getelementsbyclassname-deluxe-edition/

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial 
portions of the Software.
*/

/* 
		Use by passing in a classname, a tag (optional, defaults to *), 
		and a parent element (optional, defaults to document - must be 
		a reference, not a string). You can also use multiple class names - 
		'one two' looks for 'one' AND 'two', and 'one|two' looks for 'one' OR 'two'
*/
/* 
		Though this script gives you the power to search very generically, 
		this will slow down performance significantly. Please use 
		responsibly, and try to make your search as specific as possible using 
		the second and third parameters 
		
		UPDATES
		11.28.2006	EBS		Added "&& objContElm == document" clause to line 4 to fix problem that caused the script to bomb in IE.
*/

DomHelper.GetElementsByClassName = function(strClass, strTag, objContElm) {
  strTag = strTag || "*";
  objContElm = objContElm || document;
  //var objColl = (strTag == '*' && document.all && !window.opera && objContElm == document) ? document.all : objContElm.getElementsByTagName(strTag);
  var objColl = (objContElm.getElementsByTagName(strTag)) ? objContElm.getElementsByTagName(strTag) : document.all;
  var arr = new Array();
  var delim = strClass.indexOf('|') != -1  ? '|' : ' ';
  var arrClass = strClass.split(delim);
  for (i = 0, j = objColl.length; i < j; i++) {
    var arrObjClass = objColl[i].className.split(' ');
    if (delim == ' ' && arrClass.length > arrObjClass.length) continue;
    var c = 0;
    comparisonLoop:
    for (var k = 0, l = arrObjClass.length; k < l; k++) {
      for (var m = 0, n = arrClass.length; m < n; m++) {
        if (arrClass[m] == arrObjClass[k]) c++;
        if (( delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) {
          arr.push(objColl[i]);
          break comparisonLoop;
        }
      }
    }
  }
  return arr;
}

//if(!Array.push){
//	// To cover IE 5.0's lack of the push method
//	Array.prototype.push = function(value) {
//	  this[this.length] = value;
//	}
//}



/*
		DomHelper.AddClassName();
			Adds a class name to an element
		DomHelper.RemoveClassName();
			Removes a class name from an element
		
		"Copyright Robert Nyman, http://www.robertnyman.com
		Free to use if this text is included"
		
		Modified by Eric Shepherd (changed variable names, brought into DomHelper object)
*/



DomHelper.AddClassName = function (el, theClassName)
{
	var currentClass = el.className;
	if(!new RegExp(theClassName, "i").test(currentClass)){
		el.className = currentClass+ ((currentClass.length > 0)? " " : "") + theClassName;
	}
}

DomHelper.RemoveClassName = function (el, theClassName){
	var classToRemove = new RegExp((theClassName+ "\s?"), "i");
	el.className = el.className.replace(classToRemove, "").replace(/^\s?|\s?$/g, "");
}



/*
		DomHelper.AscendDom();
		
		Ascends the DOM looking for a particular element type
		Pass in the element the function is acting on and the 
		element you're looking for higher in the DOM tree and 
		that element will be returned
		
		Author: Stuart Langridge
*/

DomHelper.AscendDom = function(e, target) 
{
	while (e.nodeName.toLowerCase() != target && 
		e.nodeName.toLowerCase() != 'html') 
		e = e.parentNode;
	return (e.nodeName.toLowerCase() == 'html') ? null : e;
}



DomHelper.ActivateElement = function(el, storage) 
// takes a link and its contents, and replaces with the contents only, storing the link in a variable
{
	if (el.getElementsByTagName('a').length > 0) {
				// delete list item link from list and store in variable
		storage = el.removeChild(el.getElementsByTagName('a')[0]);
				// assign class to list item (now empty)
		DomHelper.AddClassName(el, this._activeClass);
				// return inner contents to list without link attached
		var newElement = document.createElement(this._innerTag);
		var oldElement = storage.innerHTML;
		newElement.innerHTML = oldElement;
		el.appendChild(newElement);
				// return link element to callee
		return storage;
	}
}



DomHelper.DeactivateElement = function(el, storage)
// takes the link and contents from a global class variable and re-inserts into the DOM
{
	if (el.getElementsByTagName(this._innerTag).length > 0) {
		var children = el.getElementsByTagName(this._innerTag);
		el.removeChild(children[0]);
		el.appendChild(storage);
		DomHelper.RemoveClassName(el, this._activeClass);
	}
}



/* 
		DomHelper.NewWindowLinks();
		
		Finds new window links (rel="pdf" or "external") and assigns
		an em tag to the link node, containing a warning message 
		that alerts the user to the new window. Also writes the event 
		listener to actually open these links in new windows.
		
		This might not belong in dhtml_lib, as it is very FP-specific, 
		with tracking scripts etc. hardcoded.
		
		Author: Eric Shepherd
*/

DomHelper.NewWindowLinks = function() {

	var allLinks = document.getElementsByTagName('a');
	
	var pdfAbbrText = 'PDF';
	var pdfOpenPar = ' (';
	var pdfAbbrTitle = 'Portable Document Format';
	
	var pdfString = (typeof overrideWinString != 'undefined') ? (', ' + overrideWinString + ')') : ', opens in new window)';
	
	var pdfAbbr; var pdfOpenParNode; var pdfWarning; var pdfWarningNode; var winNode; var winWarning;
	
	var winString = (typeof overrideWinString != 'undefined') ? (' (' + overrideWinString + ')') : ' (opens in new window)';

	for (i=0; i<allLinks.length; i++) {
		
// IF THE LINK IS A PDF
		// if pdf, open new window with warning message and no browser chrome
		if (allLinks[i].getAttribute('rel') && allLinks[i].getAttribute('rel').match(/pdf/)) {
			
			pdfAbbr = document.createElement('abbr');
			pdfAbbr.setAttribute('title', pdfAbbrTitle);
			
			pdfOpenParNode = document.createTextNode(pdfOpenPar);
			
			pdfAbbrNode = document.createTextNode(pdfAbbrText);
			pdfAbbr.appendChild(pdfAbbrNode);
			
			pdfWarning = document.createElement('em');
			pdfWarning.setAttribute('class', 'window-warning');
			pdfWarning.appendChild(pdfOpenParNode);
			pdfWarning.appendChild(pdfAbbr);
			
			pdfWarningNode = document.createTextNode(pdfString);
			pdfWarning.appendChild(pdfWarningNode);
			
			allLinks[i].appendChild(pdfWarning);
			
			EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) { DomHelper.NewWin(this, e, "noChrome") }, false);
		
// IF THE LINK IS EXTERNAL
		// if external, open new window with warning message and browser chrome
		} else if (allLinks[i].getAttribute('rel') && allLinks[i].getAttribute('rel').match(/external/)) {
			
			//winNode = document.createTextNode(winString);
			
			//winWarning = document.createElement('em');
			//winWarning.appendChild(winNode);
			
			//allLinks[i].appendChild(winWarning);
			
			EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) { DomHelper.NewWin(this, e, "chrome") }, false);
		
// IF THE LINK IS A BUY NOW LINK
		// if buy link, open new window with store, and call trackinterstitial to track the click
		} else if (allLinks[i].getAttribute('rel') && allLinks[i].getAttribute('rel').match(/buy/)) {
			
			EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) {
				callWtTrack(this, e);
				//eval(scriptCall);
				DomHelper.NewWin(this, e, "buy");
			}, false);
		
// IF THE LINK IS A POPUP
		} else if (allLinks[i].getAttribute('rel') && allLinks[i].getAttribute('rel').match(/popup/)) {
			
			// per client, don't warn user about the popup window
			//winNode = document.createTextNode(winString);
			
			//winWarning = document.createElement('em');
			//winWarning.appendChild(winNode);
			
			//allLinks[i].appendChild(winWarning);
			
			var screenW = screen.availWidth;
			var screenH = screen.availHeight;
			var rel = allLinks[i].getAttribute('rel');
			
			if (allLinks[i].getAttribute('rel').match(/\|/)) {
				// split at pipe only if there is a pipe in the rel attribute
				var relSplit = allLinks[i].getAttribute('rel').split('|');
				
				// set width and height, but max out at the screen size less 10
				var windowAttributes = '';
				if (relSplit[0] == 'popup') {
					if (relSplit[1] > screenW) {
						popupW = screenW - 10;
					} else {
						popupW = relSplit[1];
						if (SupportTest.isIE) popupW = parseInt(popupW) + 18;
					}
					if (relSplit[2] > screenH) {
						popupH = screenH - 40;
					} else {
						popupH = relSplit[2];
					}
				}
				// event listener if we have pipes specifying size in the rel attribute
				EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) { DomHelper.NewWin(this, e, 'popup', this.href, 'popup', popupW, popupH) }, false);
			} else {
				// default to generic size if rel attribute is simply "popup"
				EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) { DomHelper.NewWin(this, e, 'popup', this.href, 'popup', 600, 400) }, false);
			}
		} else if (allLinks[i].getAttribute('rel') && allLinks[i].getAttribute('rel').match(/overlay/)) {
			if (AjaxHelper) {
				EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) { DomHelper.NewWin(this, e, 'overlay', this.href) }, false);
			} else {
				EventHelper.AddEvent(allLinks[i], 'click', ptr = function(e) { DomHelper.NewWin(this, e, 'popup', this.href, 'popup', 600, 400) }, false);
			}
		}
	}
	winWarning = null;
	pdfWarning = null;
}


// called onload to add the handlers and warning messages for new window links
EventHelper.AddEvent(window, 'load', function () { DomHelper.NewWindowLinks() }, false);



/*
	DomHelper.NewWin
	Helper function to open a new window with or without some chrome, depending 
	on the parameters passed. Still allows people to open in a new tab or window 
	depending on their browser, and returns true at the end to open the link even if 
	the new window fails for some reason
	Author: Eric Shepherd, based on a script by Roger Johansson (456bereastreet.com)
*/

DomHelper.NewWin = function(theLink, e, winType, url, name, width, height)
// open new window with parameters for chrome and size
{
	if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return true;
	
	switch(winType) {
		
		case "noChrome" :
			var win = window.open(theLink.href, 'pdf', 'location=no,scrollbars,menubar,resizable,toolbar=no');
			break;
			
		case "chrome" :
			var win = window.open(theLink.href, 'new', 'location,scrollbars,menubar,resizable,toolbar');
			break;
			
		case "buy" : 
			var win = window.open(theLink.href, 'buy', 'location,scrollbars,menubar,resizable,toolbar,width=782,height=400');
			break;
			
		case "popup" :
			var win = window.open(url, name, 'scrollbars, resizable, toolbar=no, width=' + width + ', height=' + height);
			break;
		/*
		case "overlay" : 
					// create new div
			var theBody = document.getElementsByTagName('body')[0];
			var newDiv = document.createElement('div');
			newDiv.setAttribute('class', 'overlay-modal');
			theBody.appendChild(newDiv);
					// make the ajax call
					alert(this);
			AjaxHelper.load(newDiv, theLink, function() { alert('done'); });
			break;
		*/
		default :
			var win = window.open(theLink.href, 'new', 'location,scrollbars,menubar,resizable,toolbar');
			break;
	}
	if (win) {
		if (win.focus) {
			win.focus();
		}
		EventHelper.CancelDefault(e);		
	}
	return true;
}




/*
		DomHelper.SpawnHovers()
		
		This function takes any number of arguments, and assigns a class of 'on'
		to all of them when any one of them is moused over. It removes all these 
		classes on mouseout.
		
		Author: Eric Shepherd
*/

DomHelper.SpawnHovers = function() 
{
	for (var i = 0; i < arguments.length; i++) {
		var arg = arguments;
		
		EventHelper.AddEvent(arguments[i], 'mouseover', ptr1 = function(e) { 
			for (var j=0; j<arg.length; j++) {
				arg[j].className += ' on';
			}
		}, false);
		
		EventHelper.AddEvent(arguments[i], 'mouseout', ptr2 = function(e) { 
			for (var k=0; k<arg.length; k++) {
				arg[k].className = arg[k].className.replace(/\s*on/, '');
			}
		}, false);
		
	}
}




/*
		Class:		SupportTest
		Desc:			This class helps determine support, either browser or method.
							The idea is if possible to test for method support rather than browser-sniffing.
							Safari, for purposes of cancelling events, needs to be sniffed.
		Requires:	Does not require any other classes
		Use:			Boolean values.
								
		Author:		Eric Shepherd
		Date:			April 2006
*/

var SupportTest = function() {
}

SupportTest.hasDom = (document.getElementById && document.getElementsByTagName) ? true : false; 

SupportTest.isSafari = ((document.childNodes)&&(!document.all)&&(!navigator.taintEnabled)&&(!navigator.accentColorName)) ? true : false;

// This will need to be adjusted when newer Safari versions come out - currently all 2.0 releases are a 400-level number, but that will change.
SupportTest.oldSafariStyleParsing = ((document.childNodes)&&(!document.all)&&(!navigator.taintEnabled)&&(!navigator.accentColorName)&&!navigator.userAgent.match('Safari/4')) ? true : false; 

SupportTest.isIE = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1) ? true : false;

SupportTest.isIE7 = (navigator.userAgent.toLowerCase().indexOf("msie 7") != -1 ? true : false);

callWtTrack  = function(
	theLink,
	e	
	)
{
	var scriptVersion, rel, pid, scriptCall;
			rel = theLink.getAttribute('rel');
			if (document.wt != null && document.wt != undefined) scriptVersion = 1;
			if (typeof displayAll == "function") scriptVersion = 0;

			if (rel.match(/\|pid=/)) {
				var relParts = rel.split('|pid=');
				pid = relParts[1];
			} else {
				pid = 0;
			}
			switch (relParts[0]) {
				case "buy" : 
					trackName = "BuyNow";
					break;
				case "thumb-buy" :
					trackName = "ThumbBuyNow";
					break;
				default :
					trackName = "Unavailable";
			}
			switch (scriptVersion) {
				case 0 : 
					scriptCall = 'TrackInterstitial("fpaspx", "FPBuyNow", "' + pid + '", trackName);';
					break;
				case 1 : 
					scriptCall = 'document.wt.trackInterstitial("fpaspx", "FPBuyNow", "' + pid + '", trackName);';
					break;
				default : 
					scriptCall = '';
			}
			
			eval(scriptCall);
}


