﻿/* manager class */
// hack: external to class - used by callbacks
var _countriesControlID = null; 
var _yearsControlID = null;
var _monthsControlID = null;
var _daysControlID = null;
var _buttonControlID = null;
var _siteTypeID = null;
var _mgrReference = null;
var _currentField = null;
var _controls = null;
var _panelProvincesID = null;
var _panelLanguagesID = null;
var _panelTextboxesID = null;
var _panelDropdownListsID = null;
var _panelCheckboxID = null;
var _panelRememberMeID = null;
var _rememberMeCheckboxID = null;
var _acceptTermsCheckboxID = null;
var _controlType = null;
var _checkboxControlID = null;
var _provincesControlID = null;
var _overXAgeEnabled = false;
var _redirectUrl = "";
var _override = 0;
var _discoveryCallback = null;
var _verificationCallback = null;
var _dividerAfterCountryCode = ""; // default is no divider
var _hasProvinces = false;
var _hasLanguages = false;
var _selectedYear = "";

function AgeVerificationManager(siteTypeID, yearsOffset, controlType)
{
    // public methods
    this.RegisterControl = _registerControl;
    this.RegisterSubmitButton = _registerSubmitButton;
    this.RegisterPanel = _registerPanel;
    this.RegisterRememberMeCheckbox = _registerRememberMeCheckbox;
    this.RegisterAcceptTermsCheckbox = _registerAcceptTermsCheckbox;
    this.SetOverride = _setOverride;
    this.SetDefaultItemText = _setDefaultItemText;    
    this.SetDividerText = _setDividerText;    
    this.SetDividerAfterCountryCode = _setDividerAfterCountryCode;
    this.Init = _init; 
    
    this.PopulateProvinces = _populateProvinces;
    //this.PopulateLanguages = _populateLanguages;
    
    // fields
    _mgrReference = this;
    this.SiteTypeID = siteTypeID;
    _siteTypeID = siteTypeID;   
    this.YearsOffset = yearsOffset;
    this.ControlType = controlType.toLowerCase();
    _controlType = controlType.toLowerCase();
    // callbacks
    this.SetDiscoveryCompleteCallback = _setDiscoveryCompleteCallback;
    this.SetVerificationCompleteCallback = _setVerificationCompleteCallback;
    
    this.CountriesControlID = null;
    this.ProvincesControlID = null;
    this.LanguagesControlID = null;
    this.YearsControlID = null;
    this.MonthsControlID = null;
    this.DaysControlID = null;   
    this.ButtonControlID = null;
    this.Controls = null;
    this.CheckboxControlID = null;
    this.PanelProvincesID = null;
    this.PanelLanguagesID = null;
    this.PanelTextboxesID = null;
    this.PanelDropdownListsID = null;
    this.PanelCheckboxID = null;
    this.PanelRememberMeID = null;
    this.RememberMeCheckboxID = null;
    this.AcceptTermsCheckboxID = null;
    
    // private methods
    this._populateYears = _populateYears;
    this._populateMonths = _populateMonths;
    this._populateDays = _populateDays; 
    this._populateCountries = _populateCountries;
    this._execAjaxAgeValidate = _execAjaxAgeValidate;
    this._execAjaxDiscovery = _execAjaxDiscovery;
    this._onIndexChanged =  _onIndexChanged;
    
    this._go = _go;
    this._mark = _mark;
    this._clicked = _clicked;  
    
    // callbacks
    this._discoveryCallback = null;
    this._verificationCallback = null;    
}

function _setDiscoveryCompleteCallback(callback)
{
    this._discoveryCallback = callback;
    // also store in global var
    _discoveryCallback = callback;
}

function _setVerificationCompleteCallback(callback)
{
    this._verificationCallback = callback;
    // also store in global var    
    _verificationCallback = callback;
}

function _setDefaultItemText(text)
{   
    this._defaultItemText = text;
    _defaultItemText = text;    
}

function _setDividerText(text)
{
    this._dividerText = text;
    _dividerText = text;
}

function _setDividerAfterCountryCode(code)
{
    this._dividerAfterCountryCode = code;
    _dividerAfterCountryCode = code;
}

function _checkID(ctrlID)
{
    if (!document.getElementById(ctrlID))
    {
        alert(ctrlID + " element cannot be found.");
        return;
    }
    else
    {
        return ctrlID;
    }
}

function _registerControl(ctrlType, ctrlID)
{
    ctrlType = ctrlType.toLowerCase();
    if (ctrlType == "countries")
    {
        this.CountriesControlID = _checkID(ctrlID);
        _countriesControlID = ctrlID;
    }
    if (ctrlType == "provinces")
    {
        this.ProvincesControlID = _checkID(ctrlID);
        _provincesControlID = ctrlID;
    }
    if (ctrlType == "languages")
    {
        this.LanguagesControlID = _checkID(ctrlID);
        _languagesControlID = ctrlID;
    }    
    if (ctrlType == "years")
    {
        this.YearsControlID = _checkID(ctrlID);
        _yearsControlID = ctrlID;
    }    
    if (ctrlType == "months")
    {
        this.MonthsControlID = _checkID(ctrlID);
        _monthsControlID = ctrlID;
    }
    if (ctrlType == "days")
    {
        this.DaysControlID = _checkID(ctrlID);
        _daysControlID = ctrlID;
    }        
    if (ctrlType == "textboxes")
    {
        if (ctrlID.length != 3)
        {
            alert("The 'controls' array is not complete. It should contain 3 items.");
            return;
        }
        this.Controls = ctrlID;
        _controls = ctrlID;
    }
    if (ctrlType == "checkbox")
    {
        this.CheckboxControlID = _checkID(ctrlID);
        _checkboxControlID = ctrlID;
    }
}

