function EBGCountry(iCountryId, sName, sCode, bAllowOtherProvinceEntry) {
	this.iCountryId = iCountryId;
	this.sName = sName;
	this.sCode = sCode;
	this.bAllowOtherProvinceEntry = bAllowOtherProvinceEntry;
	this.aProvinceList = new Array();
	this.aProvinceIDIndex = new Array();
}

EBGCountry.prototype.getCountryId = function (){
	return this.iCountryId;
}

EBGCountry.prototype.getName = function (){
	return this.sName;
}

EBGCountry.prototype.getCode = function (){
	return this.sCode;
}

EBGCountry.prototype.allowOtherProvinceEntry = function (){
	return this.bAllowOtherProvinceEntry;
}

EBGCountry.prototype.addProvince = function(iProvinceId, sName, sCode, sAbbreviation){
	oNewProvince = new EBGProvince(this, iProvinceId, sName, sCode, sAbbreviation);
	iNewIndex = this.aProvinceList.push(oNewProvince);
	this.aProvinceIDIndex[iProvinceId] = iNewIndex-1;
}
EBGCountry.prototype.getProvinces = function(){
	return this.aProvinceList;
}
EBGCountry.prototype.getProvince = function(iProvinceId){
    return this.aProvinceList[this.aProvinceIDIndex[iProvinceId]];
}
EBGCountry.prototype.getProvinceCount = function(){
	return this.aProvinceList.length;
}
EBGCountry.prototype.removeAllProvinces = function(){
    this.aProvinceList.slice(0, this.aProvinceList.length);
    this.aProvinceIDIndex.slice(0, this.aProvinceIDIndex.length);
}

function EBGProvince(oParentCountry, iProvinceId, sName, sCode, sAbbreviation) {
	this.oParentCountry = oParentCountry;
	this.iProvinceId = iProvinceId;
	this.sName = sName;
	this.sCode = sCode;
	this.sAbbreviation = sAbbreviation;
}

EBGProvince.prototype.getParentCountry = function(){
	return this.oParentCountry;
}

EBGProvince.prototype.getProvinceId = function (){
	return this.iProvinceId;
}

EBGProvince.prototype.getName = function (){
	return this.sName;
}

EBGProvince.prototype.getCode = function (){
	return this.sCode;
}

EBGProvince.prototype.getAbbreviation = function (){
	return this.sAbbreviation;
}

function EBGCountryProvinceSelector(aProperties){
	this.sCountryElementName = aProperties["country_element_name"];
	this.sProvinceElemName = aProperties["province_element_name"];
	this.oCountryHtmlElement = document.getElementById(aProperties["country_element_name"]);
	this.oProvinceHtmlElement = document.getElementById(aProperties["province_element_name"]);
	this.sCountrySelectName = aProperties["country_select_name"];
	this.sCountryOtherInputName = aProperties["other_country_input_name"];
	this.sProvinceSelectName = aProperties["province_select_name"];
	this.sProvinceOtherInputName = aProperties["other_province_input_name"];
	this.sWebserviceUrl = aProperties["webservice_url"];
	this.aCountryList = new Array();
	this.aCountryIDIndex = new Array();
	this.onCountriesRefreshed = null;
	this.onProvincesRefreshed = null;
	this.onCountryChanged = null;
	this.onProvinceChanged = null;
	this.iSelectedCountryId = aProperties["selected_country_id"];
	this.sOtherCountry = aProperties["other_country"];
	this.iSelectedProvinceId = aProperties["selected_province_id"];
	this.sOtherProvince = aProperties["other_province"];
	this.bAllowOtherCountries = aProperties["allow_other_countries"];
	this.bJustCreated = true;

	this.loadCountries();
}

