function xmlhttpPost(strURL, queryString, resultFunc)
{
    var xmlHttpReq = false;
    var self = this;
    
    // Mozilla/Safari
    if (window.XMLHttpRequest)
    {
        self.xmlHttpReq = new XMLHttpRequest();
    }
    // IE
    else if (window.ActiveXObject)
    {
        self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    self.xmlHttpReq.open('POST', strURL, true);
    self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    
    self.xmlHttpReq.onreadystatechange = function()
    {
        if (self.xmlHttpReq.readyState == 4)
        {
        	resultFunc( PHP_Unserialize(self.xmlHttpReq.responseText) );
        }
    }
    self.xmlHttpReq.send(queryString);
}

/**
* Unserializes a PHP serialized data type.
*
* @param  string input The serialized PHP data
* @return mixed        The resulting datatype
*/
function PHP_Unserialize(input)
{
    var result = PHP_Unserialize_(input);
    
    return result[0];
}


/**
* Function which performs the actual unserializing
*
* @param string input Input to parse
*/
function PHP_Unserialize_(input)
{
    var length = 0;
    
    switch (input.charAt(0)) {
    	
        /* Array */
        case 'a':

            length = PHP_Unserialize_GetLength(input);
            input  = input.substr(String(length).length + 4);

            var arr   = new Array();
            var key   = null;
            var value = null;
			
            for (var i=0; i<length; ++i) {
                key   = PHP_Unserialize_(input);
                input = key[1];

                value = PHP_Unserialize_(input);
                input = value[1];

                arr[key[0]] = value[0];
            }

            input = input.substr(1);
            
            return [arr, input];

            break;
        
        /* Objects */
        case 'O':

            length = PHP_Unserialize_GetLength(input);
            var classname = String(input.substr(String(length).length + 4, length));
            
            input  = input.substr(String(length).length + 6 + length);
            var numProperties = Number(input.substring(0, input.indexOf(':')))
            input = input.substr(String(numProperties).length + 2);

            var obj      = new Object();
            var property = null;
            var value    = null;

            for (var i=0; i<numProperties; ++i) {
                key   = PHP_Unserialize_(input);
                input = key[1];
                
                // Handle private/protected
                key[0] = key[0].replace(new RegExp('^\x00' + classname + '\x00'), '');
                key[0] = key[0].replace(new RegExp('^\x00\\*\x00'), '');

                value = PHP_Unserialize_(input);
                input = value[1];

                obj[key[0]] = value[0];
            }

            input = input.substr(1);
            return [obj, input];
            break;


        /* Strings */
        case 's':
            length = PHP_Unserialize_GetLength(input);
            return [String(input.substr(String(length).length + 4, length)), input.substr(String(length).length + 6 + length)];

            break;

        /* Integers and doubles */
        case 'i':
        case 'd':
            var num = Number(input.substring(2, input.indexOf(';')));
            return [num, input.substr(String(num).length + 3)];

            break;
        
        /* Booleans */
        case 'b':
            var bool = (input.substr(2, 1) == 1);
            return [bool, input.substr(4)];
            break;
        
        /* Null */
        case 'N':
            return [null, input.substr(2)];
            break;

        /* Unsupported */
        case 'o':
        case 'r':
        case 'C':
        case 'R':
        case 'U':
//            alert('Error: Unsupported PHP data type found!');

        /* Error */
        default:
            return [null, null];
            break;

    }
}


/**
* Returns length of strings/arrays etc
*
* @param string input Input to parse
*/
function PHP_Unserialize_GetLength(input)
{
    input = input.substring(2);

    var length = Number(input.substr(0, input.indexOf(':')));

    return length;
}


/*
 * Get the states for a certain country
 */
function updateStates(selectedState)
{
	// Use 'address_country' to avoid conflicts with country meta tag
	countrySelect = document.getElementById('address_country');
	stateField = document.getElementById('state');
	
	var country = countrySelect.value;

	// Change state field from text field to dropdown. It starts as a text field
	// to support browsers without javascript
	stateParent = stateField.parentNode;
	
	stateSelect = document.createElement( 'select' );
	stateSelect.setAttribute( "id", 'state' );
	stateSelect.setAttribute( "name", 'billing[state]' );
	
	stateParent.replaceChild( stateSelect, stateField )
	
	// Clear all existing options and disable while loading
	stateSelect.options.length = 0;
	stateSelect.disabled=true;
	
	if ( country )
	{
		// Display "Loading" until it gets overwritten with real data
		stateSelect.options[0] = new Option('-- Loading --', '');
		
		// Create a function to handle the ajax response
		var setStates = function (responseArray)
		{
		    // Enable the state dropdown box
			if ( responseArray.length > 0 )
			{
				stateSelect.disabled=false;

				var optCnt = 0;
				
				// Only display "Please select" if there is more than one option
				if (responseArray.length > 1)
				{
					stateSelect.options[optCnt] = new Option('-- Please Select --', '');
					optCnt++;
				}
				
				for (i in responseArray)
				{
					var stateID		= responseArray[i]['value'];
					var stateName	= responseArray[i]['name'];
					
					// Add this state as an option to the dropdown box
					stateSelect.options[optCnt] = new Option(stateName, stateName);
					
					// Mark as selcted if this state matches the selcted state value
					if (stateName == selectedState)
					{
						stateSelect.options[optCnt].selected = true;
					}
					
					optCnt++;
			    }
			}
			else
			{
				// Country doesn't contain any states
				stateSelect.options[0] = new Option('[State Not Required]', 'none');
			}
		}
		
		// Send the states request to the server
		xmlhttpPost("/hs_shared/ajax/", "module=country&event=getStates&country="+country, setStates );
	}
}