function _registerPanel(panelType, divID)
{
    if (panelType.toLowerCase() == "textboxes")
    {
        this.PanelTextboxesID = _checkID(divID);
        _panelTextboxesID = divID;
    }
    else if (panelType.toLowerCase() == "dropdownlists")
    {
        this.PanelDropdownListsID = _checkID(divID);
        _panelDropdownListsID = divID;
    }
    else if (panelType.toLowerCase() == "checkbox")
    {
        this.PanelCheckboxID = _checkID(divID);
        _panelCheckboxID = divID;
    }
    else if (panelType.toLowerCase() == "provinces")
    {
        this.PanelProvincesID = _checkID(divID);
        _panelProvincesID = divID;
    }
    else if (panelType.toLowerCase() == "rememberme")
    {
        this.PanelRememberMeID = _checkID(divID);
        _panelRememberMeID = divID;
    }    
    else // languages
    {
        this.PanelLanguagesID = _checkID(divID);
        _panelLanguagesID = divID;
    }
}

function _registerRememberMeCheckbox(ctrlID)
{
    this.RememberMeCheckboxID = _checkID(ctrlID);;
    _rememberMeCheckboxID = ctrlID;
}

function _registerAcceptTermsCheckbox(ctrlID)
{
    this.AcceptTermsCheckboxID = _checkID(ctrlID);;
    _acceptTermsCheckboxID = ctrlID;
}

function _setOverride(value)
{   
    _override = value;
}

function _init()
{
    if (this.ControlType.toLowerCase() == "dropdownlists") // dropdown lists used
    {
        // populate
        this._populateYears(this.YearsOffset);
        this._populateMonths();
        this._populateDays();
        
        document.getElementById(this.YearsControlID).onchange = this._populateDays;    
        document.getElementById(this.MonthsControlID).onchange = this._populateDays;
    }
    else
    {
        var x = 0;
        var currentControl = null;
        for (x = 0; x < this.Controls.length; x++)
        {
            currentControl = this.Controls[x];
            document.getElementById(currentControl.id).onfocus = this._mark;
            document.getElementById(currentControl.id).onkeyup = this._clicked;    
        }
    }
    
    // hide divs
    if (this.PanelProvincesID) document.getElementById(this.PanelProvincesID).style.display = "none";
    if (this.PanelLanguagesID) document.getElementById(this.PanelLanguagesID).style.display = "none";
    if (this.PanelTextboxesID) document.getElementById(this.PanelTextboxesID).style.display = "none";
    if (this.PanelRememberMeID) document.getElementById(this.PanelRememberMeID).style.display = "none";   
    if (this.PanelDropdownListsID) document.getElementById(this.PanelDropdownListsID).style.display = "none";
    if (this.PanelCheckboxID) document.getElementById(this.PanelCheckboxID).style.display = "none";
    
    // onchange event to countries
    //document.getElementById(this.CountriesControlID).onchange = this._onIndexChanged;
    document.getElementById(this.CountriesControlID).onchange = this._execAjaxDiscovery;     
    // assign click event handler to button
    document.getElementById(this.ButtonControlID).onclick = _validateButtonClick;    
   
    // populate countries on load        
    window.onload = this._populateCountries;     
    // set focus to countries dropdown list
    //document.getElementById(_countriesControlID).focus();
}

function _validateButtonClick()
{
    var ctrlRef = document.getElementById(_countriesControlID);    
    if (!(ctrlRef.options[ctrlRef.selectedIndex].value.length > 0))
    {
        alert(DEFAULT_ITEM_TEXT);
    }
    return false;
}

function _onIndexChanged()
{
    // reset event handler
    document.getElementById(_buttonControlID).onclick = _execAjaxDiscovery;
}