EBGCountryProvinceSelector.prototype.createHtml = function() {
	this.oCountryHtmlElement.innerHTML = "";
	this.oProvinceHtmlElement.innerHTML = "";

	//Create country dropdown, we're assuming countries have been loaded
	if ( this.aCountryList.length > 1 || (this.aCountryList.length == 1 && this.bAllowOtherCountries))
	{
		var oCountryDropdown = document.createElement("select");
		oCountryDropdown.id = this.sCountrySelectName;
		oCountryDropdown.name = this.sCountrySelectName;
		oCountryDropdown.style.width = "150px";
	    oCountryDropdown.style.fontSize = "10px";
		oCountryDropdown.oCountryProvinceSelector = this;
		oCountryDropdown.onchange = EBGCountryProvinceSelector.changeCountry;
		var oCountryOption = document.createElement("option");
		oCountryOption.text = "--- SELECT COUNTRY ---";
		oCountryOption.value = 0;
		oCountryOption.selected = this.iSelectedCountryId == 0;
		try {
    		oCountryDropdown.add(oCountryOption, null);
    	}
    	catch (e){
    	   oCountryDropdown.add(oCountryOption);
    	}
		if ( this.bAllowOtherCountries )
		{
			oCountryOption = document.createElement("option");
			oCountryOption.text = "My country is not listed";
			oCountryOption.value = -1;
			oCountryOption.selected = this.iSelectedCountryId == -1;
			try {
        		oCountryDropdown.add(oCountryOption, null);
        	}
    	   catch (e){
        	   oCountryDropdown.add(oCountryOption);
        	}
		}
		//add options for each country
		if ( this.aCountryList.length > 0)
		{
			var i = 0;
			var iCurrentCountryId = 0;
			for (i = 0; i < this.aCountryList.length; i++)
			{
				oCountryOption = document.createElement("option");
				try {
        		  oCountryDropdown.add(oCountryOption, null);
            	}
    	       catch (e){
            	   oCountryDropdown.add(oCountryOption);
            	}
				oCountryOption.text = this.aCountryList[i].getName();
				iCurrentCountryId = this.aCountryList[i].getCountryId();
				oCountryOption.value = iCurrentCountryId;
				oCountryOption.selected = (this.iSelectedCountryId == iCurrentCountryId);
			}
		}
		this.oCountryHtmlElement.appendChild(oCountryDropdown);

		if ( this.bAllowOtherCountries )
		{
			var oDiv = document.createElement("div");
			oDiv.id = "OtherCountryDisplay_"+this.sCountrySelectName;
			oDiv.style.display = "none";

			var oOtherCountryDiv = document.createElement("div");
			var oOtherCountryLabel = document.createElement("strong");
			oOtherCountryLabel.appendChild(document.createTextNode("Enter your country below: "));
			oOtherCountryDiv.appendChild(oOtherCountryLabel);
			oDiv.appendChild(oOtherCountryDiv);
			oOtherCountryDiv = document.createElement("div");
			var oOtherCountryInput = document.createElement("input");
			oOtherCountryInput.type = "text";
			if ( this.sCountryOtherInputName && this.sCountryOtherInputName.length > 0 ){
				oOtherCountryInput.id = this.sCountryOtherInputName;
				oOtherCountryInput.name = this.sCountryOtherInputName;
			}
			else {
				oOtherCountryInput.id = this.sCountrySelectName + "_other";
				oOtherCountryInput.name = this.sCountrySelectName + "_other";
			}
			oOtherCountryInput.value = this.sOtherCountry ? this.sOtherCountry : "";
			oOtherCountryDiv.appendChild(oOtherCountryInput);
			oDiv.appendChild(oOtherCountryDiv);
			this.oCountryHtmlElement.appendChild(oDiv);
		}
	}
	else if ( this.aCountryList.length == 1)
	{
		this.iSelectedCountryId = this.aCountryList[0].getCountryId();
		oDiv = document.createElement("div");
		oDiv.appendChild(document.createTextNode(this.aCountryList[0].getName()));
		oHidden = document.createElement("input");
		oHidden.type = "hidden";
		oHidden.id = this.sCountrySelectName;
		oHidden.name = this.sCountrySelectName;
		oHidden.value = this.iSelectedCountryId;
		oDiv.appendChild(oHidden);
		this.oCountryHtmlElement.appendChild(oDiv);
	}
	
	if ( this.iSelectedCountryId != 0 ){
    	this.loadProvinces(this.iSelectedCountryId);
    }
    else {
        this.oProvinceHtmlElement.appendChild(document.createTextNode("Please select a country first"));
    }
}

