var CLIENT_VERSION = "2104";
var NS_PLUGIN = "MusicGremlin Plugin 2.1.0.4";
var dlmgr;
var bi = null; // Browser Info

if (navigator.plugins && navigator.plugins[NS_PLUGIN]){
    document.writeln("<embed id='nswmp_plugin' type='application/musicgremlin-wmp-plugin' width='1' height='1' hidden='true'/>");
    document.writeln("<embed id='nsdlmgr_plugin' type='application/musicgremlin-dlmgr-plugin' width='1' height='1' hidden='true'/>");
    document.writeln("<embed id='nsmsrm_plugin' type='application/musicgremlin-msrm-plugin' width='1' height='1' hidden='true'/>");
}
////////////////////////////////////////////
// setDivVisible(name, bVisible)
// Description : Helper function to set a div's visibility
// Param : 
//		name = id of the div
//		bVisible = bool visibility of the div
////////////////////////////////////////////
function setDivVisible(name, bVisible){
	var div = document.getElementById(name);
	if (div){
	    if (bVisible)
		    div.style.display = "";
	    else
		    div.style.display = "none";
    }
}
////////////////////////////////////////////
// jsError(functionName, msg, bForce)
// Description : function shows a message box.  also logs via ajax
// Param : 
//		functionName = name of the function
//		msg = the error message
//		bForce = the override to show the box no matter what
////////////////////////////////////////////
function jsError(functionName, msg, bForce){
	//g_ScriptAlerts is a global thats added by the base page
	//g_FriendlyError is a global that specifies what the error message will be
	
	ajaxLogIt(functionName, msg, true);
		
	if (g_ScriptAlerts || bForce){
		var s;
		if (!g_FriendlyError)
			s = "An error occurred in the following function : " + functionName + ".  The Error Description is " + msg;
		else
			s = "An error has occurred.  If this problem persists, please contact customer service.";
			
		alert(s);
	}
}
////////////////////////////////////////////
// reportMachineConfiguration()
// Description : 
// Param : 
//		functionName = name of the function
//		msg = the error message
//		bIsException = is this an exception
////////////////////////////////////////////
function reportMachineConfiguration(){
	var s;
	s = "";
	try{
		s += "useragent=" + navigator.userAgent;
	}
	catch(e){
		s += "useragent=ERROR";
	}
	try{
		s += "::cookies=" + navigator.cookieEnabled; 
	}
	catch(e){
		s += "::cookies=ERROR";
	}
	try{
		s += "::WMP=" + getWMPVersion(); 
	}
	catch(e){
		s += "::WMP=ERROR";
	}
	try{
		s += "::indiv=" + getIndivVersion(); 
	}
	catch(e){
		s += "::indiv=ERROR"; 
	}
	
	
	ajaxLogIt("MACHINEREPORT", s, false);
	
}
function getWMPVersion(){
	try{
		var o = loadWMP();
		return o.versionInfo;
		
	}
	catch(e){
		return "ERROR";
	}
}
function getIndivVersion(){
	try{
		var o = loadNetObj();
		return o.GetDRMSecurityVersion();
		
	}
	catch(e){
		return "ERROR";
	}
}
function getFullIEVersion(spnName){
	try{
		if (document.all && window.print){ // IE5 
			var spn = document.getElementById(spnName);
			var cID = "{89820200-ECBD-11CF-8B85-00AA005B4383}" 
			return spn.getComponentVersion(cID,"componentid"); 
		} 
		else{
			return "NOT IE";
		}
	}
	catch(e){
		return "ERROR";
	}
}

////////////////////////////////////////////
// ajaxLogIt(functionName, msg, bIsException)
// Description : 
// Param : 
//		functionName = name of the function
//		msg = the error message
//		bIsException = is this an exception
////////////////////////////////////////////
function ajaxLogIt(functionName, msg, bIsException){
	try{
		//g_AjaxLog is a global that say whether we call the back
		if (g_AjaxLog || bIsException)
			MusicGremlinPublic.BasePages.MusicGremlinPublicPageAjaxLogger.ajaxLogIt(functionName, msg, bIsException);
	}
	catch(e){}
}
////////////////////////////////////////////
// ajaxTest()
// Description : test out the ajax stuff
// Param : 
//		none
////////////////////////////////////////////
function ajaxTest(){
	try{
		var res = MusicGremlinPublic.BasePages.MusicGremlinPublicPageAjaxLogger.ajaxTest();
		if (res.error == null)
			return true;
		else
			return false;
	}
	catch(e){
		return false;
	}
}

