var oldPostBackFn;

// These two variables are used to store the iframe height and width when RM is framed on a web site.
var iFrameHeight = 0;
var iFrameWidth = 0;

// We're adding this new BrowserDetect object so that we can detect in the javascript which
// browser the client is using.
var BrowserDetect = {
    init: function() {
        this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
        this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
        this.OS = this.searchString(this.dataOS) || "an unknown OS";
    },
    searchString: function(data) {
        for (var i = 0; i < data.length; i++) {
            var dataString = data[i].string;
            var dataProp = data[i].prop;
            this.versionSearchString = data[i].versionSearch || data[i].identity;
            if (dataString) {
                if (dataString.indexOf(data[i].subString) != -1)
                    return data[i].identity;
            }
            else if (dataProp)
                return data[i].identity;
        }
    },
    searchVersion: function(dataString) {
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1) return;
        return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
    },
    dataBrowser: [
		{
		    string: navigator.userAgent,
		    subString: "Chrome",
		    identity: "Chrome"
		},
		{ string: navigator.userAgent,
		    subString: "OmniWeb",
		    versionSearch: "OmniWeb/",
		    identity: "OmniWeb"
		},
		{
		    string: navigator.vendor,
		    subString: "Apple",
		    identity: "Safari",
		    versionSearch: "Version"
		},
		{
		    prop: window.opera,
		    identity: "Opera"
		},
		{
		    string: navigator.vendor,
		    subString: "iCab",
		    identity: "iCab"
		},
		{
		    string: navigator.vendor,
		    subString: "KDE",
		    identity: "Konqueror"
		},
		{
		    string: navigator.userAgent,
		    subString: "Firefox",
		    identity: "Firefox"
		},
		{
		    string: navigator.vendor,
		    subString: "Camino",
		    identity: "Camino"
		},
		{		// for newer Netscapes (6+)
		    string: navigator.userAgent,
		    subString: "Netscape",
		    identity: "Netscape"
		},
		{
		    string: navigator.userAgent,
		    subString: "MSIE",
		    identity: "Explorer",
		    versionSearch: "MSIE"
		},
		{
		    string: navigator.userAgent,
		    subString: "Gecko",
		    identity: "Mozilla",
		    versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
		    string: navigator.userAgent,
		    subString: "Mozilla",
		    identity: "Netscape",
		    versionSearch: "Mozilla"
		}
	],
    dataOS: [
		{
		    string: navigator.platform,
		    subString: "Win",
		    identity: "Windows"
		},
		{
		    string: navigator.platform,
		    subString: "Mac",
		    identity: "Mac"
		},
		{
		    string: navigator.userAgent,
		    subString: "iPhone",
		    identity: "iPhone/iPod"
		},
		{
		    string: navigator.platform,
		    subString: "Linux",
		    identity: "Linux"
		}
	]
};
BrowserDetect.init();

///////////////////////////////////////
/// This method is called from the car search results grids (parent
/// and child) in the onload event for each image.  If we are then in
/// CBE mode and the setPageHeight function is defined it calls that
/// function.  This is needed so that when the CBE is framed on a
/// customers web site the frame will be resized as each image loads
/// (which happens after the DOM is reloaded as the image gets served
/// from the external web site).
///////////////////////////////////////
function setPageHeightIfApplicable()
{
    if (typeof (setPageHeight) != "undefined")
        setPageHeight();
}