EBGCountryProvinceSelector.prototype.createProvinceHtml = function(){
    this.oProvinceHtmlElement.innerHTML = "";
    if ( this.iSelectedCountryId == 0 ){
        this.oProvinceHtmlElement.appendChild(document.createTextNode("Please select a country first"));
    }
    else {
    	var oCountry = this.aCountryList[this.aCountryIDIndex[this.iSelectedCountryId]];
    	var aProvinces = null;
    	if ( oCountry ){
    		aProvinces = oCountry.getProvinces();
    	}
    	
	    if ( this.iSelectedCountryId == -1 || (oCountry.allowOtherProvinceEntry() && aProvinces.length == 0) ){
	        var oDiv = document.createElement("div");
	        var oHidden = document.createElement("input");
	        oHidden.type = "hidden";
	        oHidden.id = this.sProvinceSelectName;
	        oHidden.name = this.sProvinceSelectName;
	        oHidden.value = -1;
	        oDiv.appendChild(oHidden);
	        var oInput = document.createElement("input");
	        oInput.type = "text";
			oInput.style.width = "150px";
	        oInput.style.fontSize = "10px";
	        if ( this.sProvinceOtherInputName && this.sProvinceOtherInputName.length > 0 ){
	           	oInput.id = this.sProvinceOtherInputName;
	           	oInput.name = this.sProvinceOtherInputName;
	        }
	        else {
		        oInput.id = this.sProvinceSelectName + "_other";
	    	    oInput.name = this.sProvinceSelectName + "_other";
	    	}
	        oInput.value = this.sOtherProvince ? this.sOtherProvince : "";
	        oDiv.appendChild(oInput);
	        this.oProvinceHtmlElement.appendChild(oDiv);
	    }
	    else {
	        
	        oDiv = document.createElement("div");
	        var oDropdown = document.createElement("select");
	        oDropdown.id = this.sProvinceSelectName;
	        oDropdown.name = this.sProvinceSelectName;
			oDropdown.style.width = "150px";
	        oDropdown.style.fontSize = "10px";
	        oDropdown.oCountryProvinceSelector = this;
	        oDropdown.onchange = EBGCountryProvinceSelector.changeProvince;
	        var oOption = document.createElement("option");
	        try {
	            oDropdown.add(oOption, null);
	        }
	        catch(e){
	            oDropdown.add(oOption);
	        }
	        oOption.text = "--- SELECT ONE ---";
	        oOption.value = 0;
	        oOption.selected = this.iSelectedProvinceId == 0;
	        
	        if ( oCountry.allowOtherProvinceEntry() ){
	            oOption = document.createElement("option");
	            try {
	                oDropdown.add(oOption, null);
	            }
	            catch(e){
	                oDropdown.add(oOption);
	            }
	            oOption.text = "My state/province is not listed";
	            oOption.value = -1;
	            oOption.selected = this.iSelectedProvinceId == -1;
	        }
	        
	        for(i = 0; i < aProvinces.length; i++){
	            oOption = document.createElement("option");
	            try {
	                oDropdown.add(oOption, null);
	            }
	            catch(e){
	                oDropdown.add(oOption);
	            }
	            oOption.text = aProvinces[i].getName();
	            oOption.value = aProvinces[i].getProvinceId();
	            oOption.selected = this.iSelectedProvinceId == oOption.value;
	        }
	        oDiv.appendChild(oDropdown);
	    
	        this.oProvinceHtmlElement.appendChild(oDiv);
	        
	        if ( oCountry.allowOtherProvinceEntry() ){
	            oDiv = document.createElement("div");
	            oDiv.id = "OtherProvinceDisplay_"+this.sProvinceSelectName;
	            if ( this.iSelectedProvinceId == -1 ){
	            	oDiv.style.display = "block";
	            }
	            else {
		            oDiv.style.display = "none";
		        }
	            oInput = document.createElement("input");
	            oInput.type = "text";
	            if ( this.sProvinceOtherInputName && this.sProvinceOtherInputName.length > 0 ){
	            	oInput.id = this.sProvinceOtherInputName;
	            	oInput.name = this.sProvinceOtherInputName;
	            }
	            else {
		            oInput.id = this.sProvinceSelectName + "_other";
	    	        oInput.name = this.sProvinceSelectName + "_other";
	    	    }
	            oInput.value = this.sOtherProvince ? this.sOtherProvince : "";
	            oDiv.appendChild(oInput);
	            this.oProvinceHtmlElement.appendChild(oDiv);
	        }
	    }
	}
}

