/*jslint browser:true, eqeqeq:true, undef:true, white:true, evil:true */
/*extern DF ActiveXObject DOMParser */
//global DF namespace
window.DF = window.DF || {};
var DF = window.DF;

// * Returns the namespace specified and creates it if it doesn't exist
// *
// * DF.namespace("property.package");
// * DF.namespace("DF.property.package");
// *
// * Either of the above would create DF.property, then
// * DF.property.package
// *
// * Note: No reserved words as the property or package names!
// *
// * @param  {String} ns The name of the namespace
// * @return {Object} A reference to the namespace object
DF.namespace = function(ns) {
    if (!ns || !ns.length) {
        return null;
    }

    var levels = ns.split(".");
    var nsobj = DF;

    // ignore 'DF' on front, since it's already specified
    for (var i=(levels[0] == "DF") ? 1 : 0; i<levels.length; ++i) {
        nsobj[levels[i]] = nsobj[levels[i]] || {};
        nsobj = nsobj[levels[i]];
    }

    return nsobj;
};

//* ******************************************************** 
//* general language extensions and helpers 
//* ******************************************************** 

// Creates a callback bound to the arguments specified
Function.prototype.createCallback = function(/*args...*/){
    // make args available, in function below
    var args = arguments;
    var method = this;
    return function() {
        return method.apply(window, args);
    };
};


// * Creates a delegate (callback) scoped to obj.  If args are specifed then they
// * override the delegate's callee specified arguments.  You probably want to use
// * the callee's arguments.
// * Call directly on any function. Example: <code>this.myFunction.createDelegate(this)</code>
// * @param {Object} obj The object for which the scope is set
// * @param {<i>Array</i>} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
// * @return {Function} The new function
Function.prototype.createDelegate = function(obj, args){
    var method = this;
    return function() {
        return method.apply(obj, args || arguments);
    };
};

// * Chain function calls of original function then the passed in function.
// * The resulting function returns the results of the original function.
// * The passed func is called with the parameters of the original function.
// * If you want to specify seperate args for your func, pass a delegate as func.
// *
// * @param {Function} func The function to sequence
// * @param {<i>Object</i>} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
// * @return {Function} The new function
Function.prototype.createChain = function(func, scope){
    if(typeof func != 'function'){
        return this;
    }
    var method = this;
    return function() {
        var retval = method.apply(this || window, arguments);
        func.apply(scope || this || window, arguments);
        return retval;
    };
};

Array.prototype.size = function() 
{
  var i = 0;
  for (var j in this) 
  {
    if (typeof(this[j]) != 'undefined') 
    {
      i++;
    }
  }
  return i;
};

Array.prototype.contains = function(val) 
{
  var i = 0;
  for (var j in this) 
  {
    if (this[j] == val) 
    {
      return true;
    }
  }
  return false;
};

Array.prototype.binarySearchContains = function(val, startIdx, endIdx) 
{
	var i = 0;
	var s = startIdx > -1 ? startIdx : 0;
	var e = endIdx > -2 ? endIdx : this.length;
	e = e < s ? s : e;
	var midP = Math.floor(((e - s) / 2) + s);
	//if(this[midP] == val || this[s] == val || this[e] == val){return true;}
	if(this[midP] == val){return true;}
	else if(s == e){return false;}
	else if(this[midP] < val){return this.binarySearchContains(val, midP+1, e);}
	else{return this.binarySearchContains(val, s, midP-1);}
};

Array.prototype.pushNotEmpty = function (val)
{
	if (!val) {
		return this.length;
	}
	if (val.length === 0) {
		return this.length;
	}
	if (typeof(val.length) === 'number' && typeof(val[0]) !== 'undefined')
	{
		for (var i = 0; i < val.length; i++)
		{
			this.push(val[i]);
		}
		return this.length;
	}
	return this.push(val);
};

Array.prototype.smallest = function ()
{
	if (this.length === 0)
	{
		return null;
	}
	
	var soFar = this[0];
	for (var i = 1; i < this.length; i++)
	{
		if (this[i] < soFar)
		{
			soFar = this[i];
		}
	}

	return soFar;
};

Array.prototype.largest = function ()
{
	if (this.length === 0)
	{
		return null;
	}

	var soFar = this[0];
	for (var i = 1; i < this.length; i++)
	{
		if (this[i] > soFar)
		{
			soFar = this[i];
		}
	}

	return soFar;
};

/******************************************
* String Helpers
******************************************/
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };

String.prototype.capitalizeFirst = function()
{
	return this.length > 1 ? this.substring(0,1).toUpperCase() + this.substring(1) : this;
};

