(function(app){
	if (app) {
		// add AddressContainer object to app namespace
		app.AddressContainer = function(response) {
			// address private data
			
			// Bind the find address search button behavior
			var bindPerformAddressSearch = function() {
				jQuery("#findAddress").click(function(e){
					jQuery("#addressResults").css("display","block");
					performSearch();
					return false;
				});
				
				// Need to bind a change event to each of the attributes to reset the score
				// if the customer modifies the text. 
				var dwFormPrefix = jQuery("#dwFormPrefix").val();

				jQuery("#" + dwFormPrefix + "_address1").change(function(e){
					jQuery("#" + dwFormPrefix + "_score").attr('value', "-1");});
				jQuery("#" + dwFormPrefix + "_address2").change(function(e){
					jQuery("#" + dwFormPrefix + "_score").attr('value', "-1");});
				jQuery("#" + dwFormPrefix + "_zip").change(function(e){
					jQuery("#" + dwFormPrefix + "_score").attr('value', "-1");});
				jQuery("#" + dwFormPrefix + "_city").change(function(e){
					jQuery("#" + dwFormPrefix + "_score").attr('value', "-1");});
				jQuery("#" + dwFormPrefix + "_province").change(function(e){
					jQuery("#" + dwFormPrefix + "_score").attr('value', "-1");});
				jQuery("#" + dwFormPrefix + "_country_countryCode").change(function(e){
					jQuery("#" + dwFormPrefix + "_score").attr('value', "-1");});					
			}			

			// Bind the "Select Result" button behavior but only after
			// a search has been performed
			var bindSearchResultSelect = function() {
				
				if (typeof app.addressDoctorSelectAddressClickHandler == 'function')
				{
					jQuery("#selectAddress").click(app.addressDoctorSelectAddressClickHandler);
				}
				else
				{
					jQuery("#selectAddress").click(function(e){
						
						var selectedAddressId = jQuery("#addressSearchResults").val();
						
						// Something has been selected
						if (selectedAddressId)
						{
							if (app.addressDoctorSelectInterceptor ){
								app.addressDoctorSelectInterceptor();
							}
							var resultAddressArray = app.AddressCache.addressResults;
	
							for (var i = 0; i < resultAddressArray.length; i++) {
								
								var resultAddress = resultAddressArray[i];
								
								if (resultAddress.id == selectedAddressId)
								{
									//get dwformprefix
									var dwFormPrefix = jQuery("#dwFormPrefix").val();
									
									// Apply attributes to form attributes for selected address 
									jQuery("#" + dwFormPrefix + "_address1").attr('value',   resultAddress.address1); 
									jQuery("#" + dwFormPrefix + "_address2").attr('value',   resultAddress.address2);
									jQuery("#" + dwFormPrefix + "_zip").attr('value',        resultAddress.postcode); 
									jQuery("#" + dwFormPrefix + "_city").attr('value',       resultAddress.locality);
									jQuery("#" + dwFormPrefix + "_province").attr('value',   resultAddress.province);
									jQuery("#" + dwFormPrefix + "_score").attr('value',      resultAddress.score);
									jQuery("#" + dwFormPrefix + "_country_countryCode").val(resultAddress.country);
									jQuery("#" + dwFormPrefix + "_postbox").attr('value',   resultAddress.postbox);
								}
							}
							
							// We check for the implementation of the function and if we have it
							// we chain the execution to it
							if (typeof app.addressDoctorSelectedAddressPostClickHandler == 'function')
							{
								return app.addressDoctorSelectedAddressPostClickHandler();
							}
							
							window.location.hash="#enterAddressDetails";
						}
						else
						{
							if (typeof app.addressDoctorNoSelectedAddressClickHandler == 'function')
							{
								app.addressDoctorNoSelectedAddressClickHandler();
							}
						}
	                    
						return false;
					});
				}
			}				
			
			var displayManualPrompt = function() {
				// This is the only we we can show the manaual prompt text in the JS world, 
				// as it is conditional based on if a search has been performed, irrespective of the result
				if(jQuery(".entermanually .addresssearchselecthint").length < 1){
					jQuery(".entermanually .wrapper").append('<span class="addresssearchselecthint">' + app.resources['cannot_find_address'] + '</span>');
				}
			}
			
			// submits the dialog form with the given action
			var performSearch = function() {
				
                // Need the name of the form so we can post the search 
				// data into AJAX call. 
				var formName = jQuery("#addressSearchForm").val();
				
				// serialize the form 
				var post = jQuery("#" + formName).serialize();
				
				// get the post url
				var url= jQuery("#dwAddressSearchURL").val();
				
				// post the data and replace current content with response content
		  		jQuery.ajax({
				   type: "POST",
				   url: url,
				   data: post,
				   dataType: "html",
				   success: function(data){
		  				jQuery("#addressResults").empty().html(data);
		  				bindSearchResultSelect();
		  				displayManualPrompt();
				   },
				   failure: function(data) {
					   alert(app.resources["SERVER_ERROR"]);
				   },
				   beforeSend: function() {
					     jQuery('#addressResults').html(app.showProgress("loading"));
				   }
				});
			}
			
			return {
				containerId			: null, // holds the html container id of this address
				addressResults		: [], // Address returned from verification call
				
				init : function() {
					bindPerformAddressSearch();
				},

				toString: function() {
					return "test";
				}
			}
		}
		
		// add Address object to app namespace
		app.Address = function(response) {

			// address json data
			var model 			= response.data;
			
			// Address instance
			return {
				id					: model.id,
				houseNumber			: model.houseNumber,
				suburb				: model.suburb,
				province			: model.province,
				locality            : model.locality,
				postbox             : model.postbox,
				postcode            : model.postcode,
				country             : model.country,
				address1            : model.address1,
				address2            : model.address2,
				score               : model.score,
				

				toString: function() {
					return this.model;
				}
			}
		} // Address defintion end
			
	}
	else {
		// dw namespace has not been defined yet i.e. app object is unavailable
		alert("app is undefined!");
	}
})(app);