///////////////////////////////////////
/// This method checks the validators and then calls the .NET postback method
/// and then calls enableUI with false to disable the UI including disabling the controls themselves if this is a normal postback.
/// NOTE: this method is only invoked for a normal .NET postback not
/// an UpdatePanel based postback. Instead we hook into the beginRequest
/// event handler for UpdatePanel based postbacks
///////////////////////////////////////
function postBackDisableControls(eventTarget, eventArgument, isLowPriority)
{
    postbackFiredAlready = true;
    if (typeof (ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
    
    //When partial page rendering is disabled Sys.WebForms will be undefined
    if (typeof (Sys.WebForms) == "undefined" ||
        ! Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
    {
        mLowPriorityPostback = (isLowPriority == true);
        oldPostBackFn(eventTarget, eventArgument);
        enableUI(false, mLowPriorityPostback);
    }
}



function handleMouseClickDuringPostback(event) {
    alert('Please wait, a request is currently being processed.');
}


//Create global member variables
var mPostbackBackgroundDiv = document.createElement('div');
mPostbackBackgroundDiv.style.position = 'fixed';
mPostbackBackgroundDiv.style.zIndex = 10000; //Set the z-index to an aribrarily high number to ensure the Div tag appears topmost
mPostbackBackgroundDiv.className = 'postbackBackground';
//If the user initiates a postback or one is being done automatically by an async message watcher we want to
//ensure the user doesn't interrupt that postback and that they know why
mPostbackBackgroundDiv.onclick = handleMouseClickDuringPostback;

var mDisabledControls = null;
var mLowPriorityPostback = false;
var postbackFiredAlready = false;


///////////////////////////////////////
// pageLoad is automatically called by the AJAX framework when the
// page is first loaded. We hook up some event handlers to deal
// with disabling the UI during an UpdatePanel postback
///////////////////////////////////////
function pageLoad()
{
    //When partial page rendering is disabled Sys.WebForms will be undefined
    if( typeof( Sys.WebForms ) != "undefined" )
    {
        var lManager = Sys.WebForms.PageRequestManager.getInstance();
        lManager.remove_endRequest( onEndRequest ); //Remove in case was added on previous Async postback
        lManager.add_endRequest( onEndRequest );
        lManager.remove_pageLoading( onPageLoading );
        lManager.add_pageLoading(onPageLoading);
    }
}


function pageUnload()
{
    breakCircularReferences(document);
}


///////////////////////////////////////
// Once the update is complete but before the page has been updated
// re-enable the UI so that if any controls were disabled server-side
// as a result of this postback we don't inapproprately re-enable 
// them which is what would happen if enableControls was called in
// onEndRequest
///////////////////////////////////////
function onPageLoading(sender, args)
{
    enableControls();

    postbackFiredAlready = false;

    var lPanels = args.get_panelsUpdating();
    for (var i = 0; i < lPanels.length; i++)
        breakCircularReferences(lPanels[i]);

    lPanels = args.get_panelsDeleting();
    for (var i = 0; i < lPanels.length; i++)
        breakCircularReferences(lPanels[i]);
}

///////////////////////////////////////
// Removes functions attached to an element and its children, as the
// functions will likely contain circular 'this' references to the
// elements, and cause memory leaks when removed during a partial
// update
///////////////////////////////////////
function breakCircularReferences(d)
{
    // Run the dispose() script for everything that has one
    if (d.dispose) {
        d.dispose();
        d.dispose = null;
    }

    // Null any .Net validators - I
    if (d.evaluationfunction)
        d.evaluationfunction = null;

    // Null any .Net validators - II
    var a = d.Validators, i, l, n;
    if (a) {
        for (var n in d) {
            if (typeof d[n] === 'function' || n === 'Validators') {
                d[n] = null;
            }
        }
    }
    
    // Recurse through child control tree
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            breakCircularReferences(d.childNodes[i]);
        }
    }
}

///////////////////////////////////////
// Once the update is complete and the page has been updated
// remove the transparent Div so that the hourglass disappears and
// mouse clicks are passed to the controls. Also handle any server
// side errors that occured during the asynch postback by displaying
// the error in an alert box and then re-enabling the controls
///////////////////////////////////////
function onEndRequest(sender, args) 
{
    enableUI( true, false );
    postbackFiredAlready = false;
    
    if( args.get_error() != undefined )
    {
       args.set_errorHandled( true ); //Set to true so AJAX framework does not through client side exception
       alert( args.get_error().message );
       enableControls(); //Need to call enableControls because onPageLoading does not get called in an error situation
    }
}

///////////////////////////////////////
// enableUI is used to disable all controls when a postback takes place
// it does so by displaying a transparent Div over the the whole form
// with an hourglass mouse pointer and it then disables all of the controls if hourGlassOnly is false.
// The reason for disabling the controls is that under IE6 dropdown lists
// do not get covered by the div tag so have to be disabled so for consistency
// we disable the others.
///////////////////////////////////////
function enableUI( state, hourGlassOnly ) 
{
    if ( ! state )
    {
        //Append the dynamic Div tag to the body of the HTML and set it to position 0, 0
        //Note: We do not do this in the pageLoad function because if that gets invoked
        //before the DOM is complete (e.g. the </body> tag has been processed) you get
        //an error in IE "Internet Explorer cannot open the Internet site...Operation aborted"
        //This is particularly noticeable on a slow machine
        document.body.appendChild(mPostbackBackgroundDiv);
        Sys.UI.DomElement.setLocation( mPostbackBackgroundDiv, 0, 0 );

        mPostbackBackgroundDiv.style.cursor = 'wait';
        mPostbackBackgroundDiv.style.display = '';
        
        mPostbackBackgroundDiv.style.width = 
           document.body.scrollWidth - 20 +'px';
        mPostbackBackgroundDiv.style.height =
           document.body.scrollHeight - 20 +'px';

        if (! hourGlassOnly )
            disableControls();
    }
    else {
        mPostbackBackgroundDiv.style.cursor = 'default'; //Set the cursor back to default because just hiding the DIV doesn't seem to do so until you move the mouse
        mPostbackBackgroundDiv.style.display = 'none';
    }
}

///////////////////////////////////////
// disables all controls on form for UpdatePanel postback and cache IDs of those that have been disabled
///////////////////////////////////////
function disableControls()
{
    //If mDisabledControls is not null then we have already disabled the controls on this postback
    //so in case disableControls gets called twice we don't want to disable all controls again  
    //as they will all get cached as being disabled the second time around
    if( mDisabledControls == null )
    {
        mDisabledControls = new Array();
        disableTagControlsForUpdate( "INPUT" );
	    disableTagControlsForUpdate( "SELECT" );
	    disableTagControlsForUpdate( "A" );
    }
}

///////////////////////////////////////
// enable all controls on form after UpdatePanel postback based on cached IDs of those that were previously disabled
///////////////////////////////////////
function enableControls()
{
    if( mDisabledControls != null )
    {
        enableTagControlsAfterUpdate( "INPUT" );
	    enableTagControlsAfterUpdate( "SELECT" );
	    enableTagControlsAfterUpdate( "A" );
	    mDisabledControls = null;
    }
}

///////////////////////////////////////
// disables all controls of a particular tag type on form for UpdatePanel postback and cache IDs of those that have been disabled
///////////////////////////////////////
function disableTagControlsForUpdate( tagName )
{
    
    var lTagColl = document.getElementsByTagName( tagName );
    if( lTagColl != null )
    {
	    for( var lIndex = 0; lIndex < lTagColl.length; lIndex++ )
	    {
	        if( lTagColl[ lIndex ].type != 'hidden' )
	        {
	            if( lTagColl[ lIndex ].disabled )
	                mDisabledControls.push( lTagColl[ lIndex ].outerHTML );
    	    
	            lTagColl[ lIndex ].disabled = true;
		        lTagColl[ lIndex ].style.cursor ='wait';
		    }
	    }
    }
}

///////////////////////////////////////
// enable all controls of a particular tag type on form after UpdatePanel postback based on cached IDs of those that were previously disabled
///////////////////////////////////////
function enableTagControlsAfterUpdate( tagName )
{
    var lTagColl = document.getElementsByTagName( tagName );
    if( lTagColl != null )
    {
	    for( var lIndex = 0; lIndex < lTagColl.length; lIndex++ )
	    {
	        if( lTagColl[ lIndex ].type != 'hidden' )
	        {
	            if( Array.indexOf( mDisabledControls, lTagColl[ lIndex ].outerHTML ) == -1 )  
	                lTagColl[ lIndex ].disabled = false;
    		        
		        lTagColl[ lIndex ].style.cursor =''; //Restore the cursor to whatever it should be by default
		    }
	    }
    }
}

///////////////////////////////////////
// This is a utility method derived classes can use
// to disable specific dropdown list controls
///////////////////////////////////////
function disableSingleDropDownControl( dropDownControl )
{
	if( dropDownControl != null )
		dropDownControl.disabled = true;
}

//////////////////////////////////////////
// Filter out < and > keys which are not allowed to normally be posted under asp.net
//////////////////////////////////////////
function FilterKeys(){
	if (document.all){
		if ((event.keyCode == 188 || event.keyCode == 190) && event.shiftKey)
		{
			event.returnValue=false;
			event.cancel = true;
			event.cancelBubble = true;			
		}
	}
}

//////////////////////////////////////////
// Tries to set the __LASTFOCUS hidden element to the id value provided
//////////////////////////////////////////
function GetFocus( id )
{
    try
    {
        document.getElementById('__LASTFOCUS').value = id;
    } catch(e) {}
}

var Page_ClientValidate_Old;

//////////////////////////////////////////
// Place initialisation calls here that should be invoked in the onload event of the page
//////////////////////////////////////////
function FormBaseInit()
{
    //Hijack .NET __doPostBack method
    if (typeof (__doPostBack) != "undefined" && __doPostBack.toString() != postBackDisableControls.toString())
    {
        if (typeof (oldPostBackFn) == "undefined")
            oldPostBackFn = __doPostBack;
            
        __doPostBack = postBackDisableControls;
    }
    
    //Hijack ASP.NET's Page_ClientValidate to invoke our own
    if (typeof(Page_ClientValidate) != "undefined")
    {
	    Page_ClientValidate_Old = Page_ClientValidate;
	    Page_ClientValidate = Page_ClientValidate_Custom; //Hijack .NET's Page_ClientValidate method to call our own
    }
    
    //Hijack ASP.NET's WebForm_FireDefaultButton to invoke our own
    if( typeof( WebForm_FireDefaultButton ) != "undefined"
        && mWebForm_FireDefaultButton == null ) //If we have already hijacked it we don't want to do so again or we will be hijacking ourself!
    {
        mWebForm_FireDefaultButton = WebForm_FireDefaultButton;
        WebForm_FireDefaultButton = WebForm_FireDefaultButtonWithExclusions;
    }
}

//////////////////////////////////////////
//We replace the .NET Page_ClientValidate script with our own to handle the fact that
//by default a control that causes validation can only validate controls in the
//same validationGroup as that control or all controls on the form that are not part
//of a validationGroup (in which case the validationGroup with be ""). In our case
//we want to associate controls to different validation summaries so that their errors
//appear logically under the controls that are invalid. However, we want to invoke
//validation across all validation summaries every time so that if there are multiple
//errors related to multiple update panels these will be displayed.
//////////////////////////////////////////
function Page_ClientValidate_Custom(validationGroup)
{
	if (typeof(Page_Validators) == "undefined" || typeof(Page_ValidationSummaries) == "undefined")
		return true;

	// loop through all validators on the page to check for any with errors
	for (var j = 0; j < Page_Validators.length; j++)
		ValidatorValidate(Page_Validators[j], Page_Validators[j].validationGroup, null);

	ValidatorUpdateIsValid(); //This will set Page_IsValid to false if any validators are invalid

	ValidationSummaryOnSubmit_Init(); //Initialise all validator summaries to be blank and hidden
	
	if( ! Page_IsValid )
	{
	    ValidationSummaryOnSubmit_Custom(""); //Our custom version will display all summaries on the page if their controls have errors
	}

	// If the setPageHeight function is defined then we are being framed and we need to pass the
	// new height of the page to the containing frame.  This should be done for a successful or
	// unsuccessful validation because we could be showing or hiding error messages without moving
	// to a new page.
	if (typeof (setPageHeight) != "undefined")
	    setPageHeight();

	Page_BlockSubmit = !Page_IsValid;
	return Page_IsValid;
}
//////////////////////////////////////////
//Function to hide all validation summaries
//////////////////////////////////////////
function ValidationSummaryOnSubmit_Init()
{
	if (typeof(Page_ValidationSummaries) == "undefined")
		return;

	for (var sums = 0; sums < Page_ValidationSummaries.length; sums++)
	{
		Page_ValidationSummaries[sums].style.display = "none";
		Page_ValidationSummaries[sums].innerHTML = "";
	}
}
//////////////////////////////////////////
//We call our own ValidationSummaryOnSubmit_Custom rather than
//.NET's validator ValidationSummaryOnSubmit because the latter
//hides all other validation summaries on the page and we want
//to display all validation summaries that relate to controls
//that have errors
//////////////////////////////////////////
function ValidationSummaryOnSubmit_Custom(validationGroup) {
    if (typeof(Page_ValidationSummaries) == "undefined")
        return;
    var summary, sums, s;
    for (sums = 0; sums < Page_ValidationSummaries.length; sums++) {
        summary = Page_ValidationSummaries[sums];
        //summary.style.display = "none"; //Change = Commenting out .NET code that hides validation summaries as we do this separately in ValidationSummaryOnSubmit_Init
        //if (!Page_IsValid && IsValidationGroupMatch(summary, validationGroup)) { //Change = Commenting out .NET code that only displays the validation summary identified by validationGroup and replacing with the line below as we want to display all validation summaries
        if (!Page_IsValid) { //Change = line replacing above
            var i;
            if (summary.showsummary != "False") {
                //summary.style.display = ""; //Change = Commenting out this line to move it to the if( errors ) block below because it seemed to result in the display of a blank line for invisible validation summaries 
                if (typeof(summary.displaymode) != "string") {
                    summary.displaymode = "BulletList";
                }
                switch (summary.displaymode) {
                    case "List":
                        headerSep = "<br/>";
                        first = "";
                        pre = "";
                        post = "<br/>";
                        end = "";
                        break;
                    case "BulletList":
                    default:
                        headerSep = "";
                        first = "<ul>";
                        pre = "<li>";
                        post = "</li>";
                        end = "</ul>";
                        break;
                    case "SingleParagraph":
                        headerSep = " ";
                        first = "";
                        pre = "";
                        post = " ";
                        end = "<br/>";
                        break;
                }
                s = "";
                if (typeof(summary.headertext) == "string") {
                    s += summary.headertext + headerSep;
                }
                s += first;
                var errors = false; //Change = Adding a variable to track whether there are any errors
                for (i=0; i<Page_Validators.length; i++) {
                    //if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") { //Change = Replace .NET if statement with the one below so that the error message is only displayed under the validation summary it relates to
                    if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string" && IsValidationGroupMatch_Custom(Page_Validators[i], summary.validationGroup)) { //Change = replacing the line above
                        s += pre + Page_Validators[i].errormessage + post;
                        errors = true; //Change = Set our new variable to true if there are any errors in this validation summary
                    }
                }
                s += end;
                if( errors ) { //Change = only add the error summary if there are actually any errors
                    summary.innerHTML = s;
                    summary.style.display = ""; //Change = moving this statement here rather than immediately following if (!Page_IsValid... above
                    //window.scrollTo(0,0); //Change = Commenting out .NETs behaviour of scrolling to the top of the page so that we only scroll to the source of the first error
                } //Change = closing brace for if( errors )
            }
            //Change = the showmessagebox style of summary has not been tested with our custom method so it would probably need tweaking to work properly
            if (summary.showmessagebox == "True") {
                s = "";
                if (typeof(summary.headertext) == "string") {
                    s += summary.headertext + "\r\n";
                }
                var lastValIndex = Page_Validators.length - 1;
                for (i=0; i<=lastValIndex; i++) {
                    if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") {
                        switch (summary.displaymode) {
                            case "List":
                                s += Page_Validators[i].errormessage;
                                if (i < lastValIndex) {
                                    s += "\r\n";
                                }
                                break;
                            case "BulletList":
                            default:
                                s += "- " + Page_Validators[i].errormessage;
                                if (i < lastValIndex) {
                                    s += "\r\n";
                                }
                                break;
                            case "SingleParagraph":
                                s += Page_Validators[i].errormessage + " ";
                                break;
                        }
                    }
                }
                alert(s);
            }
        }
    }
}
//////////////////////////////////////////
//We call our own IsValidationGroupMatch_Custom because we iterate over all
//validation summaries in ValidationSummaryOnSubmit_Custom so we only want
//to copy errors for controls to the validation summary related to those
//controls. So we consider a match when both the validation summary and
//the control have no validation group set or they have the same
//validation group. The problem with .NET 3.5's IsValidationGroupMatch
//is that it considers them a match if the summary's gropu is undefined
//regardless of whether the control has validationGroup specified or not
//////////////////////////////////////////
function IsValidationGroupMatch_Custom(control, validationGroup) {
    var calcedValidationGroup = "";
    if ((typeof(validationGroup) != "undefined") && (validationGroup != null)) {
        calcedValidationGroup = validationGroup;
    }
    var controlGroup = "";
    if (typeof(control.validationGroup) == "string") {
        controlGroup = control.validationGroup;
    }
    return (controlGroup == calcedValidationGroup);
}