////////////////////////////////////////////
// individualizePlayer()
// Description : loads the download manager class and calls the indiv
//		return true if its ok else false
// Param : 
//		none
////////////////////////////////////////////
function individualizePlayer(){
	var dlmgr = loadDownloadManager(); 
	try{
		dlmgr.Individualize(true);
		return true;
	}
	catch(e){
		return false;
	}
}
////////////////////////////////////////////
// checkDRM()
// Description : this function checks to see if the DRM component is working ok
// Param : 
//		none
////////////////////////////////////////////
function checkDRM(){
	var o = loadNetObj();
	try{
		var s;
		s = o.GetSystemInfo();
		return true;
	}
	catch(e){
		return false;
	}
}
////////////////////////////////////////////
// isXP()
// Description : function determine if we are on xp
// Param : 
//		none
////////////////////////////////////////////
function isXP(){
	try{
	//if(navigator.userAgent.indexOf("Windows NT 5.1")>-1)
		if(navigator.userAgent.indexOf("Windows NT 5.1")>-1 || navigator.userAgent.indexOf("Windows NT 5.2")>-1)
			return true;
		return false;
   }
   catch(e){
		return false;
   }
	
}
function isVista(){
    if(navigator.userAgent.indexOf("Windows NT 6.0")>-1)
        return true;
    else
        return false; 
}
////////////////////////////////////////////
// isIE()
// Description : function determine if we are on IE  (need ie 6)
// Param : 
//		none
////////////////////////////////////////////
function isIE(){
	try{
		if(navigator.userAgent.indexOf("MSIE 6") >-1 || navigator.userAgent.indexOf("MSIE 7") >-1)
			return true;
		return false;
   }
   catch(e){
		return false;
   }

}
function isMoz(){
    //var moz = false;
    if ( !document.layers ){
	    var nav =  (navigator.userAgent.indexOf( 'Navigator' ) != -1);
	    var konq = (navigator.userAgent.indexOf( 'Konqueror' ) != -1 );
	    var saf = ( navigator.userAgent.indexOf( 'Safari' ) != -1 );
	    var moz = ( navigator.userAgent.indexOf( 'Gecko' ) != -1 && !nav && !saf && !konq && (navigator.userAgent.indexOf('Firefox/1.5') >= 0 || navigator.userAgent.indexOf('Firefox/2') >= 0));
    }
    return moz;
}
////////////////////////////////////////////
// getDeviceErrorPage(deviceToken)
// Description : function determine if the device token is active.
//               returns blank "" if ok, else it returns html to 
//               display.
// Param : 
//		deviceToken
////////////////////////////////////////////
function getDeviceErrorPage(deviceToken, bIsFlyout){
    try{
        if (bIsFlyout == null)
            bIsFlyout = false;
        var res = MusicGremlinPublic.Common.AjaxDeviceProxy.getUnregisteredDeviceHelp(deviceToken, bIsFlyout);
		if (res.error != null){ 
			ajaxLogIt("common.js.isActiveDevice()", res.error.Message, true);
			return "Unable to retrieve device status";
		}
		else
		    return res.value;
    }
    catch(e){
		ajaxLogIt("DownloadManager.js.ackDownload()", e.message, true);
		return "Unable to retrieve device status";
    }
}
function isCurrentVersion(){
    try{
        if (getBrowserInfo().PluginType == 1){
            var obj = new ActiveXObject("mgproxy.Mediator." + CLIENT_VERSION);
            if (obj)
                return true;
            else
                return false;
        }
        else if (getBrowserInfo().PluginType == 2){
            var obj = getDownloadManager();
            return (obj.Version == CLIENT_VERSION);
        }
    }
    catch(e){
        return false;
    }
}
////////////////////////////////////////////
// loadDownloadManager()
// Description : dynamically loads the downloadmanager
// Param : 
//		versionInfo = version of the player
////////////////////////////////////////////
function loadDownloadManager(){
    if (!dlmgr) dlmgr = getDownloadManager();
    return dlmgr;
}
function getDownloadManager(){
	try{
		if (getBrowserInfo().PluginType == 1)
		{
	        var broker = document.getElementById("mgbroker");
	        if (!broker) broker = new ActiveXObject("mgproxy.Mediator." + CLIENT_VERSION);
	        if (broker)
	            return broker.GetDownloadManager();
	        else
	            return null;    
		}
		else if (getBrowserInfo().PluginType == 2){
            return document.getElementById("nsdlmgr_plugin");		        
		}
	}
	catch(e){
	    // Need to check for ERROR_CANCELLED and rethrow so client validtor doesnt display install screen
	    if (e.number == -2147023673)
	        throw e;
		else
		    return null;
	}
}

