var ME_Maps = new Class({
	initialize: function() {
		if(!$defined(GMap2)) {
			return;
		}
		
		if (!GBrowserIsCompatible()) {
			alert("sorry your browser is not compatible with Google Maps");
			return;
		} else {
			this.map_e = $('gmap');
			// Empty any alt content out
			this.map_e.empty();
			this.map = new GMap2(this.map_e);
			this.map.addControl(new GLargeMapControl());
			this.map.addControl(new GMapTypeControl());
			this.coords_aus = {
				mid: [133.775136,-25.274398,4],
				lower: [133.775136,-31.0529,4],
				upper: [133.775136,-19.1452,4]
			};
			this.map.setCenter(new GLatLng(this.coords_aus.mid[1],this.coords_aus.mid[0]), this.coords_aus.mid[2]);
		}
		
		// Get a couple of forms via ajax so we can use in MooPrompt
		this.modal_forms = {
			mobile_lender: {
				path:'/personal/mobile_banking/book.html',
				id:'request_mobile_lender',
				validation: ME_lenders_validation
			}
		};
		this.ajax_get_forms();

		var me_postcodes = new ME_postcodes(); // Class Defined in: ME_Postcodes.js
		this.postcodes = {
			'keys': me_postcodes.return_keys(),
			'values': me_postcodes.return_values()
		}
		
		this.locations = ME_locations; // Object Defined in ME_Locations.js
		this.westpac_locations = Westpac_locations; // Object Defined in Westpac_Locations.js
		this.atmsCache = new GGeocodeCache();
		this.branchesCache = new GGeocodeCache();		
		// = Form elements = ==================================
		// prevent submission - otherwise page will reload on enter key
		$('maps_form').addEvent('submit',function(event){
			new Event(event).preventDefault();
		});
		// == Postcode field ==
		this.postcode_field = $('maps_postcode');
		// == Radios ==
		var radios = [];
		var radio_ids = ['maps_atms','maps_lender','maps_bus','maps_branch'];
		radio_ids.each(function(id) {
			var radio = $(id);
			if(!$chk(radio)){ 
				//console.error('Expected: input type="radio" with id="'+id+'"'); 
				return false; 
			}
			
			radio.addEvent('click',function() {
				this.select(radio);
			}.bind(this));
			
			radios.push(radio);
		},this);
		
		this.postcode_field.addEvent('keydown',function(event){
			var event = new Event(event);
			if(event.key=='enter') {
				// Check which radio is selected
				radios.each(function(radio) {
					if(radio.getProperty('checked')==true) {
						radio.fireEvent('click');
					}	
				});
			}
		},this);
		
		
		this.call_branch();

	},
	
	ajax_get_forms: function(){
		// This will grab the required forms for modal dialogue box
		// and put them into a hidden div so we can access them via the dom
		// the links used to open them will have the path in href so
		// if the form isnt fount the link will go to the page where the original form is
		var temp_data_div = new Element('div').setStyle('display','none');
		var data_div = new Element('div').setStyles({
			'width':900,
			'position':'absolute',
			'left': '-9999px',
			'top':0,
			'visibility':'hidden'		
		});
		$E('body').adopt(temp_data_div,data_div);
		var modal_forms = [
			this.modal_forms.mobile_lender
		];
		modal_forms.each(function(form_details,i){
			var url = 'http://'+document.domain+form_details.path;
			new Ajax(url,{
				method: 'get',
				update: temp_data_div,
				onComplete: function() {
					// Now filter out all the html crap except the form
					var form = temp_data_div.getElementById(form_details.id);
					if($chk(form)) {
						data_div.adopt(form);
					}
					if(i==modal_forms.length-1) { temp_data_div.remove(); }
					// add validation
					if($chk(form_details.validation) && !window.ie) {
						form_details.validation();
					}
				}
			}).request();
		});
	},

	return_postcode: function() {
		// doesnt really matter what argument[0] is something as long as its true in some way
		// if supplied no error will display but function with still return false if error
		var show_error = ($chk(arguments[0]) ? false : true);
		var p = this.postcode_field.getProperty('value').trim();
		if(!this.validate_postcode(p)) {
			if(show_error) {
				var msg = '';
				if(p==''){
					msg = '<h2>Please enter a post code</h2>';
				}else{
					msg = '<h2>The postcode '+p+' is invalid or unavailable</h2><h2>Enter another postcode</h2>';
				}
				this.show_msg(msg);
				this.postcode_field.addEvent('focus', function(){
					this.postcode_field.setProperty('value','');
					this.hide_msg();
					this.postcode_field.removeEvents('focus');
				}.bind(this));
			}
			return false;
		}
		return p;
	},
	
	// Function: select	
	// Called from radio event, in turn runs one of the "call_" functions 
	// where the radios value is appended to call_
	// Example if value is "atm" will run function this.call_atm() if it exists
	select: function(radio) {
		var value = radio.getProperty('value');
		if( !$chk(this['call_'+value]) ) { 
			//console.error('Function: call_'+value+' does not exist\nPlease make sure the value of radio matches one of the "call_" functions.'); 
			return; 
		}
		this['call_'+value]();
	},

	// =============================================================================================================
	// = ATM FUNCTIONS = ===========================================================================================
	call_atm: function() {//console.log('Function: call_atm - called');
		var postcode = this.return_postcode();
		if(!postcode){ return; }
		
		var geocoder = new GClientGeocoder();
		geocoder.setCache(this.atmsCache);
		
		// Find the postcode location from gmap
		var search = postcode+', Australia';
		
		geocoder.getLocations(search,function(result){
			// SUCCESS
			if(result.Status.code == G_GEO_SUCCESS) {
				var coords = result.Placemark[0].Point.coordinates;
				
				// Find X amount of atms that are in 50KM range of postcode
				var atms = [];
				
				this.locations.atms.each(function(atm,index) {
					// Check if the atm is in range
					var atm_coords = atm.Placemark[0].Point.coordinates;
					var marker = new GMarker(new GLatLng(coords[1],coords[0]));
					var distance = ( marker.getPoint().distanceFrom(new GLatLng(atm_coords[1], atm_coords[0])) ) / 1000;
					if(Math.floor(distance) <= 50) {
						// Add distance to atm.Placemark.Point so we can use in the next loop to
						// determine the closest out of the atms in range
						atm.Placemark[0].Point.distance = distance;
						atms.push(atm);
					}
				},this);
				//console.log(atms.length+' atms out of '+this.locations.atms.length+' are in range');
				
				// repeat for Westpac ATMs
				this.westpac_locations.atms.each(function(atm,index) {
					// Check if the atm is in range
					var atm_coords = atm.Placemark[0].Point.coordinates;
					var marker = new GMarker(new GLatLng(coords[1],coords[0]));
					var distance = ( marker.getPoint().distanceFrom(new GLatLng(atm_coords[1], atm_coords[0])) ) / 1000;
					if(Math.floor(distance) <= 50) {
						// Add distance to atm.Placemark.Point so we can use in the next loop to
						// determine the closest out of the atms in range
						atm.Placemark[0].Point.distance = distance;
						atms.push(atm);
					}
				},this);
				//console.log(atms.length+' atms out of '+this.locations.atms.length+' are in range');
				
				if(atms.length > 0) {
					// These two variables are use to find the closest out of the atms in range
					var closest_distance = 0;
					var closest_index = 0;
					// using - new GLatLngBounds(sw,  ne);
					
					// Clear existing overlays
					this.map.clearOverlays();
					
					// Loop through the atms in range
					atms.each(function(atm,index) {
   					// Marker settings
   					var atm_icon = new GIcon(G_DEFAULT_ICON);
   	        		atm_icon.image = ($chk(atm.westpac) ? "../images/icons/westpac_gmap_icon.png" : "../images/icons/me_gmap_icon.png");
   					// Set up our GMarkerOptions object
   					marker_options = { icon:atm_icon };
   					
						// store the closest atm
						if(index == 0) {
							closest_distance = atm.Placemark[0].Point.distance;
						}else if(atm.Placemark[0].Point.distance < closest_distance){
							closest_distance = atm.Placemark[0].Point.distance;
							closest_index = index;
						}
						
						// Add markers for each atm - NB: This needs to be last thing in loop because theres a return
						var coords = atm.Placemark[0].Point.coordinates;
						var marker = new GMarker(new GLatLng(coords[1],coords[0]),marker_options);
						this.map.addOverlay( marker );
						var info = ($chk(atm.name) ? '<strong>'+atm.name+'</strong><br/>' : '');
						info += ($chk(atm.Placemark[0].address) ? atm.Placemark[0].address : '');
						if(info!='') {
							GEvent.addListener(marker, "click", function() {
								marker.openInfoWindowHtml(info.replace(/,/g,',<br/>'));
					        });
					        return marker;
				        }
					},this);
						
					var zoom = 15; 
					var closest_coords = atms[closest_index].Placemark[0].Point.coordinates;
					
					this.map.setCenter(new GLatLng(closest_coords[1], closest_coords[0]),zoom);
					
					// Hide msg box incase its open
					this.hide_msg();
					
				}else{
					this.show_msg('<h2>No ME Bank ATM\'s were found near the post code '+postcode+'</h2>');
					this.postcode_field.addEvent('focus', function(){
						this.postcode_field.setProperty('value','');
						this.hide_msg();
						this.postcode_field.removeEvents('focus');
					}.bind(this));
				}
				
			}else{
			// FAILURE
				this.show_msg('<p>Gmaps was unable to find <strong>'+search+'</strong> please try again.</p>');
			}
		}.bind(this)); // bind this (the MOO_ME_Maps instance)
	},

	
	// =============================================================================================================
	// = LENDER FUNCTIONS = ========================================================================================
	call_lender: function() {//console.log('Function: call_lender - called');
		var postcode = this.return_postcode('no error');
		if(postcode){
			var h2 = new Element('h2').appendText('We have found a representative in your area');
			var a = new Element('a').adopt( new Element('span').appendText('Book a Mobile Banking Manager') ).addClass('button');
			a.setProperty('href',this.modal_forms.mobile_lender.path);
			a.setProperty('onClick','pageTracker._trackPageview(\'/mobilelender\'); return true;'); 
			var book = new Element('p').adopt(a);
			// Make link open modal if the form is present on the page
			var f_id = this.modal_forms.mobile_lender.id;
			var form = $(f_id);
			if(form && !window.ie6){	// Not using modal in ie6 for same reasons not using it for call backs	
				a.addEvent('click',function(e){
					new Event(e).preventDefault();
					form.addClass('modal');
					var form_size = form.getSize().scrollSize;	
					// Unfortunately a few browser inconsistencies
					// adjust size for IE
					form_size.width = (window.ie ? form_size.x+2 : form_size.x);
					form_size.height = (window.ie ? form_size.y+2 : form_size.y);
					// adjust height for opera
					form_size.height = (window.opera ? form_size.height+100 : form_size.height);
					
					var close = new Element('div').appendText('X').addClass('close');
					
					var modal = new MooPrompt('',form, {
						width: form_size.width,
						height: form_size.height,
						button1: close,
						return_content_to_dom: true
					});

					var cancel = $(f_id+'_cancel_btn');
					if($chk(cancel)){ cancel.remove(); }
				
					cancel = new Element('a').addClass('button-white').setProperty('id',f_id+'_cancel_btn');
					cancel.adopt( new Element('span').appendText('Cancel') );
					cancel.addEvent('click',function(event){
						var event = new Event(event);
						event.preventDefault();				
						modal.close();
					});
					// For some reason in opera the cancel button is ontop of submit if injected
					// before so if opera inject after all others before
					cancel['inject'+(window.opera ? 'After' : 'Before')]( $E('button.submit',form) );
				});
			}
			this.show_msg(new Element('div').adopt(h2,book));
		}else{
			var p = this.postcode_field.getProperty('value').trim();	
			var msg = '';
			if(p==''){
				msg = '<h2>Please enter a post code</h2>';
			}else{
				msg += 	'<h2>There is no reperesentative in your area <br/><small>or the post code '+p+' is unavailable</small></h2>';
				msg +=		'<p class="buttons"><a href="/contact/#personal_banking_contact" class="request button"><span>Contact <abbr title="ME Bank">ME</abbr></span></a></p>'; 
			}
			this.show_msg(msg);
		}
	},
	// =============================================================================================================
	// = BUSINESS FUNCTIONS = ======================================================================================
	/* // [rb] now replaced with state offices
	call_business: function() {//console.log('Function: call_business - called !!! redirecting to Function: call_lender');
		var postcode = this.return_postcode('no error');
		if(postcode){
			var postcode_info = this.return_postcode_info(postcode); // at the mo' its a string
			
			var h2 = new Element('h2').appendText('We have found a representative in your area');
			var book = new Element('p').adopt(new Element('a').adopt(new Element('span').appendText('Book a Mobile Banking Manager')).setProperties({
				'href': '#',
				'title': 'Goes where ???'
			}).addClass('button'));
			
			this.show_msg(new Element('div').adopt(h2,book));
		}else{
			var msg = 	'<h2>There is no reperesentative in your area</h2>';
			msg +=		'<p class="buttons"><a href="/contact/#business_banking_contact" class="request button"><span>Contact <abbr title="ME Bank">ME</abbr></span></a></p>'; 
			this.show_msg(msg);
		}
	},
	*/
	// =============================================================================================================
	// = STATE OFFICES = ===========================================================================================
	call_state_office: function() {
		// Hide msg area in case its visible
		this.hide_msg();
		// We will show all ofices in a zoomed out view of australia
		// Marker settings
		var atm_icon = new GIcon(G_DEFAULT_ICON);
      		atm_icon.image = "../images/icons/me_gmap_icon.png";//"http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png";
		// Set up our GMarkerOptions object
		marker_options = { icon:atm_icon };
		
		// Clear existing overlays
		this.map.clearOverlays();
					
		this.locations.state_offices.each(function(office,index){
			var coords = office.Placemark[0].Point.coordinates;
			var marker = new GMarker(new GLatLng(coords[1],coords[0]),marker_options);
			this.map.addOverlay( marker );
			var info = '';
			info += ($chk(office.name) ? '<strong>'+office.name+' State Office</strong>' : '');
			info += ($chk(office.Placemark[0].address) ? '<br/>'+office.Placemark[0].address.replace(/,/g,',<br/>') : '');
			info += ($chk(office.Placemark[0].hours) ? '<br/><strong>Hours:</strong> '+office.Placemark[0].hours : '');
			info += ($chk(office.Placemark[0].phone) ? '<br/><strong>Phone:</strong> '+office.Placemark[0].phone : '');
			info += ($chk(office.Placemark[0].fax) ? '<br/><strong>Fax:</strong> '+office.Placemark[0].fax : '');
			if($chk(office.Placemark[0].hasAtm)) {
				info += (office.Placemark[0].hasAtm.toLowerCase()=='yes' ? '<br/><em>24 hour ATM available at Branch</em>' : '');
			}
			info += ($chk(office.Placemark[0].note) ? '<br/><small>'+office.Placemark[0].note+'</small>' : '');
			if(info!='') {
				GEvent.addListener(marker, "click", function() {
					marker.openInfoWindowHtml(info);
		        });
		        return marker;
	        }
		},this);
		
		// center map - Using lower region coords
		this.map.setCenter(new GLatLng(this.coords_aus.lower[1],this.coords_aus.lower[0]), this.coords_aus.lower[2]);
	},
	// =============================================================================================================
	// = BRANCHES FUNCTIONS = ======================================================================================
	call_branch: function() {//console.log('Function: call_branch - called');
		// Hide msg area in case its visible
		this.hide_msg();
		// since theres only two branches lets mark both and zoom out to aus view
		// Marker settings
		var atm_icon = new GIcon(G_DEFAULT_ICON);
      	atm_icon.image = "../images/icons/me_gmap_icon.png";//"http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png";
		// Set up our GMarkerOptions object
		marker_options = { icon:atm_icon };
		
		// Clear existing overlays
		this.map.clearOverlays();
					
		this.locations.branches.each(function(branch,index){
			var coords = branch.Placemark[0].Point.coordinates;
			var marker = new GMarker(new GLatLng(coords[1],coords[0]),marker_options);
			this.map.addOverlay( marker );
			var info = '';
			info += ($chk(branch.name) ? '<strong>'+branch.name+'</strong>' : '');
			info += ($chk(branch.Placemark[0].address) ? '<br/>'+branch.Placemark[0].address.replace(/,/g,',<br/>') : '');
			info += ($chk(branch.Placemark[0].hours) ? '<br/><strong>Hours:</strong> '+branch.Placemark[0].hours : '');
			info += ($chk(branch.Placemark[0].phone) ? '<br/><strong>Phone:</strong> '+branch.Placemark[0].phone : '');
			info += ($chk(branch.Placemark[0].fax) ? '<br/><strong>Fax:</strong> '+branch.Placemark[0].fax : '');
			if($chk(branch.Placemark[0].hasAtm)) {
				info += (branch.Placemark[0].hasAtm.toLowerCase()=='yes' ? '<br/><em>24 hour ATM available at Branch</em>' : '');
				info += (branch.Placemark[0].hasAtm.toLowerCase()=='available' ? '<br/><em>ATM available</em>' : '');
			}
			if(info!='') {
				GEvent.addListener(marker, "click", function() {
					marker.openInfoWindowHtml(info);
		        });
		        return marker;
	        }
		},this);
		
		// center map
		this.map.setCenter(new GLatLng(this.coords_aus.mid[1],this.coords_aus.mid[0]), this.coords_aus.mid[2]);
	},
	
	validate_postcode: function(postcode) {
		// check that the postcode is a valid integer
		if((postcode.toString().search(/^[0-9]+$/) != 0)){
			return false;
		}

		var keys = this.postcodes.keys;
		var values = this.postcodes.values;
		if( !$chk(keys[values[postcode]]) ) {
			return false;
		} else {
			return true;
		}
	},
	
	return_postcode_info: function(postcode) {
		return this.postcodes.keys[this.postcodes.values[postcode]];
	},
	
	show_msg: function(msg) {
		if(!$chk(this.msg_box)) {			
			this.msg_box = new Element('div').setProperty('id','gmap_msg');
			this.msg_box.setOpacity(0);
			this.map_e.adopt(this.msg_box);
			
		}
		// add click event to hide 
		this.msg_box.addEvent('click',function() { this.hide_msg(); }.bind(this));
		var fade_in = new Fx.Style(this.msg_box,'opacity',{duration:250});
		if($type(msg)=='string') {
			this.msg_box.setHTML(msg);
		}else if($type(msg)=='element') {
			this.msg_box.empty();
			this.msg_box.adopt(msg);
		}
		if(this.msg_box.getStyle('opacity')==0) {
			fade_in.start(0,0.8);
		}
	},
	
	hide_msg: function() {
		if(!$chk(this.msg_box)) { return; }
		if(this.msg_box.getStyle('opacity')!=0) {		
			var fade_out = new Fx.Style(this.msg_box,'opacity',{duration:250});
			fade_out.start(0.8,0);
		}
	},
	// Contructs the html nodes and injects into div#main
	construct_html: function() {
		this.map_e = new Element('div').setProperty('id','gmap');
		this.map_form = new Element('form').setProperty('id','maps_form').addEvent('submit',function(event){
			new Event(event).preventDefault();
		});
		// Claonable items
		var fieldset = new Element('fieldset');
		var ol = new Element('ol');
		var li = new Element('li');
		var label = new Element('label');
		var input = new Element('input');
		
		//var legend = new Element('legend').setHTML('Locate <abbr title="ME Bank">ME</abbr>');
	}
});

ME_Maps.implement(new Chain);

window.addEvent('domready',function(){
	new ME_Maps();
});