//////////////////////////////////////////
//  Enables or Disables a validator.  This function will maintain a list of validators thats been disabled
//  client side so that they can be disabled on server for the postback
//////////////////////////////////////////
function EnableValidator(validator, enable)
{
    ValidatorEnable(validator, enable);

    // Get the hidden input to keep the list of disabled validators
    var disabledValidatorList = document.getElementById('__disabledValidatorList');
    // create if not exist
    if (disabledValidatorList == null)
    {
        disabledValidatorList = document.createElement('input');
        disabledValidatorList.setAttribute('type', 'hidden');
        // NOTE: the value of this element is retrieved in FormBase.cs and
        // uses the control name below to retrieve it from the Request.Form.  So
        // do not change the name without making the corresponding change in FormBase.cs -> SetValidatorsDisabledClientSide
        disabledValidatorList.setAttribute('name', '__disabledValidatorList');
        disabledValidatorList.setAttribute('id', '__disabledValidatorList');
        // document.body.firstChild.firstChild maps to the first div in the asp.net form.
        // This div also contains the viewstate and other hidden inputs.
        document.body.firstChild.firstChild.appendChild(disabledValidatorList);
    }

    if (enable)
    {
        // If enabling the validator, remove it from the list
        disabledValidatorList.value = disabledValidatorList.value.replace(validator.id + ';','');
    } 
    else
    {
        // if disabling the validator add it to the list if it doesnt exist
        if (disabledValidatorList.value.indexOf(validator.id + ';') < 0)
            disabledValidatorList.value += validator.id + ';';
    }
}