function _clicked(evt)
{
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (!evt)
    {
        alert("Error in _clicked()");
        return;
    }
    var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
    if (!elem)
    {
        alert("elem is null in _clicked()");
        return;
    }
    
    var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);
    if (charCode == 3 || charCode == 13) // "enter" clicked - submit
    {
        var ctlButton = document.getElementById(_buttonControlID);
        if (document.all)
        {
            ctlButton.click();
        }
        else if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1)
        {
            var clickEvent = window.document.createEvent("MouseEvent"); 
            clickEvent.initEvent("click", false, true); 
            ctlButton.dispatchEvent(clickEvent); 
        }
        return false;
    }    
    if ((charCode < 48 || charCode > 57) && charCode != 8 && (charCode < 96 || charCode > 105)) // if not digit or backspace, number pad's got different char codes
    {
        elem.value = ""; // clear text
        return false;
    }
    if (charCode == 8 && elem.value.length == 0) // backspace clicked and textbox is empty
    {
        _go(-1); // go back
        return;
    }

    // check if digit allowed if field
    var elementID = elem.id.toLowerCase();
    if (elementID.indexOf("month") > -1) // month
    {
        var strMonth = document.getElementById(_controls[0].id).value;
        if (isNaN(strMonth)) // not a number so return
        {
            elem.value = "";
            return false;
        }
        if (strMonth.substr(0, 1) == "0" && strMonth.substr(1, 1) == "0")
        {
            elem.value = "";
            return false;
        }
        var intMonth = parseInt(strMonth, 10);        
        if (intMonth > 12) // alow only valid months
        {
            elem.value = "";
            return false;
        }
    }
    else if (elementID.indexOf("day") > -1)
    {
        var strDay = document.getElementById(_controls[1].id).value;
        if (isNaN(strDay))
        {
            elem.value = "";
            return false;
        }
        if (strDay.substr(0, 1) == "0" && strDay.substr(1, 1) == "0")
        {
            elem.value = "";
            return false;
        }        
        var intDay = parseInt(strDay, 10);        
        if (intDay > 31)
        {
            elem.value = "";
            return false;
        }
        
        var strMonth = document.getElementById(_controls[0].id).value;      
        if (!isNaN(strMonth)) // if valid month
        {
            var intMonth = parseInt(strMonth, 10);
            if (intMonth == 2) // if feb.
            {
                if (intDay > 29)
                {
                    elem.value = ""; // don't allow > 29 days for feb.
                    return false;
                }
            }
            var monthsWith30Days = [4,6,9,11];
            var ii = 0;
            for (ii = 0; ii < monthsWith30Days.length; ii++)
            {
                if (monthsWith30Days[ii] == intMonth && intDay > 30)
                {
                    elem.value = ""; // check for months with only 30 days
                    return false;
                }
            } 
        }
    }
    else if (elementID.indexOf("year") > -1)
    {
        var strYear = document.getElementById(_controls[2].id).value;
        if (isNaN(strYear))
        {
            elem.value = "";
            return false;
        }
        
        if (strYear.length == 4) // check year for being 1900+
        {
            var intYear = parseInt(strYear, 10);        
            if (intYear < 1900)
            {
                elem.value = "";
                return false;
            }
        }
    }    
    
    // let operation go through only when 2 chars entered
    if (elem.value.length == 2)
    {
        _go(1); // go forward
    }
}

function _mark(evt)
{
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (!evt)
    {
        alert("Error in _mark()");
        return;
    }
    var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
    if (!elem)
    {
        alert("elem is null in _mark()");
        return;
    }
    _currentField = elem;
    elem.select();
}

function _go(direction)
{
    var currentFieldID = _checkID(_currentField.id);
    var fields = _controls; // set ref to controls array
    
    var elementID = "";
    var element = null;
    var fieldsLength = fields.length;
    var x = 0;
    
    for (x = 0; x < fieldsLength; x++)
    {
        if (fields[x].id.toLowerCase() == currentFieldID.toLowerCase())
        {
            if ((direction == 1) && (x == fieldsLength - 1)) // last field
            {
                // uncomment to set focus back to first field
                //elementID = fields[0].id;
                //element = document.getElementById(elementID);
                //element.focus();
                //element.select();
            }
            else if ((direction == -1) && (x == 0)) // first field
            {
                elementID = fields[fieldsLength - 1].id;
                element = document.getElementById(elementID);
                element.focus();
                element.select();                
            }
            else // any other field
            {
                elementID = fields[(x % fieldsLength) + direction].id;
                element = document.getElementById(elementID);
                element.focus();
                element.select();
            }
        }
    }
}

function _registerSubmitButton(ctrlID)
{
    this.ButtonControlID = _checkID(ctrlID);
    _buttonControlID = ctrlID;
}

function _getNumberOfDays(month, year) // 1-based
{
    return (32 - new Date(year, month - 1, 32).getDate());
}

// yearOffset = current year - yearOffset
function _populateYears(yearOffset)
{
    var date = new Date();        
    var year = date.getFullYear();        

    // get reference to control
    _checkID(this.YearsControlID);
    var ctrl = document.getElementById(this.YearsControlID);

    ctrl.options.length = 0; // clear 
                
    var option = null;
    var upperBound = year - yearOffset; // set to current year - yearOffset
    var lowerBound = upperBound - 100;
    
    var out = "";
    
    var x = 0;
    var index = 0;
    for (x = upperBound; x >= lowerBound; x--)
    {
        option = new Option(x, x);
        ctrl.options[index] = option;
        index++;
    }
}

