/**
 * 
 * @param {String} ddlRegionsID ID of the regions drop down list
 * @param {String} ddlLocationsID ID of the locations drop down list
 * @param {String} hdnLocationID ID of the hidden field that stores the active location ID
 * @param {String} locationsData The JSON object/array representing locations nested within regions
 * @param {Bool} locationsDisabled True if location choice is disabled False otherwise
 * @param {Bool} locationsPostback True if you would like a postback event to occur when the location selection is changed
 * @constructor 
 * the region form field should have an option at the top with a value of -1
 */
function LocationPicker(ddlRegionsID, ddlLocationsID, hdnLocationID, locationsData, locationsDisabled, locationsPostback, locationPickerClientName)
{    
    this._ddlRegions = null;
    this._ddlLocations = null;
    this._hdnLocations = null;
    this._locationsData = locationsData;
    this._locationsDisabled = locationsDisabled;
    this._locationsPostback = locationsPostback;
    this._locationPickerClientName = locationPickerClientName;
    this.Init(ddlRegionsID, ddlLocationsID, hdnLocationID);
}


/**
 * Initialises the object - and related HTML elements
 * 
 * @param {String} ddlRegionsID ID of the regions drop down.
 * @param {String} ddlLocationsID ID of the locations drop down.
 * @param {String} hdnLocationID ID of the hidden field that stores the active location ID 
 */
LocationPicker.prototype.Init = function(ddlRegionsID, ddlLocationsID, hdnLocationID)
{
    // Store regions and locations drop downs
    this._ddlRegions = $(ddlRegionsID);
    this._ddlLocations = $(ddlLocationsID);
    this._hdnLocations = $(hdnLocationID);
    
    this.UpdateLocations();   
    
    if(this._locationsDisabled)
        this._ddlLocations.disabled = true;
    this.InitEvents();
}


/**
 * Attaches events to the HTML elements that require them. 
 */
LocationPicker.prototype.InitEvents = function()
{
    $(this._ddlRegions).addEvent('change', this.RegionChanged.bind(this));
    $(this._ddlLocations).addEvent('change', this.LocationChanged.bind(this));
}


/**
 * Called when the region has been changed in the HTML select element
 */
LocationPicker.prototype.RegionChanged = function()
{
    this.UpdateLocations();
    this.LocationChanged();
}


/**
 * Called when the location has been changed in the HTML select element 
 */
LocationPicker.prototype.LocationChanged = function()
{
    this.UpdateSelectedLocationValue();
    if(this._locationsPostback)
    {
        __doPostBack(this._locationPickerClientName,'loc_'+this._ddlLocations[(this._ddlLocations.selectedIndex) || 0].value);
    }
}


/**
 * Updates locations based on the selected region and will check to see
 * if a location in that list is supposed to be set to active. 
 */
LocationPicker.prototype.UpdateLocations = function()
{
    var regionID = this._ddlRegions.options[this._ddlRegions.selectedIndex].value;
    var allowedLocations = this._locationsData[regionID];

    while(this._ddlLocations.options.length > 0)
        this._ddlLocations.options[0] = null;
        
    var count = 0;
    $each(allowedLocations, (function(value, key) {
     
        this._ddlLocations.options[count] = new Option(value, key); count++; 
        
        }).bind(this));
        
    this.SetSelectedLocation();
    this.UpdateSelectedLocationValue();
}


/**
 * Will store the selected value (location id) from the select element in the hidden field (selected location field) 
 */
LocationPicker.prototype.UpdateSelectedLocationValue = function()
{
    this._hdnLocations.value = this._ddlLocations[(this._ddlLocations.selectedIndex) || 0].value;
}


/**
 * Sets the selected location on the drop down to the value stored in the hidden field
 * if the location exists within the drop down.
 */
LocationPicker.prototype.SetSelectedLocation = function()
{
    var locationId = parseInt(this._hdnLocations.value);
    if(!isNaN(locationId))
    {
        for(index = 0; index < this._ddlLocations.options.length; index++)
        {
            opt = this._ddlLocations[index];
            if(locationId == opt.value)
            {
                this._ddlLocations[index].selected = true;
                this._ddlLocations.selectedIndex = index;
                
            }
        }
    }
}