String.prototype.regexEscape = function() { return this.replace(/([\[\\\^\$\.\|\?\*\+\(\)\{\}])/g, '\\$1'); };

String.prototype.startsWith = function(chk)  { return this.indexOf(chk) === 0; };

String.prototype.endsWith = function(chk) 
{
	var ind = this.lastIndexOf(chk);
	return ind+(chk.length) == this.length;
};

// *********** type checker functions ***********
function isBoolean(a) {
    return typeof a == 'boolean';
};

function isFunction(a) {
    return typeof a == 'function';
};

function isNull(a) {
    return a === null;
};

function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
};

function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
};

function isArray(a) {
    return isObject(a) && a.constructor == Array;
};

function isString(a) {
    return typeof a == 'string';
};

function isUndefined(a) {
    return typeof a == 'undefined';
};

function isNullOrEmpty(a) {
	return a === null || a === '';
};

function sortIntegeter(a,b)
{
	return a-b;
}

function getCookie(cName) 
{
	var start = cName + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') { c = c.substring(1,c.length); }
		if (c.indexOf(start) === 0) { return c.substring(start.length,c.length); }
	}
	return null;
}

/***********************************************
 * DF Helpers*************************
 **********************************************/
DF.convertPixelToInt = function(px)
{
    var cleanVal = px.replace('px','');
    return parseInt(cleanVal);   
};

DF.mouseX = function(e)
{
	 if (document.layers) 
     {
	    return document.body.scrollLeft + e.pageX;
     } 
     else if (document.all) 
     {
		return window.event.clientX + document.documentElement.scrollLeft;
     } 
     else if (document.getElementById) 
     {
	
        return document.body.scrollLeft + e.pageX;
     }
};

DF.mouseY = function(e)
{
	if (document.layers) 
    {
         return document.body.scrollTop + e.pageY;
    } 
    else if (document.all) 
    {
		return window.event.clientY + document.documentElement.scrollTop;
    } 
    else if (document.getElementById) 
    {
        return document.body.scrollTop + e.pageY;
    }
};

DF.mouseYRelative = function (e)
{
    if (document.layers) 
     {
         return e.layerY;
     } 
     else if (document.all) 
     {
        return window.event.offsetY;
     } 
     else if (document.getElementById) 
     {
        return e.layerY;
     }
};

DF.mouseXRelative = function (e)
{
    if (document.layers) 
     {
         return e.layerX;
     } 
     else if (document.all) 
     {
        return window.event.offsetX;
     } 
     else if (document.getElementById) 
     {
        return e.layerX;
     }
};

DF.parseDate24 = function(dateString)
{
	// takes in a string of the form 11/1/2006 18:00
	var temp = new Date();
	var parts = dateString.split(' ');
	var dateParts = parts[0].split("/");
	var timeParts = parts[1].split(":");
	var month = parseInt(dateParts[0],10) -1; // month is 0 based
	var day = parseInt(dateParts[1],10);
	var year = parseInt(dateParts[2],10);
	
	var hour = parseInt(timeParts[0],10);
	var min = parseInt(timeParts[1],10);
	temp.setFullYear(year,month,day);
	temp.setHours(hour,min,0,0);
	return temp;
};


DF.parseDate = function(dateString)
{
	// takes in a string of the form 11/1/2006 8:00 PM
	var temp = new Date();
	var parts = dateString.split(' ');
	var dateParts = parts[0].split("/");
	var timeParts = parts[1].split(":");
	var month = parseInt(dateParts[0],10) -1; // month is 0 based
	var day = parseInt(dateParts[1],10);
	var year = parseInt(dateParts[2],10);
	
	var hour = parseInt(timeParts[0],10);
	hour = (hour == 12)? (hour - 12) : hour;
	var min = parseInt(timeParts[1],10);
	if(dateString.indexOf("PM") > -1)
	{
		hour = hour < 12 ? hour += 12 : 12;
	}
	temp.setFullYear(year,month,day);
	temp.setHours(hour,min,0,0);
	return temp;
};

// returns YYYYMMDD int from the date passed in.  String output optional.
DF.getYYYYMMDD = function(date, stringOut) {
	var intOutput = true;
	if (stringOut === true) { intOutput = false; }
		
	var iYear = date.getFullYear();
	var iMonth = date.getMonth() +1;
	var iDay = date.getDate();
	
	var sMonth = (iMonth<10)?"0":"";
	sMonth += iMonth;
	var sDay = (iDay<10)?"0":"";
	sDay += iDay;
	
	var sTodayYMD = "" + iYear + sMonth + sDay;
	
	if (intOutput) { return parseInt(sTodayYMD); }
	else { return sTodayYMD; }
};