function _populateMonths() // monthsCollection - override for different languages
{
    var monthsCollection = 
        [ 
            {value:1, name:"January"}, {value:2, name:"February"}, {value:3, name:"March"}, {value:4, name:"April"}, {value:5, name:"May"}, {value:6, name:"June"}, 
            {value:7, name:"July"}, {value:8, name:"August"}, {value:9, name:"September"}, {value:10, name:"October"}, {value:11, name:"November"}, {value:12, name:"December"} 
        ]   

    // get reference to control
    _checkID(this.MonthsControlID);    
    var ctrl = document.getElementById(this.MonthsControlID);
     
    ctrl.options.length = 0; // clear items 
    
    var option = null;
    var x = 0;
    for (x = 0; x < monthsCollection.length; x++)
    {
        option = new Option(monthsCollection[x].name, monthsCollection[x].value);
        ctrl.options[x] = option;
    }
}

// month is 1-based integer
function _populateDays()
{
    // get reference to control
    var ctrlDays = document.getElementById(_mgrReference.DaysControlID);
    var ctrlMonths = document.getElementById(_mgrReference.MonthsControlID);
    var ctrlYears = document.getElementById(_mgrReference.YearsControlID);
    
    ctrlDays.options.length = 0; // clear items
    
    // get number of days in month
    var daysUpperBound = _getNumberOfDays(ctrlMonths.options[ctrlMonths.selectedIndex].value, ctrlYears.options[ctrlYears.selectedIndex].value); 

    var option = null;
    var x = 0;
    for (x = 0; x < daysUpperBound; x++)
    {
        option = new Option(x + 1, x + 1);
        ctrlDays.options[x] = option;
    }
}

var _xDoc = null;
function _populateCountriesCallback()
{
    _xDoc = AjaxAPI.GetXmlDoc();
    
    var nodes = _xDoc.getElementsByTagName("item");
    if (!nodes) 
    {
        alert("Error parsing XML.");
    }
    var ctrl = document.getElementById(_countriesControlID);
    ctrl.options.length = 0; // clear 
    
    var x = 0;    
    var option = null;
	var name = "";
	var value = "";   
    // add initial item
    option = new Option(DEFAULT_ITEM_TEXT, "");
    ctrl.options[0] = option;
    	 
    for(x = 0; x < nodes.length; x++)
    {   
		name = JSAPI.Trim(nodes[x].getAttribute("name"));
		value = JSAPI.Trim(nodes[x].getAttribute("value"));    
    
        option = new Option(name, value);
        ctrl.options[ctrl.options.length] = option;
		
		// insert devider after				
		if (_dividerAfterCountryCode.length > 0)
		{
		    if (value.toLowerCase() == _dividerAfterCountryCode.toLowerCase())
		    {
			    option = new Option(DIVIDER_TEXT, "");
			    ctrl.options[ctrl.options.length] = option;
		    }		
		}		
    }
    
    // get value from cookie and populate
    var countrySelectedValue = _getCookie("AgeVerificationCountry" + _siteTypeID);
    if (countrySelectedValue && countrySelectedValue.length > 0)
    {
        // set in countries drop-down list
        ctrl.value = countrySelectedValue;
        
        // mark checkbox checked
        if (_rememberMeCheckboxID)
        {
            document.getElementById(_rememberMeCheckboxID).checked = true;
        }
        // raise button click event
        if (document.getElementById(_buttonControlID))
        {
            _execAjaxDiscovery(); 
            document.getElementById(_buttonControlID).onclick = _execAjaxAgeValidate;
        }
        
        var cookieOverX = _getCookie("AgeVerificationOverXAgeEnabled" + _siteTypeID);
        var isoverx = (cookieOverX == "true" ? true : false);     
        
        if (_controlType == "textboxes" && !isoverx)
        {
            // populate from cookie
            var dateofbirth = _getCookie("AgeVerificationDateOfBirth" + _siteTypeID);
            if (dateofbirth && dateofbirth.length > 0)
            {
                var arrValues = dateofbirth.split(",");
                
                document.getElementById(_controls[0].id).value = arrValues[0];
                document.getElementById(_controls[1].id).value = arrValues[1];
                document.getElementById(_controls[2].id).value = arrValues[2];
            }
        }
        if (isoverx)
        {
            // set checkbox
            var checkedOrNot = _getCookie("AgeVerificationCheckbox" + _siteTypeID);
            document.getElementById(_checkboxControlID).checked = checkedOrNot;
        }
    }    
    
    // set country by ip
    _setCountryByIP();
}  

_xDoc = null;
function _populateProvincesCallback()
{
    _xDoc = AjaxAPI.GetXmlDoc();
    
    var nodes = _xDoc.getElementsByTagName("item");
    if (!nodes) 
    {
        alert("Error parsing XML.");
    }
    var ctrl = document.getElementById(_provincesControlID);
    if (!ctrl) return;
    
    ctrl.options.length = 0; // clear 
    
    var x = 0;    
    var option = null;
	var name = "";
	var value = "";   
    // add initial item
    option = new Option(DEFAULT_ITEM_TEXT_PROVINCE, "");
    ctrl.options[0] = option;
    	 
    for (x = 0; x < nodes.length; x++)
    {   
		name = JSAPI.Trim(nodes[x].getAttribute("name"));
		value = JSAPI.Trim(nodes[x].getAttribute("value"));    
    
        option = new Option(name, value);
        ctrl.options[ctrl.options.length] = option;
    }
    
    // set from cookie
    var provinceSelectedValue = _getCookie("AgeVerificationProvince" + _siteTypeID);
    if (provinceSelectedValue && provinceSelectedValue.length > 0)
    {
        // set in countries drop-down list
        ctrl.value = provinceSelectedValue;    
    }
}  

