// Global functions
var AttachHandler, LoadHandler, UpdateComponentDisplay,
AttachLangLinkActions, ChangeComponentLang, EnableAndAttachSelectLaterElementActions, ChooseLater,
UpdatePageTitle, GetElementsByClassName, GetCookieEnabledState,
SetCookie, GetCookie, BrowserData, GenerateBrowserOrder, RandomSort, LanguageData;

// Current browser order
var aBrowserOrder;

// Current language
var sCurrentLang = '';

// Default language
var sDefaultLang = '';

// Language retrieval pattern
var oLangPattern = new RegExp('^([a-z]{2,2})(-[a-z]{2,2})?$');

// Current user agent string
var sUserAgentString = navigator.userAgent;

// Default expiration (~5 years from current)
var sRunAgainExpiryDate = new Date();
sRunAgainExpiryDate.setDate(sRunAgainExpiryDate.getDate() + 1825);

// Cookies
var sBallotCookieName = 'choice';
var sRunAgainCookieName = 'restart';
var sRunAgainCookieExp = sRunAgainExpiryDate.toUTCString();

// Page component sections
var aPageComponents =
{
    headingComponentName: 'heading',
    browsersComponentName: 'browsers',
    contentComponentName: 'content'
};
// RegEx-to-browser name map
var aSelectLaterSupportedBrowsers =
{
    IE: 'Microsoft Internet Explorer'
};


// Attach window load handler
AttachHandler(window, 'load', LoadHandler);

// Attaches a given handler to a specified event of a given object
// obj: the object to attach to
// evt: the event to trigger on
// fnc: the handler (function) to bind to the obj/evt
function AttachHandler(oElement, sEventName, oFunction)
{
    if (oElement !== null && sEventName !== null && oFunction !== null)
    {
        // IE uses on* for event names, where other browsers do not (e.g. IE=onclick, FF=click)
        // Use this prefix in the IE case
        var sEventPrefix = 'on';
        
        // IE
        if (oElement.attachEvent)
        {
            oElement.attachEvent(sEventPrefix + sEventName, oFunction);
        }
        // Non-IE
        else if (oElement.addEventListener)
        {
            oElement.addEventListener(sEventName, oFunction, false);
        }
    }
}

// Handler intended for use on page load
function LoadHandler()
{

	// Randomize Browser
	GenerateBrowserOrder();

	// UpdateBrowserData for specific language
	UpdateAllBrowserData();

    // Enable select later elements and attach handler if so
    EnableAndAttachSelectLaterElementActions('button', 'selectLater');
}

// Enables and attaches actions for each select later element
// sElementName: The applicable HTML element name
// sClassName: The class name to qualify the element
function EnableAndAttachSelectLaterElementActions(sElementName, sClassName)
{
    // Assume browser is non-supported by default
    var bOnSupportedBrowser = false;

    // Check current browser
    for (var sBrowser in aSelectLaterSupportedBrowsers)
    {
        if (aSelectLaterSupportedBrowsers.hasOwnProperty(sBrowser))
        {
            if (aSelectLaterSupportedBrowsers[sBrowser].search(navigator.appName) > -1)
            {
                bOnSupportedBrowser = true;
                break;
            }
        }
    }

    // Return if browser is unsupported, cookies are disabled, or ballot cookie value is not true
    if (!bOnSupportedBrowser || !GetCookieEnabledState() || GetCookie(sBallotCookieName) != 'true')
    {
        return;
    }

    var aSelectLaterElements;
    
    // If document.getElementsByClassName is supported do it that way
    if (typeof (document.getElementsByClassName) != 'undefined')
    {
        aSelectLaterElements = document.getElementsByClassName(sClassName);
    }
    // Otherwise do it manually
    else
    {
        aSelectLaterElements = GetElementsByClassName(sElementName, sClassName);
    }

    // Check for a valid element list and enable + attach hanlder for each
    if (aSelectLaterElements !== null && aSelectLaterElements.length > 0)
    {
        for (var i = 0; i < aSelectLaterElements.length; i++)
        {
            // Enable
            aSelectLaterElements[i].style.display = 'block';
            
            // Attach event
            AttachHandler(aSelectLaterElements[i], 'click', ChooseLater);
        }
    }
}