EBGCountryProvinceSelector.prototype.onCountriesRefreshedFunction = function(){
	if ( this.onCountriesRefreshed != null )
	{
		this.onCountriesRefreshed();
	}
}

EBGCountryProvinceSelector.prototype.onProvincesRefreshedFunction = function(){
	if ( this.onProvincesRefreshed != null )
	{
		this.onProvincesRefreshed();
	}
}

EBGCountryProvinceSelector.prototype.loadCountries = function(){
	sPostData = "request_type=country_list";

	var oSelector = this;

	//Open http request
	var httpRequest = getHTTPObject();
	if ( httpRequest ) {
		//Get results and parse
		httpRequest.open("POST", this.sWebserviceUrl, true);
		httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

        httpRequest.onreadystatechange = function(){
			if ( httpRequest.readyState == 4) {
			    var xmlDoc = httpRequest.responseXML;
				if ( xmlDoc ) {
					oSelector.aCountryList.splice(0, oSelector.aCountryList.length);
					oSelector.aCountryIDIndex.splice(0, oSelector.aCountryIDIndex.length);

					var dataElement = xmlDoc.getElementsByTagName("Data")[0];
					var aCountryElements = dataElement.getElementsByTagName("Country");

                    var i = 0, iNewLength = 0;
					var oIdElem, oNameElem, oCodeElem, oAllowOtherElem;
					var iId, sName, sCode, bAllowOther;

					for ( i = 0; i < aCountryElements.length; i++) {
						oIdElem = aCountryElements[i].getElementsByTagName("ID")[0];
						oNameElem = aCountryElements[i].getElementsByTagName("Name")[0];
						oCodeElem = aCountryElements[i].getElementsByTagName("Code")[0];
						oAllowOtherElem = aCountryElements[i].getElementsByTagName("AllowOtherProvinceEntry")[0];

						iId = parseInt(oIdElem.firstChild.data);
						sName = oNameElem.firstChild.data;
						sCode = oCodeElem.firstChild.data;
						bAllowOther = oAllowOtherElem.firstChild.data.toLowerCase() == "true" ? true : false;

						oNewCountry = new EBGCountry(iId, sName, sCode, bAllowOther);
						iNewLength = oSelector.aCountryList.push(oNewCountry);
						oSelector.aCountryIDIndex[iId] = iNewLength-1;
					}
				} else {
					alert("Cannot load country list! No XML document found!");
				}

                oSelector.createHtml();
				oSelector.onCountriesRefreshedFunction();				
			}
		}

        httpRequest.send(sPostData);
	} else {

    	alert("Cannot load country list! Cannot open connection to webservice to get countries!");

    	this.onCountriesRefreshedFunction();
		this.createHtml();
	}
}

EBGCountryProvinceSelector.prototype.loadProvinces = function(iCountryId){
	var oCountry = this.aCountryList[this.aCountryIDIndex[iCountryId]];
	var oSelector = this;
	if ( !oCountry )
	{
		return;
	}
	var sPostData = "request_type=province_list&country_id="+iCountryId;

	//Open http request
	this.httpRequest = getHTTPObject();
	if ( this.httpRequest )
	{
		//Get results and parse
		this.httpRequest.open("POST", this.sWebserviceUrl, true);
		this.httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		this.httpRequest.onreadystatechange = function(){
			
			if ( oSelector.httpRequest.readyState == 4)
			{
				var xmlDoc = oSelector.httpRequest.responseXML;
				if ( xmlDoc )
				{
					oCountry.removeAllProvinces();

					var dataElement = xmlDoc.getElementsByTagName("Data")[0];
					var aCountryElements = dataElement.getElementsByTagName("Province");
					var i = 0, iNewLength = 0;
					var oIdElem, oNameElem, oCodeElem, oAbbrElem;
					var iId, sName, sCode, sAbbreviation;
					for ( i = 0; i < aCountryElements.length; i++)
					{
						oIdElem = aCountryElements[i].getElementsByTagName("ID")[0];
						oNameElem = aCountryElements[i].getElementsByTagName("Name")[0];
						oCodeElem = aCountryElements[i].getElementsByTagName("Code")[0];
						oAbbrElem = aCountryElements[i].getElementsByTagName("Abbreviation")[0];

						iId = parseInt(oIdElem.firstChild.data);
						sName = oNameElem.firstChild.data;
						sCode = oCodeElem.firstChild.data;
						sAbbreviation = oAbbrElem.firstChild ? oAbbrElem.firstChild.data : "";

						oCountry.addProvince(iId, sName, sCode, sAbbreviation)
					}
				}
				else {
					alert("Cannot load province list! No XML document found!");
				}
				oSelector.createProvinceHtml();
				oSelector.onProvincesRefreshedFunction(iCountryId);
			}
		};
		this.httpRequest.send(sPostData);
	}
	else {
		alert("Cannot load province list! Cannot open connection to webservice to get provinces!");
		this.onProvincesRefreshedFunction(iCountryId);
	}
}