_xDoc = null;
function _populateLanguagesCallback()
{
    _xDoc = AjaxAPI.GetXmlDoc();
    
    var nodes = _xDoc.getElementsByTagName("item");
    if (!nodes) 
    {
        alert("Error parsing XML.");
    }
    var ctrl = document.getElementById(_languagesControlID);
    ctrl.options.length = 0; // clear     
    
    var x = 0;    
    var option = null;
	var name = "";
	var value = "";   
    // add initial item
    option = new Option(DEFAULT_ITEM_TEXT_LANGUAGE, "");
    ctrl.options[0] = option;
    	 
    for(x = 0; x < nodes.length; x++)
    {   
		name = JSAPI.Trim(nodes[x].getAttribute("name"));
		value = JSAPI.Trim(nodes[x].getAttribute("value"));    
    
        option = new Option(name, value);
        ctrl.options[ctrl.options.length] = option;
    }
    
    // select locale in list if present
    if (typeof(locale) != "undefined")
    {
        locale = locale.toLowerCase(); 
        var it = 0;
        for (it = 0; it < ctrl.options.length; it++)
        {
            if (ctrl.options[it].value == locale)
            {
                ctrl.value = locale;
            }
        }
    }
}  

function _populateCountries()
{
    var url = HANDLER_BASE_URL + "?type=countries&site_type_id=" + siteTypeID;
    
    AjaxAPI.init(url, null, _populateCountriesCallback, true);
    
    var success = AjaxAPI.exec();
    if (!success)
    {
        alert("AJAX error occurred during country population.");
    }
}

function _populateProvinces()
{
    var url = HANDLER_BASE_URL + "?type=provinces&country=" + document.getElementById(_countriesControlID).value;
    
    AjaxAPI.init(url, null, _populateProvincesCallback, true);
    
    var success = AjaxAPI.exec();
    if (!success)
    {
        alert("AJAX error occurred during province population.");
    }
}

function _populateLanguages()
{
    var url = HANDLER_BASE_URL + "?type=languages&country=" + document.getElementById(_countriesControlID).value;
    
    AjaxAPI.init(url, null, _populateLanguagesCallback, true);
    
    var success = AjaxAPI.exec();
    if (!success)
    {
        alert("AJAX error occurred during language population.");
    }
}

/*  #################### discovery logic ##################### */
var _checkboxMessage = "";
function _parseXmlDiscoveryCallback()
{
    _hasProvinces = false;
    _hasLanguages = false;
    
    _xDoc = AjaxAPI.GetXmlDoc();
    if (!_xDoc)
    {
        alert("Problem with fetching XML.");
    }
    
    var nodes = _xDoc.getElementsByTagName("disco"); // document element
    if (!nodes) return;
    if (nodes.length != 1) return;
    
    var countryCode = JSAPI.Trim(nodes[0].getAttribute("countryCode"));
    if (JSAPI.IsEmpty(countryCode))
    {
        return false;
    }    
    var minAge = JSAPI.Trim(nodes[0].getAttribute("minimumAge"));
    if (JSAPI.IsEmpty(minAge))
    {
        return false;
    }
    var url = JSAPI.Trim(nodes[0].getAttribute("url"));	
    if (JSAPI.IsEmpty(url))
    {
        return false;
    }   
    // set global variable
    _redirectUrl = url;
    
    var isOverXAge = JSAPI.Trim(nodes[0].getAttribute("overXAgeEnabled"));	
    if (JSAPI.IsEmpty(isOverXAge))
    {
        return false;
    }      
    var hasProvinces = JSAPI.Trim(nodes[0].getAttribute("hasProvinces"));	
    if (JSAPI.IsEmpty(hasProvinces))
    {
        return false;
    }    
    
    var hasLanguages = JSAPI.Trim(nodes[0].getAttribute("hasLanguages"));	
    if (JSAPI.IsEmpty(hasLanguages))
    {
        return false;
    }           
    var hasMicrosite = JSAPI.Trim(nodes[0].getAttribute("hasMicrosite"));	
    if (JSAPI.IsEmpty(hasMicrosite))
    {
        return false;
    }     
    
    if (hasMicrosite == 0)
    {
        // change event handler on the submit button
        document.getElementById(_buttonControlID).onclick = _execAjaxAgeValidate;    
    }
    else // if has microsite, set button action to redirect to microsite's gateway
    {
        document.getElementById(_buttonControlID).onclick = _redirect;
        return;
    }
    
    if (_override == 1) // skip the rest and just call the callback method with args
    {
        if (isOverXAge == 1)
        {
            // global flag
            _overXAgeEnabled = true;
        }
    
        // create args object
        var args = {};
        args.countryCode = countryCode;
        args.minimumAge = minAge;
        args.url = url;
        args.overXAgeEnabled = (isOverXAge == 1 ? true : false);
        args.hasProvinces = (hasProvinces == 1 ? true : false);
        args.hasLanguages = (hasLanguages == 1 ? true : false);
        args.hasMicrosite = (hasMicrosite == 1 ? true : false);
        
        // invoke callback method
        _discoveryCallback(null, args);
        return;
    }

    if (hasProvinces == 1) // display and populate provinces dropdown list
    {
        document.getElementById(_panelProvincesID).style.display = "block";
        _populateProvinces();
        _hasProvinces = true;
    }
    if (hasLanguages == 1) // display and populate languages dropdown list
    {
        document.getElementById(_panelLanguagesID).style.display = "block";
        setTimeout("_populateLanguages()", 500); // set 2 second delay to let provinces load
        _hasLanguages = true;
    }    
    if (isOverXAge == 1) // display checkbox
    {
        document.getElementById(_panelCheckboxID).style.display = "block";
        var lblID = _checkID(_checkboxControlID + "Label");
        if (_checkboxMessage == "") // store in global var
        {
            _checkboxMessage = document.getElementById(lblID).innerHTML;
        }
        var index = _checkboxMessage.indexOf("{0}");
        if (index > -1)
        {
            document.getElementById(lblID).innerHTML = _checkboxMessage.substr(0, index) + " " + 
                minAge + " " + _checkboxMessage.substr(index + 3, _checkboxMessage.length);
        }
            
        // global flag
        _overXAgeEnabled = true;
    }
    else if (_controlType == "textboxes") // textboxes
    {
        document.getElementById(_panelTextboxesID).style.display = "block";
        document.getElementById(_panelRememberMeID).style.display = "block";
        
        var x = 0;
        var currentControl = null;
        for (x = 0; x < _controls.length; x++)
        {
            currentControl = _controls[x];
            if (currentControl.focus == "1")
            {
                if (document.getElementById(currentControl.id))
                {
                    document.getElementById(currentControl.id).focus();
                }
            }    
        }
    }
    else // dropdown lists
    {
        document.getElementById(_panelDropdownListsID).style.display = "block";
    }
}  