// Converts an ISO 8601 timestamp (or the defacto format) to a javascript Date object.
// If the "Z" or "[+-]HH:MM" is left off, the local time will be used.
// Accepts: YYYY-MM-DD hh:mm:ss OR the correct YYYY-MM-DDThh:mm:ssZ
DF.parseISODate = function (str) {
	var isoRegexp = /(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/;
    str = str + "";
    if (typeof(str) != "string" || str.length === 0) {
        return null;
    }
    var res = str.match(isoRegexp);
    if (typeof(res) == "undefined" || res === null) {
        return null;
    }
    var year, month, day, hour, min, sec, msec;
    year = parseInt(res[1], 10);
    if (typeof(res[2]) == "undefined" || res[2] === '') {
        return new Date(year);
    }
    month = parseInt(res[2], 10) - 1;
    day = parseInt(res[3], 10);
    if (typeof(res[4]) == "undefined" || res[4] === '') {
        return new Date(year, month, day);
    }
    hour = parseInt(res[4], 10);
    min = parseInt(res[5], 10);
    sec = (typeof(res[6]) != "undefined" && res[6] !== '') ? parseInt(res[6], 10) : 0;
    if (typeof(res[7]) != "undefined" && res[7] !== '') {
        msec = Math.round(1000.0 * parseFloat("0." + res[7]));
    } else {
        msec = 0;
    }
    if ((typeof(res[8]) == "undefined" || res[8] === '') && (typeof(res[9]) == "undefined" || res[9] === '')) {
        return new Date(year, month, day, hour, min, sec, msec);
    }
    var ofs;
    if (typeof(res[9]) != "undefined" && res[9] !== '') {
        ofs = parseInt(res[10], 10) * 3600000;
        if (typeof(res[11]) != "undefined" && res[11] !== '') {
            ofs += parseInt(res[11], 10) * 60000;
        }
        if (res[9] == "-") {
            ofs = -ofs;
        }
    } else {
        ofs = 0;
    }
    return new Date(Date.UTC(year, month, day, hour, min, sec, msec) - ofs);
};

DF.$ = function (id)
{
	if (id)
	{
		if (id.nodeType && id.tagName)
		{
			return id;
		}
		return document.getElementById(id);
	}
	return null;
};

DF.daysOfWeek = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
DF.monthAbrevLiterals = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
DF.monthLiterals = ["January","February","March","April","May","June","July","August","September","October","November","December"];
	    
DF.evalJson = function(jsonText) { return eval("(" + jsonText + ")"); };

DF.makeXmlDoc = function (xmlText)
{
	var xmlDoc;
	try
	{
		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async = "false";
		xmlDoc.loadXML(xmlText);
	} catch (e) {
		try
		{
			var parser = new DOMParser();
			xmlDoc = parser.parseFromString(xmlText, "text/xml");
		} catch (e2) {
			xmlDoc = null;
		}
	}
	return xmlDoc;
};

DF.convDateToDir = function(date) {
	return date.getFullYear() + ((date.getMonth()+1) < 10 ? "0" : "") + (date.getMonth() + 1) + (date.getDate() < 10 ? "0" : "") + date.getDate();
};

DF.elementScreenPosition = function(obj)
{
	var curtop = window.event ? 0 : 8;
	var curleft = curtop;
	if (obj.offsetParent) {
		curleft += obj.offsetLeft;
		curtop += obj.offsetTop;
		while (!!(obj = obj.offsetParent)) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}

	return {"offsetX": curleft, "offsetY" : curtop};
};

// Set opacity of an element from 0 to 100
DF.setOpacity = function(domElement, val)
{
	val = val < 0 ? 0 : val;
	val = val > 99 ? 100 : val;
	domElement.style.opacity = val / 100.0;
	domElement.style.filter = 'alpha(opacity=' + val + ')';
};

DF.addClass = function(domElement, className)
{
	var curr = domElement.className.split(" ");
	var found = false;
	for(var c=0; c<curr.length; c++) {
		if (curr[c] == className) {
			found = true;
		}
	}
	if (!found) {
		domElement.className = domElement.className + " " + className;
	}
};

DF.removeClass = function(domElement, className)
{
	var curr = domElement.className.split(" ");
	var clean = "";
	for(var c = 0; c < curr.length; c++) {
		if (curr[c] != className) {
			clean += (c === 0 ? "" : " ") + curr[c];
		}
	}
	domElement.className = clean;
};

DF.findElements = function (tagName, checkMethod, parentNode)
{
	if (typeof(parentNode) === 'undefined' || parentNode === null || parentNode === window)
	{
		parentNode = document.body;
	}

	var potential = [];
	if (!isArray(tagName))
	{
		potential.pushNotEmpty(parentNode.getElementsByTagName(tagName));
	}
	else
	{
		for (var n = 0; n < tagName.length; n++)
		{
			potential.pushNotEmpty(parentNode.getElementsByTagName(tagName[n]));
		}
	}
	var actual = [];
	
	for(var i = 0; i < potential.length; i++)
	{
		if (checkMethod === null || checkMethod(potential[i]))
		{
			actual.push(potential[i]);
		}
	}
	
	return actual;
};

DF.SetDisplayByName = function (name, display)
{
	var elements = document.getElementsByName(name);
	for (var i = 0; i < elements.length; i++)
	{
		elements[i].style.display = display;
	}
};

//******************** CONNECTION **********************
DF.namespace("DF.connection");

DF.connection = {
	_xmlReqType : ['MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'],
	asyncConnect : function(type, uri, delegateCB, disableCache, postData)
	{
		var conn = null;
		try 
		{
			conn = new XMLHttpRequest();
		}
		catch(e)
		{
			for(var i = 0; i < this._xmlReqType.length; i++)
			{
				try
				{
					conn = new ActiveXObject(this._xmlReqType[i]);
					if(conn)
					{
						break;
					}
				}
				catch(e2)
				{
					conn = null;
				}
			}
		}
		if(conn) 
		{
			if(disableCache)
			{
				if(uri.indexOf("?") > -1)
				{
					uri = uri + '&randDC=' + Math.random();
				}
				else
				{
					uri = uri + '?randDC=' + Math.random();
				}	
			}
			conn.onreadystatechange = this.connectionUpdateHandler.createDelegate(this,[conn,delegateCB]);
			conn.open(type, uri, true);
			
			if(postData)
			{
				conn.setRequestHeader("Content-length", postData.length);
				conn.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				conn.setRequestHeader("Connection", "close");
			}
			conn.send(postData?postData : null);
		}
	},
	connectionUpdateHandler : function(conn, cb)
	{
		try
		{
			if (conn.readyState == 4) 
			{
				if (conn.status == 200 && cb.delegate) 
				{
					cb.delegate({"status":conn.status,"ok":true,"responseText" : conn.responseText, "argument": cb.argument});
				} 
				else if(cb.delegate)
				{
					cb.delegate({"status":conn.status,"ok":false,"responseText" : null, "argument": cb.argument});
				}
			}
		}
		catch(e)
		{
			// something blew up in FF
			if(cb.delegate)
			{
				//cb.delegate({"status":"Status Unavailable","ok":false,"responseText" : null, "argument": cb.argument});
			}
		}
	},
	swapContentByName : function (type, uri, eleName)
	{
		var cb = function (response)
		{
			if (response.ok)
			{
				var elements = document.getElementsByName(eleName);
				for (var i = 0; i < elements.length; i++)
				{
					elements[i].innerHTML = response.responseText;
					var sTags = elements[i].getElementsByTagName('script');
					for(var j=0; j<sTags.length; j++)
					{
						var nTag = document.createElement('script');
						nTag.text = sTags[j].text;
						elements[i].appendChild(nTag);
						j++;
					}
				}
			}
		};
		
		DF.connection.asyncConnect(type, uri, {delegate: cb});
	}
};


//******************** EVENT **********************
DF.namespace("DF.evt");

DF.evt.DomLoadEvents = [];

(function ()
{
	var DOM_READY = false;

	DF.evt.AddDomLoadEvent = function (fn) 
	{
		if (DOM_READY)
		{
			setTimeout(fn.createDelegate(window, ['onDomReady']), 0);
		}
		else
		{
			DF.evt.DomLoadEvents.push(fn);
		}
	};
})();

DF.evt.AddDomLoadEventReaper = function()
{
	var fireEvts = function()
	{
		while (DF.evt.DomLoadEvents.length > 0)
		{
			var delegate = DF.evt.DomLoadEvents.pop();
			setTimeout(delegate.createDelegate(window, ['onDomReady']), 0);
		}
	};

	var readyState = function()
	{
		if (document.readyState === "interactive" || document.readyState === "complete") { fireEvts(); }
	};
	
	if(document.addEventListener) {
		document.addEventListener("DOMContentLoaded", fireEvts, false);
	}
	else
	{
		document.onreadystatechange = function() {
			readyState(fireEvts);
			return false;
		};
	}
}();

DF.evt.AddDomLoadEvent(function(){DOM_READY = true;});

DF.evt.AddLoadEvent = function(func) 
{
	var oldOnLoad = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			oldOnLoad();
			func();
		};
	}
};