//This is an internally called function when the country dropdown selected option
//is changed by a user clicking a different item
EBGCountryProvinceSelector.prototype.changeSelectedCountry = function (iCountryId){
    if ( iCountryId == -1 ){
        this.iSelectedCountryId = iCountryId;
        this.createProvinceHtml(); 
        
        this.showOtherCountryField(true);  
    }
    else {
        oCountry = this.aCountryList[this.aCountryIDIndex[iCountryId]];
    
        if ( oCountry ){
            var iOldSelectedCountryId = this.iSelectedCountryId;
            this.iSelectedCountryId = iCountryId;
            if ( iOldSelectedCountryId != iCountryId ){
                if ( oCountry.getProvinceCount() == 0 ){
                    this.loadProvinces(iCountryId);
                }
                else {
                    this.createProvinceHtml();
                }
            }
            //this.callOnCountryChanged(iCountryId)
        }
        else {
            this.iSelectedCountryId = 0;
            this.createProvinceHtml();
        }
        this.showOtherCountryField(false);
    }
}

//This is an internally called function when the province dropdown selected option
//is changed by a user clicking a different item
EBGCountryProvinceSelector.prototype.changeSelectedProvince = function(iProvinceId) {
    this.iSelectedProvinceId = iProvinceId;
    this.showOtherProvinceField(iProvinceId == -1 ? true : false);
    //this.callOnProvinceChanged(iProvinceId);
}
//Call this to change country/province id programmatically
EBGCountryProvinceSelector.prototype.setCountryAndProvince = function(iCountryId, iProvinceId){
	var oCountryDropdown = document.getElementById(this.sCountrySelectName);
	oCountryDropdown.value = iCountryId;
	this.changeSelectedProvince(iProvinceId);
	this.changeSelectedCountry(iCountryId);
	
	var oProvinceDropdown = document.getElementById(this.sProvinceSelectName);
	if ( oProvinceDropdown )
		oProvinceDropdown.value = iProvinceId;
}

EBGCountryProvinceSelector.prototype.showOtherCountryField = function(bShow){
    oOtherDiv = document.getElementById("OtherCountryDisplay_"+this.sCountrySelectName);
    if ( oOtherDiv ){
        if ( bShow ) {
            oOtherDiv.style.display = "block";
        }
        else{
            oOtherDiv.style.display = "none";
        }
    }
}

EBGCountryProvinceSelector.prototype.showOtherProvinceField = function(bShow){
    oOtherDiv = document.getElementById("OtherProvinceDisplay_"+this.sProvinceSelectName);
    if ( oOtherDiv ){
        if ( bShow ) {
            oOtherDiv.style.display = "block";
        }
        else{
            oOtherDiv.style.display = "none";
        }
    }
}

EBGCountryProvinceSelector.changeCountry = function(event){
    var oCountryDropdown = getEventTarget(event);
    var oCPSelector = oCountryDropdown.oCountryProvinceSelector;
    
    if ( oCPSelector ) {
		oCPSelector.iSelectedProvinceId = 0;
        oCPSelector.changeSelectedCountry(oCountryDropdown.value);
    }
}

EBGCountryProvinceSelector.changeProvince = function(event){
    var oProvinceDropdown = getEventTarget(event);
    var oCPSelector = oProvinceDropdown.oCountryProvinceSelector;
    
    if ( oCPSelector ) {
        oCPSelector.changeSelectedProvince(oProvinceDropdown.value);
    }
}