function _execAjaxDiscovery()
{
    // reset global flag
    _overXAgeEnabled = false;
    
    // hide divs
    if (_panelProvincesID) document.getElementById(_panelProvincesID).style.display = "none";
    if (_panelLanguagesID) document.getElementById(_panelLanguagesID).style.display = "none";
    if (_panelTextboxesID) document.getElementById(_panelTextboxesID).style.display = "none";
    if (_panelRememberMeID) document.getElementById(_panelRememberMeID).style.display = "none";    
    if (_panelDropdownListsID) document.getElementById(_panelDropdownListsID).style.display = "none";
    if (_panelCheckboxID) document.getElementById(_panelCheckboxID).style.display = "none";
    
    var url = HANDLER_BASE_URL + "?country=" + _getSelectedCountry() + "&site_type_id=" + _siteTypeID + "&type=discovery";
    
    AjaxAPI.init(url, null, _parseXmlDiscoveryCallback, true);
    
    var success = AjaxAPI.exec();
    if (!success)
    {
        alert("AJAX error occurred during the discovery stage.");
    }
}
/*  #################### end discovery logic ##################### */

/*  ###################### validation logic ###################### */
var monthDayEnabled = false;
function _parseXmlAgeValidateCallback()
{
    _xDoc = AjaxAPI.GetXmlDoc();
    if (!_xDoc)
    {
        alert("Problem with fetching XML.");
    }
    
    var nodes = _xDoc.getElementsByTagName("age");
    if (!nodes)
    {
        alert("Error fetching XML.");
    }
    if (nodes.length != 1)
    {
        alert("Error fetching XML.");
    }    
    
    // reset event handler on submit button
    //document.getElementById(_buttonControlID).onclick = _execAjaxDiscovery;
    
    var valid = JSAPI.Trim(nodes[0].getAttribute("valid")); // returns 0 or 1
    if (JSAPI.IsEmpty(valid))
    {
        return false;
    }
    var minAge = JSAPI.Trim(nodes[0].getAttribute("min"));	
    if (JSAPI.IsEmpty(minAge))
    {
        return false;
    }         
    var url = JSAPI.Trim(nodes[0].getAttribute("url"));   
    url = JSAPI.Replace(url, "&amp;", "&"); // decode back to & to get valid url
    if (JSAPI.IsEmpty(url))
    {
        return false;
    }   
    url = url + ""; // cast to string  	          
    
    //var yearEntered = document.getElementById("year").options[document.getElementById("year").selectedIndex].value;
    minAge = parseInt(minAge, 10); // cast to int
    
    var encrypted = JSAPI.Trim(nodes[0].getAttribute("encrypted"));   
    encrypted = encrypted + ""; // cast to string  
    var isValid = (valid == 1 ? true : false);
    
    // terms accepted? if not return invalid
    if (_acceptTermsCheckboxID)
    {
        if (document.getElementById(_acceptTermsCheckboxID))
        {
            if (!document.getElementById(_acceptTermsCheckboxID).checked)
            {
                OpenBrWindow(INVALID_AGE_URL, "LDA_NOT_MET", "toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no", "450", "350", "true");
                return;
            }
        }
    }    

    // remember me?
    if (_rememberMeCheckboxID)
    {
        if (document.getElementById(_rememberMeCheckboxID).checked)
        {
            // checked so store in cookies
            var provincesControlID = document.getElementById(_provincesControlID);
            
            _setCookie("AgeVerificationCountry" + _siteTypeID, document.getElementById(_countriesControlID).value);
            if (provincesControlID)
            {
                _setCookie("AgeVerificationProvince" + _siteTypeID, provincesControlID.value);
            }
            //_setCookie("AgeVerificationCheckbox" + _siteTypeID, document.getElementById(_checkboxControlID).checked);  
            //_setCookie("AgeVerificationOverXAgeEnabled" + _siteTypeID, _overXAgeEnabled);  
            
            var month = document.getElementById(_controls[0].id).value;
            var day = document.getElementById(_controls[1].id).value;
            var year = document.getElementById(_controls[2].id).value;  
            _setCookie("AgeVerificationDateOfBirth" + _siteTypeID, month + "," + day + "," + year);
        }
        else
        {
            // delete cookies
            _deleteCookie("AgeVerificationCountry" + _siteTypeID, null, null);
            _deleteCookie("AgeVerificationProvince" + _siteTypeID, null, null);            
            //_deleteCookie("AgeVerificationCheckbox" + _siteTypeID, null, null);     
            //_deleteCookie("AgeVerificationOverXAgeEnabled" + _siteTypeID, null, null);      
            _deleteCookie("AgeVerificationDateOfBirth" + _siteTypeID, null, null);             
        }
    }
    
    // append key to each link
    //_appendKeyToLinks(encrypted);
    
    // redirect url or deeplink may be submitted
    var qs = window.location.search;
    qs = qs + "";
    if (qs != "null" && qs != "")
    {
        var hasRedirect = false;    
        if (qs.toLowerCase().indexOf("url=") > -1)
        {
            hasRedirect = true;
            qs = qs.substring(qs.indexOf("url=") + 4); // retrieve redirect url
        }  
        
        // replace "key=" with "dummy="
        if (qs.toLowerCase().indexOf("key=") > -1)
        {
            var regEx = /key=/gi;
            qs = qs.replace(regEx, "dummy=");
        }
        if (hasRedirect) // replace url with the redirecturl
        {
            if (isValid)
            {
                if (url.indexOf("construction.html") == -1)
                {
                    url = qs;
                }
            }
            else // invalid age url
            {
                url = INVALID_AGE_URL;
            }
        }
        else
        {
            url += qs;
        }
    }          
    
    if (_override == 1) // skip the rest and just call the callback method with args
    {
        // create args object
        var args = {};
        args.valid = isValid;
        args.minimumAge = minAge;
        args.encryptedKey = encrypted; // cast to string  
        args.url = url;        
        
        // invoke callback method
        _verificationCallback(null, args);
        return;
    }     
    
    // redirect to appropriate page
    url = (!isValid ? url : url + (url.indexOf("?") > -1 ? "&" : "?") + "key=" + encrypted); // don't append key if age not verified
    
    if (!isValid)
    {
        OpenBrWindow(url, "LDA_NOT_MET", "toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no", "450", "350", "true");
    }
    else
    {
        window.location = url;
        return false;
    }
}  