DF.evt.AddUnloadEvent = function(fn) {
	var curr = window.onunload;
	if (typeof(window.onunload) != 'function') {
		window.onunload = fn;
	} 
	else {
		window.onunload = function() {
			curr();
			fn();
		};
	}
};

DF.evt.CancelEvent = function(e) {
	if (typeof(e.preventDefault) == 'function') {
		e.preventDefault();
	} else {
		e.preventDefault = true;
	}
	if (typeof(e.cancelBubble) == 'function') {
		e.cancelBubble();
	} else {
		e.cancelBubble = true;
	}
	if (typeof(e.cancelEvent) == 'function') {
		e.cancelEvent();
	} else {
		e.cancelEvent = true;
	}
	if (typeof(e.stopPropagation) == 'function') {
		e.stopPropagation();
	} else {
		e.stopPropagation = true;
	}
	return false;
};

DF.evt.CustomEvent = function(type) {
    this.type = type;
    this.scope = window;
    this.subscribers = [];
};

DF.evt.CustomEvent.prototype = {
    subscribe: function(fn) {
        this.subscribers.push( new DF.evt.Subscriber(fn) );
    },

    unsubscribe: function(fn) {
        var found = false;
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            var s = this.subscribers[i];
            if (s && s.contains(fn)) {
                this._delete(i);
                found = true;
            }
        }
        return found;
    },
    fire: function() {
        var len=this.subscribers.length;
        if (!len) {
            return;
        }

        var args = [];

        for (var i=0; i<arguments.length; ++i) {
            args.push(arguments[i]);
        }

        for (i=0; i<len; ++i) {
            var s = this.subscribers[i];
            if (s) {
                s.fn.call(window, this.type, args);
            }
        }
    },
    unsubscribeAll: function() {
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            this._delete(len - 1 - i);
        }
    },
    _delete: function(index) {
        var s = this.subscribers[index];
        if (s) {
            delete s.fn;
        }
        this.subscribers.splice(index, 1);
    }
};