//////////////////////////////////////////
//  Enables or Disables all validators for the specified controlId
//////////////////////////////////////////
function EnableValidatorsForControlId(controlId, enable)
{
    for (val in Page_Validators)
        if (Page_Validators[val].controltovalidate == controlId)
            EnableValidator(Page_Validators[val], enable);
}

function EnableValidatorsForControls(controls,enable)
{
    // now go through all the controls we have to
    for (control in controls)
        EnableValidatorsForControlId(controls[control].id, enable);
}




//////////////////////////////////////////
// Scrolls specified object into view
//////////////////////////////////////////
function scrollToObject(objectId, onlyIfNotAlreadyScrolled)
{
	// if required, check that user has not already scrolled vertically.
	if (onlyIfNotAlreadyScrolled && document.body.scrollTop > 0)
	{
		return;
	}
	
	// When Partial Page rendering is disabled (in which case Sys.WebForms will be 
	// undefined, .NET tries to restore the scroll position 
	// following partial page updats via an UpdatePanel
	// so we need to set the _scrollPosition to prevent this behaviour when we
	// are explicitly scrolling to an objectd
	if( typeof( Sys.WebForms ) != "undefined" )
    {
	    var lManager = Sys.WebForms.PageRequestManager.getInstance();
        lManager._scrollPosition = null;
    }
        
	setTimeout("__scrollToObject('" + objectId + "');", 0);
}