function _execAjaxAgeValidate()
{
    var url = HANDLER_BASE_URL;
    
    if (_overXAgeEnabled) // checkbox 
    {
        // check if checkbox checked
        if (document.getElementById(_checkboxControlID).checked)
        {
            // use dummy date
            url += "?month=1&day=1&year=1900&country=US-EN&type=validate_date";
        }
        else // not checked so boot the user - set date in the future
        {
            url += "?month=1&day=1&year=2999&country=US-EN&type=validate_date";
        }
    }    
    else
    {
        if (_controlType == "dropdownlists") // dropdown list
        {
            if (!_validProvinceAndLocale())
            {
                return;
            }        
        
            url += "?month=" + document.getElementById(_monthsControlID).options[document.getElementById(_monthsControlID).selectedIndex].value + 
                "&day=" + document.getElementById(_daysControlID).options[document.getElementById(_daysControlID).selectedIndex].value + 
                "&year=" + document.getElementById(_yearsControlID).options[document.getElementById(_yearsControlID).selectedIndex].value + 
                "&country=" + _getSelectedCountry() + 
                "&province=" + _getSelectedProvince() +
                "&locale=" + _getSelectedLocale() +
                "&site_type_id=" + _siteTypeID +
                "&type=validate_date";
        }
        else if (_controlType == "textboxes")
        {
            // last-minute validation
            if (!_hasSelectedCountry())
            {
                document.getElementById(_buttonControlID).onclick = _validateButtonClick;
                _validateButtonClick();
                return;
            }             
            if (!_validProvinceAndLocale())
            {
                return;
            }  
        
            var month = JSAPI.Trim(document.getElementById(_controls[0].id).value);
            var day = JSAPI.Trim(document.getElementById(_controls[1].id).value);
            var year = JSAPI.Trim(document.getElementById(_controls[2].id).value);
            
            _selectedYear = year;
                
            if (!JSAPI.IsDate(month + "/" + day + "/" + year))
            {
                alert("Invalid date.")
                return;
            }            
            // end last-minute validation
                
            url += "?month=" + month + "&day=" + day + "&year=" + year + 
                "&country=" + _getSelectedCountry() + 
                "&province=" + _getSelectedProvince() +
                "&locale=" + _getSelectedLocale() +
                "&site_type_id=" + _siteTypeID +
                "&type=validate_date";
        }
    }

    AjaxAPI.init(url, null, _parseXmlAgeValidateCallback, true);
    
    var success = AjaxAPI.exec();
    if (!success)
    {
        alert("AJAX error occurred in _execAjaxAgeValidate()");
    }
    
    return false; // do not remove
}   