//must call with a wrapped delegate
DF.evt.Subscriber = function(fn) {
    this.fn = fn;
    this.obj = null;
    this.override = false;
};

//must call with a wrapped delegate for scoping
DF.evt.Subscriber.prototype.contains = function(fn) {
    return (this.fn == fn);
};


// Load once
if (!DF.evt.Event) {
    DF.evt.Event = function() {
        var listeners = [];

        return {
            EL: 0,
            TYPE: 1,
            FN: 2,

            //el : id or element Obj
            //wrap up your own functions, no delayed attaching, no load/unload handling, DOM2 events only!
            addListener: function(el, sType, fn) {
                if (!fn || !fn.call) {
                    return false;
                }

                if (typeof el == "string") {
                    el = document.getElementById(el);
                }

                if (!el) {
                    return false;
                }

                var li = [el, sType, fn];
                var index = listeners.length;
                listeners[index] = li;

                //DOM2 events reg
                if (el.addEventListener) { //Non-IE

                    el.addEventListener(sType, fn, false);
                }
                else if (el.attachEvent) { // IE

                    el.attachEvent("on" + sType, fn);
                }

                return true;              
            },

            //optional index, overrides listener lookup by fn reference
            removeListener: function(el, sType, fn, index) {

                if (!fn || !fn.call) {
                    return false;
                }

                if (typeof el == "string") { //assumed element id if string
                    el = document.getElementById(el);
                } 

                var listener = null;
  
                if ("undefined" == typeof index) { //optional index arg
                    index = this._getListenerIndex(el, sType, fn);
                }
                if (index >= 0) {
                    listener = listeners[index];
                }
                if (!el || !listener) {
                    return false;
                }

				//DOM2 event unloading
                if (el.removeEventListener) {
                    el.removeEventListener(sType, listener[this.FN], false);
                }
                else if (el.detachEvent) { //IE
                    el.detachEvent("on" + sType, listener[this.FN]);
                }

                delete listeners[index][this.FN];
                listeners.splice(index, 1);

                return true;
            },
            
            _getListenerIndex: function(el, sType, fn) {
                for (var i=0,len=listeners.length; i<len; ++i) {
                    var li = listeners[i];
                    if ( li                 && 
                         li[this.FN] == fn  && 
                         li[this.EL] == el  && 
                         li[this.TYPE] == sType ) {
                        return i;
                    }
                }

                return -1;
            },

            _unload: function() {
                if (listeners && listeners.length > 0) {
                    var j = listeners.length;
                    while (j) {
                        var index = j-1;
                        var l = listeners[index];
                        if (l) {
                            this.removeListener(l[this.EL], l[this.TYPE], l[this.FN], index);
                        } 
                        j = j - 1;
                    }
                }
            }
        };
    }();
}


//******************** STYLES **********************
DF.namespace('DF.pguide.styles');

