// PUMP Nightclub Javascript Routines
// (c) 2011 PUMP nightclub Inc.
var PUMP = {
	remoteAddr: '',		// Users Remote IP Address, as seen by the webserver
	
	init: function() {
		this.initChat();
		// Get the users Remote IP Address (auto execute of javascript stores above
		new Ajax.Request('/asp/remoteinfo.asp', { method: 'get', parameters: {} });
	},
	
	toggleChat: function () {
		if ($('pumpchat')) {
			Effect.toggle('pumpchat', 'blind', { duration: 0.5});
		}
	},
	
	initChat: function () {
		if ($('pumpchat')) {
			$('chatToggle').observe('click', function() { PUMP.toggleChat(); });
		}
	},
	
	setCookieWithDomain: function(c_name,value,expiredays,path,domain) {
		var exdate=new Date();
		exdate.setDate(exdate.getDate()+expiredays);
		document.cookie=c_name+ '=' +escape(value)+((expiredays==null) ? '' : ';expires='+exdate.toUTCString())+((path==null) ? '' : ';path='+path)+((domain) ? ';domain='+domain : '');
    },

	setCookie: function(c_name,value,expiredays,path) {
        var exdate=new Date();
        exdate.setDate(exdate.getDate()+expiredays);
        document.cookie=c_name+ '=' +escape(value)+((expiredays==null) ? '' : ';expires='+exdate.toUTCString())+((path==null) ? '' : ';path='+path);
    },

    getCookie: function(c_name) {
        if (document.cookie.length>0) {
            c_start=document.cookie.indexOf(c_name + '=');
            if (c_start!=-1) {
                c_start=c_start + c_name.length+1;
                c_end=document.cookie.indexOf(';',c_start);
                if (c_end==-1) c_end=document.cookie.length;
                return unescape(document.cookie.substring(c_start,c_end));
            }
        }
        return '';
    }

};

Object.extend(Date.prototype, {
  strftime: function(format) {
    var day = this.getDay(), month = this.getMonth();
    var hours = this.getHours(), minutes = this.getMinutes();
    function pad(num) { return num.toPaddedString(2); };

    return format.gsub(/\%([aAbBcdDHiImMpSwyY])/, function(part) {
      switch(part[1]) {
        case 'a': return $w("Sun Mon Tue Wed Thu Fri Sat")[day]; break;
        case 'A': return $w("Sunday Monday Tuesday Wednesday Thursday Friday Saturday")[day]; break;
        case 'b': return $w("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")[month]; break;
        case 'B': return $w("January February March April May June July August September October November December")[month]; break;
        case 'c': return this.toString(); break;
        case 'd': return this.getDate(); break;
        case 'D': return pad(this.getDate()); break;
        case 'H': return pad(hours); break;
        case 'i': return (hours === 12 || hours === 0) ? 12 : (hours + 12) % 12; break;
        case 'I': return pad((hours === 12 || hours === 0) ? 12 : (hours + 12) % 12); break;
        case 'm': return pad(month + 1); break;
        case 'M': return pad(minutes); break;
        case 'p': return hours > 11 ? 'PM' : 'AM'; break;
        case 'S': return pad(this.getSeconds()); break;
        case 'w': return day; break;
        case 'y': return pad(this.getFullYear() % 100); break;
        case 'Y': return this.getFullYear().toString(); break;
      }
    }.bind(this));
  }
});

//-------------------------------------------------------------------------
// Error logging utility
//-------------------------------------------------------------------------
function log(msg) {
	setTimeout(function() {	throw new Error(msg); }, 0);
}
		
//-------------------------------------------------------------------------
// HTML Encoder/Decoder Object
//-------------------------------------------------------------------------