function _validProvinceAndLocale()
{
    if (_hasProvinces)
    {
        if (!_hasSelectedProvince())
        {
            alert("Please select a province.")
            return false;
        }
    }
    if (_hasLanguages)
    {
        if (!_hasSelectedLanguage())
        {
            alert("Please select a language.")
            return false;
        }
    }  
    return true;
}

function _getSelectedCountry()
{
    var ctrlRef = document.getElementById(_countriesControlID);
    return ctrlRef.options[ctrlRef.selectedIndex].value;
}

function _getSelectedProvince()
{
    if (!_hasProvinces) return ""; 
    var ctrlRef = document.getElementById(_provincesControlID);    
    return ctrlRef.options[ctrlRef.selectedIndex].value;
}

function _getSelectedLocale()
{
    if (!_hasLanguages) return ""; 
    var ctrlRef = document.getElementById(_languagesControlID);    
    return ctrlRef.options[ctrlRef.selectedIndex].value;
}

function _hasSelectedCountry()
{
    var ctrlRef = document.getElementById(_countriesControlID);    
    return (ctrlRef.options[ctrlRef.selectedIndex].value.length > 0);
}

function _hasSelectedProvince()
{
    if (!_hasProvinces) return false; 
    var ctrlRef = document.getElementById(_provincesControlID);    
    return (ctrlRef.options[ctrlRef.selectedIndex].value.length > 0);
}

function _hasSelectedLanguage()
{
    if (!_hasLanguages) return false; 
    var ctrlRef = document.getElementById(_languagesControlID);    
    return (ctrlRef.options[ctrlRef.selectedIndex].value.length > 0);
}

function _setCountryByIP()
{
    var ctrl = document.getElementById(_countriesControlID);    
    
    if (typeof(ismatch) != "undefined")
    {
        if (ismatch == 1) // populate only if country matches language in browser
        {
            if (typeof(countryCode) != "undefined")
            {
                var it = 0;
                for (it = 0; it < ctrl.options.length; it++)
                {
                    if (ctrl.options[it].value == countryCode.toUpperCase())
                    {
                        ctrl.value = countryCode.toUpperCase();
                        _execAjaxDiscovery();
                    }
                }
            }
        }
    }
}

function _redirect()
{
    window.location = _redirectUrl;
    return false;
}

function _appendKeyToLinks(key)
{
    var links = document.getElementsByTagName("a");
    var pipe = "?";
    var link = "";
    var x = 0;
    
    for (x = 0; x < links.length; x++)
    {
        link = links[x].href;
        if (link.indexOf("?") > -1)
        {
            pipe = "&";
        }
        links[x].href = link + pipe + "key=" + key;
    }
}
/*  #################### end validation logic ##################### */ 

/* ##################### cookies ################################## */
function _setCookie(name, value)
{
	var expiredate = new Date();
	expiredate.setTime(expiredate.getTime() + (365*24*60*60*1000)); // 365 is days

    document.cookie= name + "=" + escape(value) + "; expires=" + expiredate.toGMTString();
}

/**
 * Gets the value of the specified cookie.
 *
 * name  Name of the desired cookie.
 *
 * Returns a string containing value of specified cookie,
 *   or null if cookie does not exist.
 */
function _getCookie(name)
{
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1)
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else
    {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1)
    {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}

function _deleteCookie(name, path, domain)
{
    if (getCookie(name))
    {
        document.cookie = name + "=" + 
            ((path) ? "; path=" + path : "") +
            ((domain) ? "; domain=" + domain : "") +
            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}
/* ##################### end cookies ################################## */

/* ##################### functions ########################### */
function OpenBrWindow(theURL, winName, features, myWidth, myHeight, isCenter) 
{ 
	if(window.screen)if(isCenter)if(isCenter=="true")
	{
		var myLeft = (screen.width - myWidth) / 2;
		var myTop = (screen.height - myHeight) / 2;
		
		features += (features != '') ? ',' : '';
		features += ',left=' + myLeft + ',top=' + myTop;
	}

	var win = window.open(theURL, winName, features + ((features != '') ? ',' : '') + 'width=' + myWidth + ',height=' + myHeight);
}

function checkleapyear(datea)
{
	datea = parseInt(datea);
	if(datea%4 == 0)
	{
		if(datea%100 != 0)
		{
			return true;
		}
		else
		{
			if(datea%400 == 0)
				return true;
			else
				return false;
		}
	}
    return false;
}
/* Script by hscripts.com */
/* ##################### end temporal functions ####################### */