// Alerts the user with a message when clicked
function ChooseLater(e)
{
    var sNotificationAttributeName = 'notification';
    var sNotificationString = '';
    
    // Get event source node
    var oEventNode = (e !== null && typeof (e.target) == 'undefined') ? e.srcElement : e.target;

    // Set cookie
    SetCookie(sRunAgainCookieName, 'true', sRunAgainCookieExp);
    
    // Get curent node notification string and display
    if (oEventNode.attributes[sNotificationAttributeName] !== null)
    {
        sNotificationString = oEventNode.attributes[sNotificationAttributeName].value;
        alert(sNotificationString);
    }
}

// Provides support for gathering an array of elements based on element + class name
// sElementName: The HTML name of the element to collect
// sClassName: The qualifying class name of the HTML element
function GetElementsByClassName(sElementName, sClassName)
{
    var aOutputElements = [];
    var aApplicableElements = document.getElementsByTagName(sElementName);

    for (var i = 0; i < aApplicableElements.length; i++)
    {
        if (aApplicableElements[i].attributes['class'] !== null)
        {
            if (aApplicableElements[i].attributes['class'].value == sClassName)
            {
                aOutputElements.push(aApplicableElements[i]);
            }
        }
    }

    return aOutputElements;
}

// Tests for cookie support. Returns true if enabled, false otherwise
function GetCookieEnabledState()
{
    // Set a cookie for this session to check for
    document.cookie = 'cookiesEnabled=true;';
    
    return (document.cookie.indexOf('cookiesEnabled=true') > -1) ? true : false;
}

// Sets a cookie name/value pair
// sName: The cookie name
// sValue: The cookie value
// sExpDate: The optional expiration dat of the cookie
function SetCookie(sName, sValue, sExpDate)
{
    var sCookie = '';
    // Make sure cookies are enabled and inputs are valid
    if (GetCookieEnabledState() && sName !== null && sValue !== null)
    {
        sCookie = sName + '=' + escape(sValue);

        // Add expiry if specified
        if (sExpDate !== null)
        {
            sCookie += ';expires=' + sExpDate;
        }

		sCookie += ';path=/';
        document.cookie = sCookie;
    }
}

// Returns the value of a specified key if page has a unique id, cookies are enabled
// and specified values exist
// sName: The cookie name
function GetCookie(sName)
{
    // Make sure cookies are enabled and inputs are valid
    if (GetCookieEnabledState() && sName !== null)
    {
        var aCookie = document.cookie.split('; ');

        for (var i = 0; i < aCookie.length; i++)
        {
            var aCrumbs = aCookie[i].split('=');
            if (sName == aCrumbs[0])
            {
                return unescape(aCrumbs[1]);
            }
        }
    }

    // Return null if the criteria is not met
    return null;
}


// Used for browser data
function BrowserData(name, logo, description, installLink, infoLink)
{
   this.name = name;
   this.logo = logo;
   this.description = description;
   this.installLink = installLink;
   this.infoLink = infoLink;
}

function UpdateBrowserData(nBrowserLocation, nBrowser)
{
	var oBrowserData = dataBrowsers[nBrowser];
	var oBrowserLogo = document.getElementById("_img_" + nBrowserLocation);
	var tdDescription = document.getElementById("_description_" + nBrowserLocation);
	var aInstallLink = document.getElementById("_installLink_" + nBrowserLocation);
	var aTellMeMoreLink = document.getElementById("_tellMeMoreLink_" + nBrowserLocation);
	
	oBrowserLogo.src = oBrowserData.logo;
	oBrowserLogo.alt = unescape(oBrowserData.name);
	oBrowserLogo.title = unescape(oBrowserData.name);
	tdDescription.innerHTML = unescape(oBrowserData.description);
	aInstallLink.href = unescape(oBrowserData.installLink);
	aTellMeMoreLink.href = unescape(oBrowserData.infoLink);

}

function UpdateAllBrowserData()
{
	for (var i=0; i < aBrowserOrder.length ; i++)
	{
		UpdateBrowserData(i+1, aBrowserOrder[i]);
	}
}

// Genereate random browser order
function GenerateBrowserOrder()
{

	var aBrowserOrderTop5 = new Array(0,1,2,3,4);
	var aBrowserOrderRest = new Array();
	
	for (var i=5; i < dataBrowsers.length; i++)
	{ 
		aBrowserOrderRest.push(i);
	}

	aBrowserOrderTop5.sort(RandomSort);
	aBrowserOrderRest.sort(RandomSort);
	
	aBrowserOrder = aBrowserOrderTop5.concat(aBrowserOrderRest);	
}

function RandomSort (a,b)
{
    return (0.5 - Math.random());
}