DF.pguide.styles.styleController = function()
{
	this.sSheet = null;
	this.styleRules = [];
	this.safari = (browserCheck.getBrowser().id == 'Safari');
	this.safariDeprecated = this.safari && (browserCheck.getVersion(browserCheck.getBrowser()) < 400);
};

DF.pguide.styles.styleController.prototype = 
{
	init : function()
	{
		// get the style block from the page for general rules
		this.getSheet();
		if(document.all)
		{
			for(var i = 0; i < this.sSheet.rules.length; i++)
			{
				var cssRule = this.sSheet.rules[i];
				if(cssRule.selectorText === null) {
					continue;
				}
				this.styleRules[cssRule.selectorText.toLowerCase()] = cssRule;
			}
		}
		else
		{
			for(var i = 0; i < this.sSheet.cssRules.length; i++)
			{
				var cssRule = this.sSheet.cssRules[i];
				if(cssRule.selectorText === null) {
					continue;
				}
				this.styleRules[cssRule.selectorText.toLowerCase()] = cssRule;
			}
		}
	},
	getSheet : function()
	{
		if(this.safari)
		{
			this.sSheet = document.styleSheets[0];
			return;
		}
		for(var i = 0; i < document.styleSheets.length; i++)
		{
			var sheet = document.styleSheets[i];
			if(this.isController(sheet.ownerNode))
			{
				this.sSheet = sheet;
				break;
			}
			else if(this.isController(sheet.owningElement))
			{
				this.sSheet = sheet;
				break;
			}
		}
		if(!this.sSheet)
		{
			this.sSheet = document.styleSheets[0];
		}
	},
	setStyle : function(styleName, val, idx) 
	{	
		if(!this.styleRules[styleName.toLowerCase()])
		{
			if(!this.createRule(styleName, val, idx))
			{
				return;
			}
		}
		var cssRule = this.styleRules[styleName.toLowerCase()];
		cssRule.style.cssText = val;
	},
	createRule : function(styleName, value, idx)
	{
//		debugger;
		if(document.all)
		{
			var idx = (idx !== null && idx >= 0 ? idx : this.sSheet.rules.length-1);
			this.sSheet.addRule(styleName,'{' + value + '}', idx);
			this.styleRules[styleName.toLowerCase()] = this.sSheet.rules[idx];
		}
		else
		{
			var index = this.sSheet.insertRule(styleName + '{' + value + '}', (idx !== null && idx >= 0 ? idx : this.sSheet.cssRules.length));
			this.styleRules[styleName.toLowerCase()] = this.sSheet.cssRules[index];
		}
		return this.safari;
	},
	flush : function()
	{
		this.sSheet = null;
		delete this.styleRules;
		this.styleRules = [];
	},
	isController : function (elem)
	{
		if (typeof(elem) === 'undefined' || elem === null)
		{
			return false;
		}
		return elem.getAttribute('name') == 'DFStyleController' || elem.id == 'DFStyleController';
	}
};

DF.namespace('DF.styles');

DF.styles.findSheet = function (fileName)
{
	var isEq = function (elem)
	{
		if (typeof(elem) === 'undefined' || elem === null)
		{
			return false;
		}
		var val = elem.getAttribute('href') + '';
		return val.endsWith(fileName);
	};
	
	for (var i = 0; i < document.styleSheets.length; i++)
	{
		var ss = document.styleSheets[i];
		if (isEq(ss.ownerNode))
		{
			return ss;
		}
		else if (isEq(ss.owningElement))
		{
			return ss;
		}
	}
	
	return null;
};

DF.namespace('DF.browserInformation');

DF.browserInformation = function()
{
	this.init();
};

DF.browserInformation.prototype = {
	init: function () 
	{
		this.browser = this.getBrowser();
		this.version = this.getVersion(this.browser);
		this.supported = (this.browser  && this.version) ? (this.browser.versMin <= this.version) : false;
	},
	getBrowser : function () 
	{
		for (var i=0;i<this.supportedBrowsers.length;i++)	
		{
			var dataString = this.supportedBrowsers[i].string;
			if (dataString) 
			{
				if (dataString.indexOf(this.supportedBrowsers[i].searchStr) != -1)
				{
					return this.supportedBrowsers[i];
				}
			}
		}
	},
	getVersion: function (browser) 
	{
		if(!browser)
		{
			return -1;
		}
		
		var version = navigator.userAgent;
			
		var index = version.indexOf(browser.versionStr || browser.id);
		if (index != -1)
		{
			var browserVersion = parseFloat(version.substring(index+(browser.versionStr || browser.id).length+1));
			if(browserVersion)
			{
				return browserVersion;
			}
			
		}
		
		version = navigator.appVersion;
		index = version.indexOf(browser.versionStr || browser.id);
		if (index != -1)
		{
			var browserVersion = parseFloat(version.substring(index+(browser.versionStr || browser.id).length+1));
			if(browserVersion)
			{
				return browserVersion;
			}
			
		}
		return -1;
	},
	supportedBrowsers: 
	[
		{
			string: navigator.vendor,
			searchStr: "Apple",
			id: "Safari",
			versMin : 1.3
		},
		{
			string: navigator.userAgent,
			searchStr: "Firefox",
			id: "Firefox",
			versMin : 1.1
		},
		{
			string: navigator.userAgent,
			searchStr: "MSIE",
			id: "Explorer",
			versionStr : "MSIE",
			versMin : 6
		}
	]	
};