function __scrollToObject(objectId)
{
	var lObjectToScrollTo = document.getElementById(objectId);
	if (lObjectToScrollTo != null)
	{
		lObjectToScrollTo.scrollIntoView(true);
	}
}


var mWebForm_FireDefaultButton;

///////////////////////////////////////
// Replace .NET's WebForm_FireDefaultButton with our own as .NET's will treat the ENTER key as having
// clicked the default button even if a link currently has the focus or a dropdown list is expanded and
// the user is just pressing enter to select the item from the dropdown list.
///////////////////////////////////////
function WebForm_FireDefaultButtonWithExclusions( event, target )
{
    if ((typeof (event.cancelBubble) == "undefined" || !event.cancelBubble) && (!event.srcElement || (event.srcElement.tagName.toLowerCase() != "a" && event.srcElement.tagName.toLowerCase() != "submit" && event.srcElement.tagName.toLowerCase() != "select")))
        return mWebForm_FireDefaultButton( event, target );
    else
        return true;
}

//Extracts the parameterName specified from the querystring
function getParameter(parameterName) {
    var queryString = window.location.search.substring(1).toLowerCase();
    //alert(queryString);
    var parameters = new Array();
    parameters = queryString.split('&');
    for (var i = 0; i < parameters.length; i++) {
        //alert(parameters[i]);
        //alert(parameters[i].indexOf(parameterName));
        if (parameters[i].indexOf(parameterName.toLowerCase()) >= 0) {
            //alert(parameters[i]);
            var parameterValue = new Array();
            parameterValue = parameters[i].split('=');
            return parameterValue[1];
        }
    }
    return "null";
}