Encoder = {
	// When encoding do we convert characters into html or numerical entities
	EncodeType : "entity",  // entity OR numerical

	isEmpty : function(val) {
		if (val) {
			return ((val===null) || val.length==0 || /^\s+$/.test(val));
		} else {
			return true;
		}
	},

	// Convert HTML entities into numerical entities
	HTML2Numerical : function(s) {
		var arr1 = new Array('&nbsp;','&iexcl;','&cent;','&pound;','&curren;','&yen;','&brvbar;','&sect;','&uml;','&copy;','&ordf;','&laquo;','&not;','&shy;','&reg;','&macr;','&deg;','&plusmn;','&sup2;','&sup3;','&acute;','&micro;','&para;','&middot;','&cedil;','&sup1;','&ordm;','&raquo;','&frac14;','&frac12;','&frac34;','&iquest;','&agrave;','&aacute;','&acirc;','&atilde;','&Auml;','&aring;','&aelig;','&ccedil;','&egrave;','&eacute;','&ecirc;','&euml;','&igrave;','&iacute;','&icirc;','&iuml;','&eth;','&ntilde;','&ograve;','&oacute;','&ocirc;','&otilde;','&Ouml;','&times;','&oslash;','&ugrave;','&uacute;','&ucirc;','&Uuml;','&yacute;','&thorn;','&szlig;','&agrave;','&aacute;','&acirc;','&atilde;','&auml;','&aring;','&aelig;','&ccedil;','&egrave;','&eacute;','&ecirc;','&euml;','&igrave;','&iacute;','&icirc;','&iuml;','&eth;','&ntilde;','&ograve;','&oacute;','&ocirc;','&otilde;','&ouml;','&divide;','&Oslash;','&ugrave;','&uacute;','&ucirc;','&uuml;','&yacute;','&thorn;','&yuml;','&quot;','&amp;','&lt;','&gt;','&oelig;','&oelig;','&scaron;','&scaron;','&yuml;','&circ;','&tilde;','&ensp;','&emsp;','&thinsp;','&zwnj;','&zwj;','&lrm;','&rlm;','&ndash;','&mdash;','&lsquo;','&rsquo;','&sbquo;','&ldquo;','&rdquo;','&bdquo;','&dagger;','&dagger;','&permil;','&lsaquo;','&rsaquo;','&euro;','&fnof;','&alpha;','&beta;','&gamma;','&delta;','&epsilon;','&zeta;','&eta;','&theta;','&iota;','&kappa;','&lambda;','&mu;','&nu;','&xi;','&omicron;','&pi;','&rho;','&sigma;','&tau;','&upsilon;','&phi;','&chi;','&psi;','&omega;','&alpha;','&beta;','&gamma;','&delta;','&epsilon;','&zeta;','&eta;','&theta;','&iota;','&kappa;','&lambda;','&mu;','&nu;','&xi;','&omicron;','&pi;','&rho;','&sigmaf;','&sigma;','&tau;','&upsilon;','&phi;','&chi;','&psi;','&omega;','&thetasym;','&upsih;','&piv;','&bull;','&hellip;','&prime;','&prime;','&oline;','&frasl;','&weierp;','&image;','&real;','&trade;','&alefsym;','&larr;','&uarr;','&rarr;','&darr;','&harr;','&crarr;','&larr;','&uarr;','&rarr;','&darr;','&harr;','&forall;','&part;','&exist;','&empty;','&nabla;','&isin;','&notin;','&ni;','&prod;','&sum;','&minus;','&lowast;','&radic;','&prop;','&infin;','&ang;','&and;','&or;','&cap;','&cup;','&int;','&there4;','&sim;','&cong;','&asymp;','&ne;','&equiv;','&le;','&ge;','&sub;','&sup;','&nsub;','&sube;','&supe;','&oplus;','&otimes;','&perp;','&sdot;','&lceil;','&rceil;','&lfloor;','&rfloor;','&lang;','&rang;','&loz;','&spades;','&clubs;','&hearts;','&diams;');
		var arr2 = new Array('&#160;','&#161;','&#162;','&#163;','&#164;','&#165;','&#166;','&#167;','&#168;','&#169;','&#170;','&#171;','&#172;','&#173;','&#174;','&#175;','&#176;','&#177;','&#178;','&#179;','&#180;','&#181;','&#182;','&#183;','&#184;','&#185;','&#186;','&#187;','&#188;','&#189;','&#190;','&#191;','&#192;','&#193;','&#194;','&#195;','&#196;','&#197;','&#198;','&#199;','&#200;','&#201;','&#202;','&#203;','&#204;','&#205;','&#206;','&#207;','&#208;','&#209;','&#210;','&#211;','&#212;','&#213;','&#214;','&#215;','&#216;','&#217;','&#218;','&#219;','&#220;','&#221;','&#222;','&#223;','&#224;','&#225;','&#226;','&#227;','&#228;','&#229;','&#230;','&#231;','&#232;','&#233;','&#234;','&#235;','&#236;','&#237;','&#238;','&#239;','&#240;','&#241;','&#242;','&#243;','&#244;','&#245;','&#246;','&#247;','&#248;','&#249;','&#250;','&#251;','&#252;','&#253;','&#254;','&#255;','&#34;','&#38;','&#60;','&#62;','&#338;','&#339;','&#352;','&#353;','&#376;','&#710;','&#732;','&#8194;','&#8195;','&#8201;','&#8204;','&#8205;','&#8206;','&#8207;','&#8211;','&#8212;','&#8216;','&#8217;','&#8218;','&#8220;','&#8221;','&#8222;','&#8224;','&#8225;','&#8240;','&#8249;','&#8250;','&#8364;','&#402;','&#913;','&#914;','&#915;','&#916;','&#917;','&#918;','&#919;','&#920;','&#921;','&#922;','&#923;','&#924;','&#925;','&#926;','&#927;','&#928;','&#929;','&#931;','&#932;','&#933;','&#934;','&#935;','&#936;','&#937;','&#945;','&#946;','&#947;','&#948;','&#949;','&#950;','&#951;','&#952;','&#953;','&#954;','&#955;','&#956;','&#957;','&#958;','&#959;','&#960;','&#961;','&#962;','&#963;','&#964;','&#965;','&#966;','&#967;','&#968;','&#969;','&#977;','&#978;','&#982;','&#8226;','&#8230;','&#8242;','&#8243;','&#8254;','&#8260;','&#8472;','&#8465;','&#8476;','&#8482;','&#8501;','&#8592;','&#8593;','&#8594;','&#8595;','&#8596;','&#8629;','&#8656;','&#8657;','&#8658;','&#8659;','&#8660;','&#8704;','&#8706;','&#8707;','&#8709;','&#8711;','&#8712;','&#8713;','&#8715;','&#8719;','&#8721;','&#8722;','&#8727;','&#8730;','&#8733;','&#8734;','&#8736;','&#8743;','&#8744;','&#8745;','&#8746;','&#8747;','&#8756;','&#8764;','&#8773;','&#8776;','&#8800;','&#8801;','&#8804;','&#8805;','&#8834;','&#8835;','&#8836;','&#8838;','&#8839;','&#8853;','&#8855;','&#8869;','&#8901;','&#8968;','&#8969;','&#8970;','&#8971;','&#9001;','&#9002;','&#9674;','&#9824;','&#9827;','&#9829;','&#9830;');
		return this.swapArrayVals(s,arr1,arr2);
	},	

	// Convert Numerical entities into HTML entities
	NumericalToHTML : function(s) {
		var arr1 = new Array('&#160;','&#161;','&#162;','&#163;','&#164;','&#165;','&#166;','&#167;','&#168;','&#169;','&#170;','&#171;','&#172;','&#173;','&#174;','&#175;','&#176;','&#177;','&#178;','&#179;','&#180;','&#181;','&#182;','&#183;','&#184;','&#185;','&#186;','&#187;','&#188;','&#189;','&#190;','&#191;','&#192;','&#193;','&#194;','&#195;','&#196;','&#197;','&#198;','&#199;','&#200;','&#201;','&#202;','&#203;','&#204;','&#205;','&#206;','&#207;','&#208;','&#209;','&#210;','&#211;','&#212;','&#213;','&#214;','&#215;','&#216;','&#217;','&#218;','&#219;','&#220;','&#221;','&#222;','&#223;','&#224;','&#225;','&#226;','&#227;','&#228;','&#229;','&#230;','&#231;','&#232;','&#233;','&#234;','&#235;','&#236;','&#237;','&#238;','&#239;','&#240;','&#241;','&#242;','&#243;','&#244;','&#245;','&#246;','&#247;','&#248;','&#249;','&#250;','&#251;','&#252;','&#253;','&#254;','&#255;','&#34;','&#38;','&#60;','&#62;','&#338;','&#339;','&#352;','&#353;','&#376;','&#710;','&#732;','&#8194;','&#8195;','&#8201;','&#8204;','&#8205;','&#8206;','&#8207;','&#8211;','&#8212;','&#8216;','&#8217;','&#8218;','&#8220;','&#8221;','&#8222;','&#8224;','&#8225;','&#8240;','&#8249;','&#8250;','&#8364;','&#402;','&#913;','&#914;','&#915;','&#916;','&#917;','&#918;','&#919;','&#920;','&#921;','&#922;','&#923;','&#924;','&#925;','&#926;','&#927;','&#928;','&#929;','&#931;','&#932;','&#933;','&#934;','&#935;','&#936;','&#937;','&#945;','&#946;','&#947;','&#948;','&#949;','&#950;','&#951;','&#952;','&#953;','&#954;','&#955;','&#956;','&#957;','&#958;','&#959;','&#960;','&#961;','&#962;','&#963;','&#964;','&#965;','&#966;','&#967;','&#968;','&#969;','&#977;','&#978;','&#982;','&#8226;','&#8230;','&#8242;','&#8243;','&#8254;','&#8260;','&#8472;','&#8465;','&#8476;','&#8482;','&#8501;','&#8592;','&#8593;','&#8594;','&#8595;','&#8596;','&#8629;','&#8656;','&#8657;','&#8658;','&#8659;','&#8660;','&#8704;','&#8706;','&#8707;','&#8709;','&#8711;','&#8712;','&#8713;','&#8715;','&#8719;','&#8721;','&#8722;','&#8727;','&#8730;','&#8733;','&#8734;','&#8736;','&#8743;','&#8744;','&#8745;','&#8746;','&#8747;','&#8756;','&#8764;','&#8773;','&#8776;','&#8800;','&#8801;','&#8804;','&#8805;','&#8834;','&#8835;','&#8836;','&#8838;','&#8839;','&#8853;','&#8855;','&#8869;','&#8901;','&#8968;','&#8969;','&#8970;','&#8971;','&#9001;','&#9002;','&#9674;','&#9824;','&#9827;','&#9829;','&#9830;');
		var arr2 = new Array('&nbsp;','&iexcl;','&cent;','&pound;','&curren;','&yen;','&brvbar;','&sect;','&uml;','&copy;','&ordf;','&laquo;','&not;','&shy;','&reg;','&macr;','&deg;','&plusmn;','&sup2;','&sup3;','&acute;','&micro;','&para;','&middot;','&cedil;','&sup1;','&ordm;','&raquo;','&frac14;','&frac12;','&frac34;','&iquest;','&agrave;','&aacute;','&acirc;','&atilde;','&Auml;','&aring;','&aelig;','&ccedil;','&egrave;','&eacute;','&ecirc;','&euml;','&igrave;','&iacute;','&icirc;','&iuml;','&eth;','&ntilde;','&ograve;','&oacute;','&ocirc;','&otilde;','&Ouml;','&times;','&oslash;','&ugrave;','&uacute;','&ucirc;','&Uuml;','&yacute;','&thorn;','&szlig;','&agrave;','&aacute;','&acirc;','&atilde;','&auml;','&aring;','&aelig;','&ccedil;','&egrave;','&eacute;','&ecirc;','&euml;','&igrave;','&iacute;','&icirc;','&iuml;','&eth;','&ntilde;','&ograve;','&oacute;','&ocirc;','&otilde;','&ouml;','&divide;','&Oslash;','&ugrave;','&uacute;','&ucirc;','&uuml;','&yacute;','&thorn;','&yuml;','&quot;','&amp;','&lt;','&gt;','&oelig;','&oelig;','&scaron;','&scaron;','&yuml;','&circ;','&tilde;','&ensp;','&emsp;','&thinsp;','&zwnj;','&zwj;','&lrm;','&rlm;','&ndash;','&mdash;','&lsquo;','&rsquo;','&sbquo;','&ldquo;','&rdquo;','&bdquo;','&dagger;','&dagger;','&permil;','&lsaquo;','&rsaquo;','&euro;','&fnof;','&alpha;','&beta;','&gamma;','&delta;','&epsilon;','&zeta;','&eta;','&theta;','&iota;','&kappa;','&lambda;','&mu;','&nu;','&xi;','&omicron;','&pi;','&rho;','&sigma;','&tau;','&upsilon;','&phi;','&chi;','&psi;','&omega;','&alpha;','&beta;','&gamma;','&delta;','&epsilon;','&zeta;','&eta;','&theta;','&iota;','&kappa;','&lambda;','&mu;','&nu;','&xi;','&omicron;','&pi;','&rho;','&sigmaf;','&sigma;','&tau;','&upsilon;','&phi;','&chi;','&psi;','&omega;','&thetasym;','&upsih;','&piv;','&bull;','&hellip;','&prime;','&prime;','&oline;','&frasl;','&weierp;','&image;','&real;','&trade;','&alefsym;','&larr;','&uarr;','&rarr;','&darr;','&harr;','&crarr;','&larr;','&uarr;','&rarr;','&darr;','&harr;','&forall;','&part;','&exist;','&empty;','&nabla;','&isin;','&notin;','&ni;','&prod;','&sum;','&minus;','&lowast;','&radic;','&prop;','&infin;','&ang;','&and;','&or;','&cap;','&cup;','&int;','&there4;','&sim;','&cong;','&asymp;','&ne;','&equiv;','&le;','&ge;','&sub;','&sup;','&nsub;','&sube;','&supe;','&oplus;','&otimes;','&perp;','&sdot;','&lceil;','&rceil;','&lfloor;','&rfloor;','&lang;','&rang;','&loz;','&spades;','&clubs;','&hearts;','&diams;');
		return this.swapArrayVals(s,arr1,arr2);
	},

	// Numerically encodes all unicode characters
	numEncode : function(s){
		if(this.isEmpty(s)) return "";
		var e = "";
		for (var i = 0; i < s.length; i++) {
			var c = s.charAt(i);
			if (c < " " || c > "~") {
				c = "&#" + c.charCodeAt() + ";";
			}
			e += c;
		}
		return e;
	},
	
	// HTML Decode numerical and HTML entities back to original values
	htmlDecode : function(s){
		var c,m,d = s;
		if(this.isEmpty(d)) return "";
		// convert HTML entites back to numerical entites first
		d = this.HTML2Numerical(d);
		// look for numerical entities &#34;
		arr=d.match(/&#[0-9]{1,5};/g);
		// if no matches found in string then skip
		if(arr!=null){
			for(var x=0;x<arr.length;x++){
				m = arr[x];
				c = m.substring(2,m.length-1); //get numeric part which is refernce to unicode character
				// if its a valid number we can decode
				if(c >= -32768 && c <= 65535){
					// decode every single match within string
					d = d.replace(m, String.fromCharCode(c));
				}else{
					d = d.replace(m, ""); //invalid so replace with nada
				}
			}			
		}
		return d;
	},		

	// encode an input string into either numerical or HTML entities
	htmlEncode : function(s,dbl){
		if(this.isEmpty(s)) return "";
		// do we allow double encoding? E.g will &amp; be turned into &amp;amp;
		dbl = dbl | false; //default to prevent double encoding
		// if allowing double encoding we do ampersands first
		if(dbl){
			if(this.EncodeType=="numerical"){
				s = s.replace(/&/g, "&#38;");
			}else{
				s = s.replace(/&/g, "&amp;");
			}
		}
		// convert the xss chars to numerical entities ' " < >
		s = this.XSSEncode(s,false);
		if(this.EncodeType=="numerical" || !dbl){
			// Now call function that will convert any HTML entities to numerical codes
			s = this.HTML2Numerical(s);
		}
		// Now encode all chars above 127 e.g unicode
		s = this.numEncode(s);
		// now we know anything that needs to be encoded has been converted to numerical entities we
		// can encode any ampersands & that are not part of encoded entities
		// to handle the fact that I need to do a negative check and handle multiple ampersands &&&
		// I am going to use a placeholder
		// if we don't want double encoded entities we ignore the & in existing entities
		if(!dbl){
			s = s.replace(/&#/g,"##AMPHASH##");
			if(this.EncodeType=="numerical"){
				s = s.replace(/&/g, "&#38;");
			}else{
				s = s.replace(/&/g, "&amp;");
			}
			s = s.replace(/##AMPHASH##/g,"&#");
		}
		// replace any malformed entities
		s = s.replace(/&#\d*([^\d;]|$)/g, "$1");
		if(!dbl){
			// safety check to correct any double encoded &amp;
			s = this.correctEncoding(s);
		}
		// now do we need to convert our numerical encoded string into entities
		if(this.EncodeType=="entity"){
			s = this.NumericalToHTML(s);
		}
		return s;					
	},

	// Encodes the basic 4 characters used to malform HTML in XSS hacks
	XSSEncode : function(s,en){
		if(!this.isEmpty(s)){
			en = en || true;
			// do we convert to numerical or html entity?
			if(en){
				s = s.replace(/\'/g,"&#39;"); //no HTML equivalent as &apos is not cross browser supported
				s = s.replace(/\"/g,"&quot;");
				s = s.replace(/</g,"&lt;");
				s = s.replace(/>/g,"&gt;");
			}else{
				s = s.replace(/\'/g,"&#39;"); //no HTML equivalent as &apos is not cross browser supported
				s = s.replace(/\"/g,"&#34;");
				s = s.replace(/</g,"&#60;");
				s = s.replace(/>/g,"&#62;");
			}
			return s;
		}else{
			return "";
		}
	},

	// returns true if a string contains html or numerical encoded entities
	hasEncoded : function(s){
		if(/&#[0-9]{1,5};/g.test(s)){
			return true;
		}else if(/&[A-Z]{2,6};/gi.test(s)){
			return true;
		}else{
			return false;
		}
	},

	// will remove any unicode characters
	stripUnicode : function(s){
		return s.replace(/[^\x20-\x7E]/g,"");
	},

	// corrects any double encoded &amp; entities e.g &amp;amp;
	correctEncoding : function(s){
		return s.replace(/(&amp;)(amp;)+/,"$1");
	},

	// Function to loop through an array swaping each item with the value from another array e.g swap HTML entities with Numericals
	swapArrayVals : function(s,arr1,arr2){
		if(this.isEmpty(s)) return "";
		var re;
		if(arr1 && arr2){
			// array lengths must match
			if(arr1.length == arr2.length){
				for(var x=0,i=arr1.length;x<i;x++){
					re = new RegExp(arr1[x], 'g');
					s = s.replace(re,arr2[x]); //swap arr1 item with matching item from arr2	
				}
			}
		}
		return s;
	},

	inArray : function( item, arr ) {
		for ( var i = 0, x = arr.length; i < x; i++ ){
			if ( arr[i] === item ){
				return i;
			}
		}
		return -1;
	}
};

//-------------------------------------------------------------------------
// Browser Upgrade Notice
//-------------------------------------------------------------------------
var BrowserDetect = { 
	init: function () { 
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS"; 
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++) { 
			var dataString = data[i].string; 
			var dataProp = data[i].prop; 
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity; 
			} else if (dataProp) 
				return data[i].identity; 
		}
	}, 
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString); 
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1)); 
	},
	dataBrowser: [ 
		{ string: navigator.userAgent, subString: "Chrome", identity: "Chrome" },
		{ string: navigator.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb" },
		{ string: navigator.vendor, subString: "Apple", identity: "Safari", versionSearch: "Version" },
		{ prop: window.opera, identity: "Opera" },
		{ string: navigator.vendor, subString: "iCab", identity: "iCab" },
		{ string: navigator.vendor, subString: "KDE", identity: "Konqueror" },
		{ string: navigator.userAgent, subString: "Firefox", identity: "Firefox" },
		{ string: navigator.vendor, subString: "Camino", identity: "Camino" },
		{ string: navigator.userAgent, subString: "Netscape", identity: "Netscape" }, // for newer Netscapes (6+)
		{ string: navigator.userAgent, subString: "MSIE", identity: "Explorer", versionSearch: "MSIE" },
		{ string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv" },
		{ string: navigator.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla" } // for older Netscapes (4-)
	],
	dataOS : [ 
		{ string: navigator.platform, subString: "Win", identity: "Windows" }, 
		{ string: navigator.platform, subString: "Mac", identity: "Mac" },
		{ string: navigator.userAgent, subString: "iPhone", identity: "iPhone/iPod" },
		{ string: navigator.platform, subString: "Linux", identity: "Linux" }
	]
};
BrowserDetect.init();

function upgradeBrowser(e) {
	var el = $(e);
	if (!el) {
		return;
	}
	if ( // minimum versions required
	   (BrowserDetect.browser == 'Explorer' && parseFloat(BrowserDetect.version) < 7.0) ||
	   (BrowserDetect.browser == 'Chrome' && parseFloat(BrowserDetect.version) < 7.0) ||
	   (BrowserDetect.browser == 'Firefox' && parseFloat(BrowserDetect.version) < 3.0) ||
	   (BrowserDetect.browser == 'Safari' && parseFloat(BrowserDetect.version) < 5.0) ||
	   (BrowserDetect.browser == 'Opera' && parseFloat(BrowserDetect.version) < 9.5) 
	) {
		el.innerHTML = '';
		el.insert(Builder.node('h1', { style: "white-space: nowrap; margin: 5px;" }, 'We have detected that you are using an outdated web browser'));
		el.insert(Builder.node('h2', { style: "white-space: nowrap; margin: 5px;" }, 'Please consider upgrading or switching your browser to one that is more up-to-date'));
		el.insert(Builder.node('table', Builder.node('tbody', Builder.node('tr', [
				Builder.node('td', { className: 'nowrap' }, 
					Builder.node('a', { href:  'http://www.microsoft.com/windows/internet-explorer/', title: 'Download Internet Explorer' },
						[ Builder.node('img', { src: '/img/msie.gif', alt: 'MSIE' }), Builder.node('br'), 'Microsoft IE 8+' ] )
				),
				Builder.node('td', { className: 'nowrap' }, 
					Builder.node('a', { href:  'http://www.google.com/chrome/', title: 'Download Google Chrome' },
						[ Builder.node('img', { src: '/img/chrome.gif', alt: 'Chrome' }), Builder.node('br'), 'Google Chrome 8+'] )
				),
				Builder.node('td', { className: 'nowrap' }, 
					Builder.node('a', { href:  'http://www.mozilla.com/firefox/', title: 'Download Mozilla Firefox' },
						[ Builder.node('img', { src: '/img/firefox.gif', alt: 'Firefox' }), Builder.node('br'), 'Mozilla Firefox 3+'] )
				),
				Builder.node('td', { className: 'nowrap' }, 
					Builder.node('a', { href:  'http://www.opera.com/', title: 'Download Opera' },
						[ Builder.node('img', { src: '/img/opera.gif', alt: 'Opera' }), Builder.node('br'), 'Opera 9.5+' ] )
				),
				Builder.node('td', { className: 'nowrap' }, 
					Builder.node('a', { href:  'http://www.apple.com/safari/', title: 'Download Safari' },
						[ Builder.node('img', { src: '/img/safari.gif', alt: 'Safari' }), Builder.node('br'), 'Safari 5.0+' ])
				)
			]))));
		el.insert(Builder.node('span', 
			'You are currently using ' + BrowserDetect.browser + ' version ' + BrowserDetect.version + ' on ' + BrowserDetect.OS + ' '));
		el.insert(Builder.node('span', Builder.node('a', { href: '#', onclick: '$(messages).hide(); return false;'}, 
					Builder.node('i', '(Close this message)'))));
		el.show();
	}
}

//-------------------------------------------------------------------------
// Music News Feeds
//-------------------------------------------------------------------------

var NewsWidget = {
	interval: null,
	el:  null,
	items: [],
	initialContent: '',

	update: function() {
		// randomly sort news
		this.items = this.items.sortBy(Math.random);
		// clear the original contents
		this.initialContent = this.el.innerHTML;
		this.el.innerHTML = '';
		// add the items to the news widget
		for (var i = 0; i < this.items.length; ++i) {
			// Data Stored from the RSS Feed Items
			var item = {
				'id':	 i,
				'title': this.items[i].getElementsByTagName('title')[0].childNodes[0].nodeValue,
				'link':  this.items[i].getElementsByTagName('link')[0].childNodes[0].nodeValue,
				'desc':  Encoder.htmlDecode(this.items[i].getElementsByTagName('description')[0].childNodes[0].nodeValue),
				'date':  this.items[i].getElementsByTagName('pubDate')[0].childNodes[0].nodeValue,
				'icon':  null,
				'source': null
			};
			item.date = (item.date.indexOf(':') > 0) ? item.date.substring(0, item.date.indexOf(':') - 3) : item.date;
			if (/billboard\.com/.test(item.link)) {
				item.icon = '/img/icon-bb.gif';
				item.source = 'Billboard.com';
			} else if (/canoe\.ca/.test(item.link)) {
				item.icon = '/img/icon-jam.gif';
				item.source = 'Canoe JAM!';
			}
			this.el.insert(this.createEntry(item));
		}
		this.el.observe('mouseenter', function () { NewsWidget.stop(); });
		this.el.observe('mouseleave', function () { NewsWidget.restart(); });
		this.start();
	},

	createEntry: function (item) {
		var entry = Builder.node('div', { rel: 'NewsItem_' + item.id, className: 'musicnewsitem', style: 'margin: 0px 5px;' }, 
			Builder.node('div', { style: 'text-align: left; font-size: 12px; margin 0 5px; padding: 5px; border-bottom: 1px dotted #808080;' }, [
				Builder.node('h3', { 
							style: 'text-align: left; padding-left: 40px; min-height: 30px; background: transparent url(' + item.icon + ') 0 0 scroll no-repeat;'
						},
						Builder.node('a', { href: item.link, target: 'musicnews', title: 'Click to read more' }, item.title)
				),
				Builder.node('p', { 
						className: 'news-datestamp', 
						style: 'font-size: 10px; margin: 0; padding: 3px 0px; font-style: italic;' 
					}, item.date + ' (' + item.source +'):'
				),
				Builder.node('p', { 
						className: 'news-desc', 
						style: 'margin: 0; padding: 3px 0;'
					}, item.desc
				)
			])
		);
		return (entry);
	},
	
	scroll: function () {
		this.el.stopObserving('mouseleave');
		this.el.insert(this.el.firstDescendant().clone(1));
		new Effect.Parallel([
				new Effect.Fade(this.el.firstDescendant(), { sync: true }),
				new Effect.SlideUp(this.el.firstDescendant(), { sync: true })
			], { 
				duration: 1.0,
				afterFinish: function (eft) { 
					NewsWidget.el.firstDescendant().remove(); 
					NewsWidget.el.observe('mouseleave', function () { NewsWidget.restart(); });
				}
			}
		);
	},

	start: function() {
		this.interval = setInterval('NewsWidget.scroll()', 8000);
	},

	stop: function () {
		clearInterval(this.interval);
	},
	
	restart: function () {
		this.scroll(); 
		this.start(); 
	},

	init: function (e) {
		this.el = $(e);
		if (this.el) {
			new Ajax.Request('/asp/xmlproxy.asp', {
				method: 'get',
				parameters: { 'url': 'http://rss.canoe.ca/Jam/Music/home.xml', cachefor: 480 },
				onComplete: function (transport) { 
					if (transport.request.success()) {
					var items = $A(transport.responseXML.getElementsByTagName('item'));
						for (var i = 0; i < items.length; ++i) {
							NewsWidget.items[NewsWidget.items.length] = items[i];
						}
					}
					new Ajax.Request('/asp/xmlproxy.asp', {
						method: 'get',
						parameters: { 'url': 'http://www.billboard.com/rss/news', cachefor: 480 },
						onComplete: function (transport) {
							if (transport.request.success()) {
								var items = $A(transport.responseXML.getElementsByTagName('item'));
								for (var i = 0; i < items.length; ++i) {
									NewsWidget.items[NewsWidget.items.length] = items[i];
								}
							}
							NewsWidget.update();
						}
					});
				}
			});
		}
	}
}

//-------------------------------------------------------------------------
//  Bliboard Dance Charts
//-------------------------------------------------------------------------

var BillboardWidget = {
	chartEntries: new Array(),
	el: null,

	appendEntry: function (entry) {
		var elID = this.el.id + '_video_' +  entry.position;
		var div = Builder.node('div', {className: 'item', id: elID}, [
			Builder.node('div', { className: 'position' }, entry.position + ':'),
			Builder.node('div', { className: 'details' }, 
				Builder.node('a', {
					href:		entry.url,
					rel:		entry.rel,
					className:	entry.className,
					title:		entry.title }, [
						Builder.node('b', { className: 'song'}, entry.song), 
						Builder.node('br'), 
						Builder.node('i', { className: 'artist'}, entry.artist)
					]
				)
			)]
		);
		this.el.insert(div);
		if (entry.thumbnail) {
			var tip = Builder.node('img', {
					height:	entry.thumbnail.height, 
					width:	entry.thumbnail.width,
					src: 	entry.thumbnail.url, 
					alt: 'video thumbnail'
				}
			);
			new Tip(div, tip, { 
				width: 'auto', 
				style: 'darkgrey', 
				stem: 'rightMiddle', 
				hideOthers: true,
				hook: { 
					target: 'leftMiddle', 
					tip: 'rightMiddle'
				}
			});
		}
	},

// videoid	= responseJSON.feed.entry[0].media$group.yt$videoid.$t
// title	= responseJSON.feed.entry[0].title.$t
// videourl	= responseJSON.feed.entry[0].content.src
// thumburl	= responseJSON.feed.entry[0].media$group.media$thumbnail[0].url
// thumb_x	= responseJSON.feed.entry[0].media$group.media$thumbnail[0].width
// thumb_y	= responseJSON.feed.entry[0].media$group.media$thumbnail[0].heigth
// length	= responseJSON.feed.entry[0].media$group.yt$duration.seconds

	processChartEntries: function(transport) {
//		log(transport.responseText);
		var videos = transport.responseJSON;
		this.el.innerHTML = '';
//		log('Num Entries: ' + this.chartEntries.length);
		for ( var i = 0; i < this.chartEntries.length; ++i) {
			var feed = videos[i].feed;
			if (feed && feed['openSearch$totalResults']['$t'] > 0 && feed.entry) {
				var entry = feed.entry[0];
				var videoid = entry['media$group']['yt$videoid']['$t'];
//				log('Entry: ' + i + '  Video ID: ' + videoid);
				this.chartEntries[i].rel		= 'set[chartvideos][flash]';
				this.chartEntries[i].videoid	= videoid;
				this.chartEntries[i].index		= i;
				this.chartEntries[i].className	= 'lightview';
				this.chartEntries[i].url		= 'http://www.youtube.com/v/' + videoid + '&amp;autoplay=1&amp;rel=0&amp;iv_load_policy=3';
				this.chartEntries[i].thumbnail	= {
					url: entry['media$group']['media$thumbnail'][0].url,
					width: entry['media$group']['media$thumbnail'][0].width,
					height: entry['media$group']['media$thumbnail'][0].height
				};
				this.chartEntries[i].title = this.chartEntries[i].position + ': ' + this.chartEntries[i].song + ' :: Artist: ' + this.chartEntries[i].artist;
			}
			this.appendEntry(this.chartEntries[i]);
		}
	},
	
	processClubCharts: function (transport) {
		var items = transport.responseXML.getElementsByTagName('item');
		var q = [];
		for (var i = 0; i < items.length && i < 20; i++) {
			var chartEntry = items[i].getElementsByTagName('title')[0].childNodes[0].nodeValue;
			var position = chartEntry.split(": ", 1);
			var song     = chartEntry.substr(position.toString().length + 1).split(", ", 1);
			var artist   = chartEntry.substr(position.toString().length + song.toString().length + 3);
			var url      = 'javascript:void(0)';
			var title    = 'Video not found on YouTube';
			this.chartEntries[i] = { 'title': title, 'position': position, 'song': song, 'artist': artist, 'url': url, 'className': '', 'rel': '', thumbnail: null };
			var key = '"' + artist + '" "' + song + '"';
			q[i] = key.replace(/\s+/g, ' ');
		}
		new Ajax.Request('/asp/youtube-search-json.asp', {
			method: 'post',
			parameters: {
				'ip': PUMP.remoteAddr,
				'q': q  // array of songs to look for
			},
			onSuccess: function (transport) { BillboardWidget.processChartEntries(transport); }
		});
	},
	
	start: function (e) {
		this.el = $(e);
		if (this.el) {
			new Ajax.Request('/asp/xmlproxy.asp', {
				method: 'get',
				parameters: { url: 'http://www.billboard.com/rss/charts/dance-club-play-songs', cachefor: 720 },
				onSuccess: function (transport) { BillboardWidget.processClubCharts(transport); }
			});
		}
	}
};
//-------------------------------------------------------------------------
// Get Events from Facebook
//-------------------------------------------------------------------------

var FacebookEvents = {
	el: null,
	dateRE: /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)/,
	nlRE: /\n/g,
	quoRE: /"/g,
	
	convertDate: function (date_stamp) {
		// converts a facebook time to a date object
		var a = this.dateRE.exec(date_stamp);
		var date = new Date(+a[1], +a[2] - 1, +a[3], +a[4] - 0, +a[5], +a[6]);
		// get the date into format "Weekday, Month Day Year at Time"
		var hour	= date.getHours();
		var min		= date.getMinutes();
		var ampm	= 'am';
		if (hour > 11) {
			ampm = 'pm';
			hour = hour - 12;
		}
		var dateStr	= date.toLocaleDateString() + ' at ' + hour + ':' + (min < 10 ? '0' + min.toString() : min) + ampm;
		return dateStr;
	},

	getEvent: function(transport) {
		var event = transport.responseJSON;
		var img_options = {
			className: 'lightview', 
	//		rel: 'image', 
			title: event.name + ' :: :: width: 200, menubar: bottom, closeButton: small, topclose: true',
			href: 'http://graph.facebook.com/' + event.id + '/picture?type=large'
		};
		var div = Builder.node('div', { className: 'container rounded-corners' }, [
			Builder.node('h2', event.name),
			Builder.node('div', { className: 'rounded-corners-small', style: 'position: relative; width: auto; background-color: #303030; text-align: left; margin: 5px; padding: 5px;' }, [
				Builder.node('a', img_options,
					Builder.node('img', { 
						style: 'float:left; width:100px;', 
						src: 'http://graph.facebook.com/' + event.id + '/picture?type=normal'
					})
				),
				Builder.node('div', { style: 'margin-left: 110px;' }, [
					Builder.node('div', { style: 'font-style: italic; font-weight: bold; margin-bottom: 5px;' }, this.convertDate(event.start_time)),
					Builder.node('div', { id: 'event-' + event.id }, '' ).update('<p>' + event.description.split(/\n\n/g).join('</p><p>').replace(/\n/g,'<br/>') +'<p>') //,
				//	Builder.node('div', { style: 'clear:both;' } ,'')
				])
			])
		]);
		this.el.insert(div);
	},
	
	getEvents: function(transport) {
		var events = $A(transport.responseJSON.data);
		events.reverse(true);
		for (var i = 0; i < events.length; i++) {
			new Ajax.Request('/asp/fbevent.asp', {
				method: 'get',
				parameters: { 'eid': events[i].id },
				onSuccess: this.getEvent.bind(this)
			});
		}
	},

	start: function (e) {
		this.el = $(e);
		if (this.el) {
			new Ajax.Request('/asp/fbevents.asp', {
				method: 'get',
				onSuccess: this.getEvents.bind(this)
			});
		}
	}

};

var FacebookEventsWidget = {
	el: null,
//	dateRE: /(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)\+(\d\d\d\d)/,
//	dateRE: /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/,
	dateRE: /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)/,
	nlRE: /\n/g,
	quoRE: /"/g,
	
	convertDate: function (date_stamp) {

		// converts a facebook time to a date object
		var a = this.dateRE.exec(date_stamp);
//		var date = new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
		var date = new Date(+a[1], +a[2] - 1, +a[3], +a[4] - 0, +a[5], +a[6]);
//		var dateparts = this.dateRE.exec(date_stamp);
		// get the date into format "Weekday, Month Day Year at Time"
		var hour	= date.getHours();
		var min		= date.getMinutes();
		var ampm	= 'am';
		if (hour > 11) {
			ampm = 'pm';
			hour = hour - 12;
		}
		var dateStr	= date.toLocaleDateString() + ' at ' + hour + ':' + (min < 10 ? '0' + min.toString() : min) + ampm;
		return dateStr;
	},
	
	makeToolTip: function (eid) {
		var id = 'event_' + eid;
		new Tip(id, { 
			ajax: {
				url: '/asp/fbevent-html.asp?eid=' + eid,
				options: { }
			},
			width: 'auto', style: 'darkgrey', hideOthers: true, 
			hideAfter: 0.14, hideOn: false, borderColor: '#101010',
			stem: { position: 'rightBottom', width: 40, height: 16 },
			hook: { target: 'leftMiddle', tip: 'rightBottom'}
		});
	},

	getEvents: function(transport) {
		this.el.innerHTML = '';
		var events = $A(transport.responseJSON.data);
		events.reverse(true);
		for (var i = 0; i < events.length; i++) {
			var id = 'event_' + events[i].id;
			var div = Builder.node('div', { 'id': id,  style: 'text-align: left; border-bottom: dotted 1px #808080; marginj: 0 5px; padding: 5px;' }, [
				Builder.node('a', { 
					href: 'http://www.facebook.com/event.php?eid=' + events[i].id, 
					title: 'Click to see event on Facebook',
					target: '_blank' }, events[i].name),
				Builder.node('br'),
				Builder.node('span', { style: 'font-size: 11px; font-style: italic;' }, this.convertDate(events[i].start_time))
			]);
			this.el.insert(div);
			this.makeToolTip(events[i].id); // Get the event data to make tool tip
		}
	},
	
	start: function (e) {
		this.el = $(e);
		if (this.el) {
			new Ajax.Request('/asp/fbevents.asp', {
				method: 'get',
				onSuccess: function (transport) { FacebookEventsWidget.getEvents(transport); }
			});
		}
	}
};

var SlideFader = {
	el: null, slides: [], idx: 0, interval: null,
	
	trans: function () {
		//fade slide a out and slide b in
		var idx = this.idx;
		var next_idx = idx + 1;
		if (next_idx >= this.slides.length) {
			next_idx = 0;
		}
		new Effect.Parallel( [
				new Effect.BlindUp (SlideFader.slides[idx], { sync: true, duration: 1.0 } ),
				new Effect.Fade (SlideFader.slides[idx], { sync: true, delay: 0.5, duration: 1.5 } ),
				new Effect.Appear (SlideFader.slides[next_idx], { sync: true, dealy: 1.0 } )
			], { 
				duration: 1.0
			}
		);
		this.idx = next_idx;
	},

	pause: function() {
		if (this.interval) {
			clearInterval(this.interval);
		}
	},
	
	restart: function() {
		Fader.trans();
		Fader.start();
	},
	
	start: function(el) {
		this.el = $(el);
		if (this.el) {
			this.slides = this.el.childElements();
			var numSlides 
			// abolutely position the slides, and then hide the slides, except the 1st one
			this.slides[0].setStyle({display: 'block', position: 'absolute', top: 0, left: 0});
			for (var i = 1; i < this.slides.length; ++i) {
				this.slides[i].setStyle({display: 'none', position: 'absolute', top: 0, left: 0});
			}
			if (this.slides.length > 1) {
				this.interval = setInterval('SlideFader.trans()', 8500);
			}
		}
	}
};

//-------------------------------------------------------------------------
// Google Analytics
//-------------------------------------------------------------------------

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-17528091-1']);
_gaq.push(['_trackPageview']);
(function() {
	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
	var s = document.getElementsByTagName('script')[0];
	s.parentNode.insertBefore(ga, s);
})();

function gaRecordOutboundLink(evt) {
	try {
		var myTracker=_gat._getTrackerByName();
		_gaq.push(['myTracker._trackEvent', ' + "External Link" + ', ' + this.href + ']);
			setTimeout('document.location = "' + this.href + '"', 100);
//			setTimeout('window.open("' + this.href + '", "_newtab")', 100);
	} catch(err) { 
	}
//	evt.stop();
	return false;
}

function trackExternalLinks() {
	$$('a[rel~=external]').each(function(a) {
		a.onclick = gaRecordOutboundLink;
//		a.observe('click', gaRecordOutboundLink);
	});
}
//-------------------------------------------------------------------------
// Initialize The page
//-------------------------------------------------------------------------

document.observe('dom:loaded', function () { upgradeBrowser('messages'); } );
document.observe("dom:loaded", function () { PUMP.init(); });
document.observe("dom:loaded", function () { trackExternalLinks(); });
document.observe('dom:loaded', function () { SlideFader.start('slide_holder'); });
document.observe('dom:loaded', function () { NewsWidget.init('musicnews'); } );
document.observe('dom:loaded', function () { FacebookEventsWidget.start('facebookevents'); } );
document.observe('dom:loaded', function () { FacebookEvents.start('facebookevents-full'); } );
document.observe('dom:loaded', function () { BillboardWidget.start('chartwidget'); } );