////////////////////////////////////////////
// loadWMP()
// Description : dynamically loads wmp
// Param : 
//		none
////////////////////////////////////////////
function loadWMP(){
	try{
		if (getBrowserInfo().PluginType == 1)
		    return new ActiveXObject("WMPlayer.OCX");
		else if (getBrowserInfo().PluginType == 2){
            return document.getElementById("nswmp_plugin");		
        }
	}
	catch(e){
		return null;
	}
}
////////////////////////////////////////////
// loadNetObj()
// Description : dynamically loads the net obj (drm) library
// Param : 
//		none
////////////////////////////////////////////
function loadRegistrationObject(){
	try{
		if (getBrowserInfo().PluginType == 1)
		    return new ActiveXObject("DRM.GetLicense");
		else if (getBrowserInfo().PluginType == 2){
		    return document.getElementById("nsmsrm_plugin");
		}
	}
	catch(e){
		return null;
	}
}

////////////////////////////////////////////
// loadNetObj()
// Description : dynamically loads the net obj (drm) library
// Param : 
//		none
////////////////////////////////////////////
function loadNetObj(){
    return loadRegistrationObject();
}
////////////////////////////////////////////
// parseWMP10(versionInfo)
// Description : parses the version number and returns a bool about wmp 10
// Param : 
//		versionInfo = version of the player
////////////////////////////////////////////
function parseWMP10(versionInfo){
	var a = versionInfo.split(".");
	if (new Number(a[0]) >= 10)
		return true;
	else
		return false;
}
////////////////////////////////////////////
// parseIndiv(versionInfo)
// Description : parses the security version and returns a bool about indived
// Param : 
//		securityVersion = security version of the player
////////////////////////////////////////////
function parseIndiv(securityVersion){
  	var sFoundSec;
  	var nRequiredSec = '2200', nFoundSec = 0.0;
  	sFoundSec = new String('0.0')
  
	var sRegEx
    sRegEx = /\./g;
    sFoundSec = String(securityVersion);
    sFoundSec = sFoundSec.replace(sRegEx, '');

  	if (Number(sFoundSec) < nRequiredSec)
		return false;
  	else{
  		if ((Number(sFoundSec) % 2) == 1)
			return true;
		else
			return false;
	}

}
////////////////////////////////////////////
// isWMP10()
// Description : full function to check the player version (player doesnt use this as it has an embedded player)
// Param : 
//		none
////////////////////////////////////////////
function isWMP10(){
	try{
		var o = loadWMP();
		return parseWMP10(o.versionInfo);
	}
	catch(e){
		return false;
	}
}
////////////////////////////////////////////
// isIndiv()
// Description : full function to check the player indiv (player doesnt use this as it has an embedded player)
// Param : 
//		none
////////////////////////////////////////////
function isIndiv(){
	try{
		var o = loadNetObj();
		return parseIndiv(o.GetDRMSecurityVersion());
		
	}
	catch(e){
		return false;
	}
}
////////////////////////////////////////////
// checkForClientControl(bDisplay)
// Description : check for the client control
// Param : 
//		bDisplay = shows an error
////////////////////////////////////////////
function checkForClientControl(bDisplay) {
	try {
		// we know it's IE, no issues w/ this line
		var obj = loadDownloadManager();
		if (obj != null) {
			// client obj exists on box, show inner text of span
			return true;
		}
		else
		{
		    return false;
		}
	} catch (e) {
		// Check if user clicked cancel on Vista elevation prompt
		if (e.number == -2147023673)
		    throw e;
		    
		if (bDisplay)
			if (getBrowserInfo.PluginType == 1)
			    alert ("The ActiveX control must be installed to continue");
			else (getBrowserInfo.PluginType == 2)
			    alert ("The browser plugin must be installed to continue");
		return false;
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

function writeSessionCookie (cookieName, cookieValue) {
  if (testSessionCookie()) {
    document.cookie = escape(cookieName) + "=" + escape(cookieValue) + "; path=/";
    return true;
  }
  else return false;
}
function getCookieValue (cookieName) {
  var exp = new RegExp (escape(cookieName) + "=([^;]+)");
  if (exp.test (document.cookie + ";")) {
    exp.exec (document.cookie + ";");
    return unescape(RegExp.$1);
  }
  else return false;
}
function testSessionCookie () {
  document.cookie ="testSessionCookie=Enabled";
  if (getCookieValue ("testSessionCookie")=="Enabled")
    return true 
  else
    return false;
}
function testPersistentCookie () {
  writePersistentCookie ("testPersistentCookie", "Enabled", "minutes", 1);
  if (getCookieValue ("testPersistentCookie")=="Enabled")
    return true  
  else 
    return false;
}
function writePersistentCookie (CookieName, CookieValue, periodType, offset, domain) {

  var expireDate = new Date ();
  offset = offset / 1;
  
  var myPeriodType = periodType;
  switch (myPeriodType.toLowerCase()) {
    case "years":
      expireDate.setYear(expireDate.getFullYear()+offset);
      break;
    case "months":
      expireDate.setMonth(expireDate.getMonth()+offset);
      break;
    case "days":
      expireDate.setDate(expireDate.getDate()+offset);
      break;
    case "hours":
      expireDate.setHours(expireDate.getHours()+offset);
      break;
    case "minutes":
      expireDate.setMinutes(expireDate.getMinutes()+offset);
      break;
    default:
      alert ("Invalid periodType parameter for writePersistentCookie()");
      break;
  } 
  document.cookie = escape(CookieName ) + "=" + escape(CookieValue) + "; expires=" + expireDate.toGMTString() + "; path=/" + ((domain) ? "; domain=" + domain : "");
}  
function deleteCookie (cookieName) {
  if (getCookieValue (cookieName)) writePersistentCookie (cookieName,"Pending delete","years", -1);  
  return true;     
}
function isDate(p_Expression){
	return !isNaN(new Date(p_Expression));		// <<--- this needs checking
}
function dateAdd(p_Interval, p_Number, p_Date){
	if(!isDate(p_Date)){return "invalid date: '" + p_Date + "'";}
	if(isNaN(p_Number)){return "invalid number: '" + p_Number + "'";}	

	p_Number = new Number(p_Number);
	var dt = new Date(p_Date);
	switch(p_Interval.toLowerCase()){
		case "yyyy": {// year
			dt.setFullYear(dt.getFullYear() + p_Number);
			break;
		}
		case "q": {		// quarter
			dt.setMonth(dt.getMonth() + (p_Number*3));
			break;
		}
		case "m": {		// month
			dt.setMonth(dt.getMonth() + p_Number);
			break;
		}
		case "y":		// day of year
		case "d":		// day
		case "w": {		// weekday
			dt.setDate(dt.getDate() + p_Number);
			break;
		}
		case "ww": {	// week of year
			dt.setDate(dt.getDate() + (p_Number*7));
			break;
		}
		case "h": {		// hour
			dt.setHours(dt.getHours() + p_Number);
			break;
		}
		case "n": {		// minute
			dt.setMinutes(dt.getMinutes() + p_Number);
			break;
		}
		case "s": {		// second
			dt.setSeconds(dt.getSeconds() + p_Number);
			break;
		}
		case "ms": {		// second
			dt.setMilliseconds(dt.getMilliseconds() + p_Number);
			break;
		}
		default: {
			return "invalid interval: '" + p_Interval + "'";
		}
	}
	return dt;
}
function getObjWidth(obj){
    return obj.childNodes[0].width;
}
function getObjHeight(obj){
    return obj.childNodes[0].height;
}

function dateDiff(p_Interval, p_Date1, p_Date2, p_firstdayofweek, p_firstweekofyear){
	if(!isDate(p_Date1)){return "invalid date: '" + p_Date1 + "'";}
	if(!isDate(p_Date2)){return "invalid date: '" + p_Date2 + "'";}
	var dt1 = new Date(p_Date1);
	var dt2 = new Date(p_Date2);

	// get ms between dates (UTC) and make into "difference" date
	var iDiffMS = dt2.valueOf() - dt1.valueOf();
	var dtDiff = new Date(iDiffMS);

	// calc various diffs
	var nYears  = dt2.getUTCFullYear() - dt1.getUTCFullYear();
	var nMonths = dt2.getUTCMonth() - dt1.getUTCMonth() + (nYears!=0 ? nYears*12 : 0);
	var nQuarters = parseInt(nMonths/3);	//<<-- different than VBScript, which watches rollover not completion
	
	var nMilliseconds = iDiffMS;
	var nSeconds = parseInt(iDiffMS/1000);
	var nMinutes = parseInt(nSeconds/60);
	var nHours = parseInt(nMinutes/60);
	var nDays  = parseInt(nHours/24);
	var nWeeks = parseInt(nDays/7);


	// return requested difference
	var iDiff = 0;		
	switch(p_Interval.toLowerCase()){
		case "yyyy": return nYears;
		case "q": return nQuarters;
		case "m": return nMonths;
		case "y": 		// day of year
		case "d": return nDays;
		case "w": return nDays;
		case "ww":return nWeeks;		// week of year	// <-- inaccurate, WW should count calendar weeks (# of sundays) between
		case "h": return nHours;
		case "n": return nMinutes;
		case "s": return nSeconds;
		case "ms":return nMilliseconds;	// millisecond	// <-- extension for JS, NOT available in VBScript
		default: return "invalid interval: '" + p_Interval + "'";
	}
}
function datePart(p_Interval, p_Date, p_firstdayofweek, p_firstweekofyear){
	if(!isDate(p_Date)){return "invalid date: '" + p_Date + "'";}

	var dtPart = new Date(p_Date);
	switch(p_Interval.toLowerCase()){
		case "yyyy": return dtPart.getFullYear();
		case "q": return parseInt(dtPart.getMonth()/3)+1;
		case "m": return dtPart.getMonth()+1;
		case "y": return dateDiff("y", "1/1/" + dtPart.getFullYear(), dtPart);			// day of year
		case "d": return dtPart.getDate();
		case "w": return dtPart.getDay();	// weekday
		case "ww":return dateDiff("ww", "1/1/" + dtPart.getFullYear(), dtPart);		// week of year
		case "h": return dtPart.getHours();
		case "n": return dtPart.getMinutes();
		case "s": return dtPart.getSeconds();
		case "ms":return dtPart.getMilliseconds();	// millisecond	// <-- extension for JS, NOT available in VBScript
		default: return "invalid interval: '" + p_Interval + "'";
	}
}
function weekdayName(p_Date, p_abbreviate){
	if(!isDate(p_Date)){return "invalid date: '" + p_Date + "'";}
	var dt = new Date(p_Date);
	var retVal = dt.toString().split(' ')[0];
	var retVal = Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')[dt.getDay()];
	if(p_abbreviate==true){retVal = retVal.substring(0, 3)}	// abbr to 1st 3 chars
	return retVal;
}
function monthName(p_Date, p_abbreviate){
	if(!isDate(p_Date)){return "invalid date: '" + p_Date + "'";}
	var dt = new Date(p_Date);	
	var retVal = Array('January','February','March','April','May','June','July','August','September','October','November','December')[dt.getMonth()];
	if(p_abbreviate==true){retVal = retVal.substring(0, 3)}	// abbr to 1st 3 chars
	return retVal;
}


function openwhatisgremlist() {
		window.open("/GetNewMusic/Gremlisthelp.aspx", "GremlistHelp", "width=600,height=500,left=50,top=50,toolbar=no,resizable=yes,menubar=no,scrollbars=yes");
	}

function popWindow(page,DaName,w,h,scroll)        
{        
	tempWindow = window.open(page,DaName,"scrollbars="+scroll+",resizable=no,width="+w+",height="+h+",status=no,location=no,toolbar=no,menubar=no");
	tempWindow.focus();      
}

// Opens the installer instructions window to load the client control activex control.
function showInstallerWindow()
{
    if (getBrowserInfo().PluginType == 1)
        return showActiveXInstallerWindow();
    else if (getBrowserInfo().PluginType == 2)
        return showNetscapePluginInstallerWindow();
}
function showActiveXInstallerWindow(){
    var winInstaller = window.open("/Common/ActivexInstall.aspx", "install");
    if (winInstaller){
        winInstaller.moveTo( 0, 0 );
        winInstaller.resizeTo( screen.availWidth, screen.availHeight );
        return true;
    }
    else
        return false;
}
function showNetscapePluginInstallerWindow(){
    var winInstaller = window.open("/Common/NetscapePluginInstall.aspx", "install");
    if (winInstaller){
        winInstaller.moveTo( 0, 0 );
        winInstaller.resizeTo( screen.availWidth, screen.availHeight );
        
        return true;
    }
    else
        return false;
}

function PageQuery(q) {
    if(q.length > 1)
         this.q = q.substring(1, q.length);
    else
        this.q = null;
    this.keyValuePairs = new Array();
    if(q) {
        for(var i=0; i < this.q.split("&").length; i++) {
            this.keyValuePairs[i] = this.q.split("&")[i];
        }
    }
    this.getKeyValuePairs = function() { return this.keyValuePairs; };
    this.getValue = function(s) {
        for(var j=0; j < this.keyValuePairs.length; j++) {
            if(this.keyValuePairs[j].split("=")[0] == s)
                return this.keyValuePairs[j].split("=")[1];
        }
        return false;
    };
    this.getParameters = function() {
        var a = new Array(this.getLength());
        for(var j=0; j < this.keyValuePairs.length; j++) {
            a[j] = this.keyValuePairs[j].split("=")[0];
        }
        return a;
    };
    this.getLength = function() { return this.keyValuePairs.length; } ;
}
function queryString(key){
    var page = new PageQuery(window.location.search); 
    return unescape(page.getValue(key)); 
}

function writeNowPlayingPlayerCookie(CookieName, CookieValue) {
    writePersistentCookie(CookieName, "", "years", -1);
    writePersistentCookie(CookieName, CookieValue, "months", 3, g_DomainName);
}

////////////////////////////////////////////////////////////////////////////////
// JBS Template Objects
function JBSTemplate(name, html){
    this.name = name;
    this.html = html;
}
function JBSTemplateVariable(name,value){
    this.name = name;
    this.value = value;
}
function JBSTemplateBinder(){
    this.templates = new Array();
    this.variables = new Array();
    this.addTemplate=function(name, html){
        for(var i in this.templates){
            if (this.templates[i].name == name){
                this.templates[i].html = html 
                return;
            }
        }
        this.templates[this.templates.length] = new JBSTemplate(name, html);
    };
    this.setValue=function(name,value){
        for(var i in this.variables)
            if (this.variables[i].name == name){
                this.variables[i].value = value;
                return;
            }
        this.variables[this.variables.length] = new JBSTemplateVariable(name,value);
    };
    this.bind=function(template){
        var html;
        for(var t in this.templates){
            if (this.templates[t].name == template){
                html = this.templates[t].html;
                for(var i in this.variables){
                    if (this.variables[i].name && this.variables[i].value){
                        var re = new RegExp(this.variables[i].name,"g");
                        html = html.replace(re,this.variables[i].value);
                    }
                }
            }
        }
        return html;
    };
}

function generic_ajax_show_callback(res){
    if (res.error == null)
        JBSPopup.display(res.value);
}

function startExtInstall(){
    //var install_xpi = {'MusicGremlin Client Control Extension': '/include/mgmozclient.xpi'};   
    var params = {
        "MusicGremlin Extension 2.0.0.0": { URL: "/include/mgmozclient.xpi",
             IconURL: "/images/mozextlogo.png"}
    };
    InstallTrigger.install(params); 
}

function getBrowserInfo(){
    if (bi)
        return bi;
    else{        
        try{
            var res = MusicGremlinPublic.Common.AjaxBrowserInfoProxy.getBrowserInfo(navigator.userAgent);
            if (!res.error) bi = res.value;
        }
        catch(e){}
    }
        
    return bi;
}
var __downlevelSamplePlayer;
function downlevelPlay(id){
    __downlevelSamplePlayer = window.open('/Common/Popup/SamplePlayDownlevel.aspx?id=' + id, '__SAMPLE__DOWNLEVEL', 'height:100px,width:100px,top:100px,left:100px');
}