//Map Method to handle the user finding a location on the map by adding a blue pushpin and
//panning the map to display all pushpins. If the find was unsuccessful this will display
//the VE error message returned
//Note: Any changes made to the VEShape added below need to be applied to teh VendorMapPanel.MapAllItems
//method as well and vice versa
function OnClientFindHandler(sender, args) {
    try {

        var mapEvent = args.get_MapEvent();
        if (mapEvent.Places.length > 1) {
            $get(sender.id.replace('_veMap', '_hdnMarkedSuccess')).value = "true";

            var txtLocationToMark = $get(sender.id.replace('_veMap', '_txtLocationToMark'));
            txtLocationToMark.value = mapEvent.Places[1].Name;

            var latlon = mapEvent.Places[1].LatLong;
            $get(sender.id.replace('_veMap', '_hdnMarkedLatitude')).value = latlon.Latitude;
            $get(sender.id.replace('_veMap', '_hdnMarkedLongitude')).value = latlon.Longitude;

            var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(latlon.Latitude, latlon.Longitude));
            shape.SetTitle("<div style='text-align:center'><b>Current Marked Location:</b></div>");
            shape.SetDescription("<div style='text-align:center'>" + txtLocationToMark.value + "</div>");
            shape.SetCustomIcon("<span class='MapPin MapPinBlue'/></span>");
            var map = $find(sender.id);
            map.AddShape(shape);
            var pointsArray = ShowBestMap(sender.id);
            //A bug in VE occurs if you mark the same location multiple times. Sporadically the call to
            //SetMapView does not actually work so we detect whether all pins are visible after the call
            //to ShowBestMap above and then call it again on a timer delay if it didn't work the first time
            if (pointsArray.length > 0) {
                var mapView = map.GetMapView();
                for (index = 0; index < pointsArray.length; index++) {
                    if (pointsArray[index].Latitude < mapView.BottomRightLatLong.Latitude
                        || pointsArray[index].Latitude > mapView.TopLeftLatLong.Latitude
                        || pointsArray[index].Longitude < mapView.TopLeftLatLong.Longitude
                        || pointsArray[index].Longitude > mapView.BottomRightLatLong.Longitude) {
                        window.setTimeout("ShowBestMap('" + sender.id + "');", 100);
                        break;
                    }
                }

            }
        }
        else if (mapEvent.VEErrorMessage != "") {
            $get(sender.id.replace('_veMap', '_hdnMarkedSuccess')).value = "false";
            $get(sender.id.replace('_veMap', '_lblMarkError')).innerText = mapEvent.VEErrorMessage;
            $get(sender.id.replace('_veMap', '_lblMarkError')).style.display = "block";
        }

    }
    catch (e) {

    }
}