DF.isIE6 = function()
{
	
	return window.navigator.appVersion.indexOf('MSIE 6') > -1;
	//typeof(document.body.style.maxHeight) === "undefined";
};

DF.Util = DF.Util || {};

DF.Util.getQueryParam = function(param)
{
	var srch = document.location.search.replace("?", "");
	srch = srch.split('&');
	
	for(var i=0; i< srch.length; i++)
	{
		if(srch[i].toLowerCase().split('=')[0] === param.toLowerCase())
		{
			return srch[i].toLowerCase().split('=')[1];
		}
	}
	return '';
};


//PREVIEW SITE FUNCTION NEEDED FOR Preview Markup DO NO REMOVE
function setTopDomain(overrideCheck)
{
	
	//if(document.domain !== 'localhost.com'){document.domain = 'localhost.com';}
	//alert(document.domain);
	var topLevel = document.domain.split('.');
	topLevel = topLevel.length > 1 ? (topLevel[topLevel.length-2].toLowerCase() + '.' + topLevel[topLevel.length-1].toLowerCase()) : document.domain;
	
	if(overrideCheck)
	{
		if(document.domain !== topLevel)
		{
			document.domain = topLevel;
		}
		else if(!document.all)
		{
			document.domain = document.domain; // hack fix
		}
	}
	else if(DF.Util.getQueryParam('setTopDomain').toLowerCase() === 'true')
	{
		if(document.domain !== topLevel)
		{
			document.domain = topLevel;
		}
		else if(!document.all)
		{
			document.domain = document.domain; // hack fix
		}
	}
	//alert(document.domain);
}

if(!DF.isIE6())
{
	setTopDomain();
}
else
{
	//DF.evt.AddDomLoadEvent(function(){setTopDomain(window["MARKUP_WINDOW"]);});
}

//DF.evt.AddLoadEvent(function(){alert('!');});

DF.evt.AddDomLoadEvent(function(){setTimeout(
	function(){
	try
	{
		if(DF.isIE6())
		{
			//alert(window["MARKUP_WINDOW"]);
			setTopDomain();
			//alert(document.domain);
			var test = window;
			setTimeout(function()
			{
				try
				{
					if(!window["MARKUP_WINDOW"] && window.parent && window.parent["MARKUP_WINDOW"])
					{
						test.parent.IE6Initialize(document.body.scrollWidth, document.body.scrollHeight);
					}
				}
				catch(e){}
			},200);
			
		}
	}
	catch(e){}
}, 0);});

DF.evt.AddLoadEvent(function(){setTimeout(
	function(){
	try
	{
		if(DF.isIE6())
		{
			//alert(window["MARKUP_WINDOW"]);
			setTopDomain();
			//alert(document.domain);
			var test = window;
			setTimeout(function()
			{
				try
				{
					if(!window["MARKUP_WINDOW"] && window.parent && window.parent["MARKUP_WINDOW"])
					{
						test.parent.IE6Initialize(document.body.scrollWidth, document.body.scrollHeight);
					}
				}
				catch(e){}
			},200);
			
		}
	}
	catch(e){}
}, 0);});

DF.forceSSL = function() {
	if(window.location.protocol == "http:") {
		window.location = "https://" + window.location.hostname + window.location.pathname + window.location.search;
	}
};

DF.forceNoSSL = function() {
	if(window.location.protocol == "https:"){
		window.location = "http://" + window.location.hostname + window.location.pathname + window.location.search;
	}
};

DF.clearSSL = function(url) {
	if(window.location.protocol == "https:") {
		window.location = "http://" + window.location.hostname + url;
	}
};