//Pans the map specified by id parameter to display all pushpins
function ShowBestMap(id) {
    var map = $find(id);

    var numShapes = map.GetShapeLayerByIndex(0).GetShapeCount();
    if (numShapes > 0) {
        var pointsArray = new Array();
        for (index = 0; index < numShapes; index++) {
            var shape = map.GetShapeLayerByIndex(0).GetShapeByIndex(index);
            pointsArray.push(new VELatLong(shape.GetPoints()[0].Latitude, shape.GetPoints()[0].Longitude));
        }
        map.SetMapView(pointsArray);
    }

    return pointsArray;
}


//Opens new window containing DPDVendorDetails.aspx and returns false so that it can be used as OnClick handler
function openVendorDetailsForProductItinerary(searchResultID, productItineraryID) {

    window.open('DPDVendorDetails.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID, 'VendorDetails', 'width=750, height=550, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing DPDVendorDetails.aspx and returns false so that it can be used as OnClick handler
function openVendorDetailsForProductItineraryDetail(searchResultID, productItineraryID, productItineraryDetailID) {

    window.open('DPDVendorDetails.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID + '&amp;productItineraryDetailID=' + productItineraryDetailID, 'VendorDetails', 'width=750, height=550, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing AdditionalBookingInfo.aspx and returns false so that it can be used as OnClick handler
function openAddInfo1(searchResultID, productItineraryID) {

    window.open('AdditionalBookingInfo.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID, 'AdditionalInfo', 'width=500, height=400, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing AdditionalBookingInfo.aspx and returns false so that it can be used as OnClick handler
function openAddInfo2(bookCriterionID) {

    window.open('AdditionalBookingInfo.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;BookCriterionID=' + bookCriterionID + '&amp;Type=1', 'AdditionalInfo', 'width=500, height=400, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing AdditionalBookingInfo.aspx for status code info and returns false so that it can be used as OnClick handler
function openAddStatusCodeInfo(bookCriterionID) {

    window.open('AdditionalBookingInfo.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;BookCriterionID=' + bookCriterionID + '&amp;Type=2', 'AdditionalInfo', 'width=500, height=400, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing RateInfo.aspx and returns false so that it can be used as OnClick handler
//This has been extended to take in an optional rate composite key, where we want to get rate information specific for a particular room
function openRateInfo(searchResultID, productItineraryID, productItineraryDetailID, rateName, checkInDate, checkOutDate) 
{
    window.open('RateInfo.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID + '&amp;productItineraryDetailID=' + productItineraryDetailID + '&amp;rateName=' + rateName + '&amp;checkInDate=' + checkInDate + '&amp;checkOutDate=' + checkOutDate, 'AdditionalInfo', 'width=500, height=400, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing RoomDetails.aspx and returns false so that it can be used as OnClick handler
function openRoomDetails(searchResultID, productItineraryID, productItineraryDetailID) {
    window.open('RoomDetails.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID + '&amp;productItineraryDetailID=' + productItineraryDetailID, 'RoomDetails', 'width=500, height=400, menubar=no, resizable=yes, scrollbars=yes');
}

function openGenericWindow(url, title, width, height) 
{
    window.open(url, title, 'width=' + width + ', height=' + '=' + height + ', menubar=no, resizable=yes, scrollbars=yes, status=yes');
}

//Opens new window containing CancellationConditions.aspx and returns false so that it can be used as OnClick handler
function openCancellationConditions(bookCriterionID) 
{
    window.open('CancellationConditions.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;BookCriterionID=' + bookCriterionID, 'CancellationConditions', 'width=500, height=400, menubar=no, resizable=yes, scrollbars=yes');
}

//just makes sure we have a valid value, then 
//if we dont, just default it to 7
function getNumberOfDays(dateFlexabilityClientID)
{
    var lNumOfDays = 7;

    if (!(dateFlexabilityClientID == undefined || dateFlexabilityClientID == null))
        lNumOfDays = dateFlexabilityClientID.value;

    return lNumOfDays;
}

//Opens new window containing ProductStatusAvailability.aspx and returns false so that it can be used as OnClick handler
function openProductStatusAvailability(searchResultID, productItineraryID, dateFlexabilityClientID) 
{
    window.open('ProductStatusAvailability.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID + '&amp;selectedNoOfDays=' + getNumberOfDays(dateFlexabilityClientID), 'ProductAvailability', 'width=1000, height=600, menubar=no, resizable=yes, scrollbars=yes');
}

//Opens new window containing ProductStatusAvailability.aspx and returns false so that it can be used as OnClick handler
function openProductStatusAvailabilityDetail(searchResultID, productItineraryID, productItineraryDetailID, dateFlexabilityClientID) 
{
    window.open('ProductStatusAvailability.aspx?Language=' + getParameter('Language') + '&amp;FSSessionID=' + getParameter('FSSessionID') + '&amp;searchResultID=' + searchResultID + '&amp;productItineraryID=' + productItineraryID + '&amp;productItineraryDetailID=' + productItineraryDetailID + '&amp;selectedNoOfDays=' + getNumberOfDays(dateFlexabilityClientID), 'ProductAvailability', 'width=1000, height=600, menubar=no, resizable=yes, scrollbars=yes');
}

//Call below is required to avoid an javascript exception when this script file is loaded
//dynamically as a result of a UpdatePanel postback
if( typeof( Sys ) != "undefined" )
    Sys.Application.notifyScriptLoaded();