DF.namespace("DF.Modules");
DF.Modules.Highlights = (function ()
{
	var _map = {};
	var _visibleDiv = null;
	var _fadeDiv = null;
	var _shadowDiv = null;
	
	var ShadowDiv = function ()
	{
		var _cornerOverlap = 12;	// 6 each corner each side has 2 corners
		var _shadowDepth = { left : 34, top : 34, right : 34, bottom : 34 };
		
		var _isIE = (function ()
		{
			var b = new DF.browserInformation();
			return b.browser.id === "Explorer";
		})();
		
		var make = function (c, parent)
		{
			var d = document.createElement("div");
			d.className = c;
			
			if (parent)
			{
				parent.appendChild(d);
			}
			
			return d;
		};
		
		var shWrap = make("ShadowHolder");
		shWrap.style.display = "none";
		
		make("ShadowTL", shWrap);
		
		var shTop = make("ShadowTop", shWrap);
		
		make("ShadowTR", shWrap);
		
		var shLeft = make("ShadowLeft", shWrap);
		
		var shRight = make("ShadowRight", shWrap);
		
		make("ShadowBL", shWrap);
		
		var shBottom = make("ShadowBottom", shWrap);
		
		make("ShadowBR", shWrap);
		
		document.body.appendChild(shWrap);
		
		this.show = function (rectangleToShadow)
		{
			shWrap.style.width = rectangleToShadow.width + _shadowDepth.left + _shadowDepth.right;
			shWrap.style.height = rectangleToShadow.height + _shadowDepth.top + _shadowDepth.bottom;
			shWrap.style.top = rectangleToShadow.top - _shadowDepth.top;
			shWrap.style.left = rectangleToShadow.left - _shadowDepth.left;
			
			shTop.style.width = rectangleToShadow.width - _cornerOverlap;
			shBottom.style.width = rectangleToShadow.width - _cornerOverlap;
			
			var heightMod = 0;
			
			if (_isIE && (rectangleToShadow.height % 2 !== 0))
			{
				heightMod = 1;
			}
			
			shLeft.style.height = rectangleToShadow.height - _cornerOverlap - heightMod;
			shRight.style.height = rectangleToShadow.height - _cornerOverlap - heightMod;
			
			shWrap.style.display = "block";
		};
		
		this.hide = function ()
		{
			shWrap.style.display = "none";
		};
	};

	var close = function ()
	{
		_fadeDiv.style.display = "none";
		_shadowDiv.hide();
		_visibleDiv.style.display = "none";
		_visibleDiv = null;
		return false;
	};

	var registerClose = function (div)
	{
		var links = div.getElementsByTagName("a");
		for (var i = 0; i < links.length; i++)
		{
			var l = links[i];
			if (l.className === "CloseHighlight")
			{
				l.href="javascript:;";
				DF.evt.Event.addListener(l, 'click', close.createDelegate(this, [div]));
			}
		}
	};

	var findSize = function ()
	{
		var body = document.body;
		var masterContainer = body.firstChild;
		
		var heights = [masterContainer.offsetHeight, body.clientHeight];
		var widths = [masterContainer.offsetWidth, body.clientWidth];

		return {
			smallHeight : heights.smallest(),
			smallWidth : widths.smallest(),
			bigHeight : heights.largest(),
			bigWidth : widths.largest()
		};
	};

	var fadeSite = function (siteSize)
	{
		if (_fadeDiv === null)
		{
			_fadeDiv = document.createElement("div");
			_fadeDiv.className = "FadeSite";
			_fadeDiv.style.display = "none";
			document.body.appendChild(_fadeDiv);
		}

		_fadeDiv.style.width = siteSize.bigWidth;
		_fadeDiv.style.height = siteSize.bigHeight;
		_fadeDiv.style.display = "block";
	};
	
	var showShadow = function (rectangleToShadow)
	{
		if (_shadowDiv === null)
		{
			_shadowDiv = new ShadowDiv();
		}

		_shadowDiv.show(rectangleToShadow);
	};

	var centerAndShow = function ()
	{
		var divWidth = parseInt(_visibleDiv.style.width.replace("px", ''));
		var divHeight = parseInt(_visibleDiv.style.height.replace("px", ''));
		var siteSize = findSize();

		var cssLeft = parseInt((siteSize.smallWidth - divWidth) / 2);
		var cssTop = parseInt((siteSize.smallHeight - divHeight) / 2);

		fadeSite(siteSize);
		showShadow({top:cssTop,left:cssLeft,width:divWidth,height:divHeight});

		_visibleDiv.style.top = cssTop + "px";
		_visibleDiv.style.left = cssLeft + "px";
		_visibleDiv.style.display = "block";
	};

	return {
		show : function (modId)
		{
			var div = _map[modId];
			if (isUndefined(div) || div === null)
			{
				div = DF.$("Highlight" + modId);
				if (div === null)
				{
					return false;
				}
				registerClose(div);
				_map[modId] = div;
			}

			if (_visibleDiv !== null)
			{
				close();
			}

			_visibleDiv = div;
			centerAndShow();

			return false; // don't nav
		}
	};
})();
