document.observe("dom:loaded", function() {

	// resize the page so it is always in blocks of 40 pixels
	var height = $('wrapper').getHeight();
	if (height%40 != 0) {
		var max = Math.ceil(height/40);
		$('wrapper').setStyle({
			'height': max*40 + 'px'
		});
	}

	// do we have the map
	if ($('map')) {
		// ok what type of map
		if ($('create')) {
			new CreateForm();
		} else {
			// basic map
			new GoogleMap($F('location'), $('map'), {
				draggable: false
			});
		}
	}

	// create the script for the form submit
	$$('a.submit').each(function(sub) {
		sub.observe('click', function(e) {
			var sub = Event.element(e).up('a');
			var form = sub.previous();
			form.submit();
		});
	});

	// calendar code
	if ($$('.time').length > 0) {
		Calendar.setup({
			dateField      : 'start_date',
			triggerElement : 'start_date'
		});
		Calendar.setup({
			dateField      : 'end_date',
			triggerElement : 'end_date'
		});
	}

	var form = function(ta) {
		if (ta.value == '' && ta.readAttribute('title') != null) {
			ta.value = ta.readAttribute('title');
			ta.addClassName('grey');
			var undo = function() {
				if (ta.hasClassName('grey')) {
					ta.removeClassName('grey');
					ta.value = '';
				}
			};
			ta.observe('click', undo);
			ta.observe('focus', undo);
		}
	}

	$$('form textarea').each(form);
	$$('form input').each(form);
});

var CreateForm = Class.create({
	initialize: function() {
		if ($F('lat') == '') {
			address = $F('location');
		} else {
			address = $F('lat') + ',' + $F('long');
		}
		
		this.map = new GoogleMap(address, $('map'), {
			draggable: true
		});
		
		document.observe('map:geocoded', function(event) {
			var pos = event.memo[0].geometry.location;
			$('lat').writeAttribute('value', pos.lat());
			$('long').writeAttribute('value', pos.lng());
			$('address').value = event.memo[0].formatted_address;
		}.bind(this));

		document.observe('map:dragend', function(event) {
			var pos = event.memo.getPosition();
			$('lat').writeAttribute('value', pos.lat());
			$('long').writeAttribute('value', pos.lng());

			this.map.getLocation(pos, function(response) {
				$('address').value = response.formatted_address;
			});
		}.bind(this));
	}
});

var GoogleMap = Class.create({
	initialize: function(address, div, options) {

		this.options = Object.extend({
			draggable: true
		}, options || {});

		this.mapOptions = {
			zoom: 15,
			mapTypeControl: false,
			navigationControl: true,
			navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
			mapTypeId: google.maps.MapTypeId.ROADMAP
		}

		this.div = $(div);

		// is the address
		if (address.match(/[0-9.]+\s*,\s*[0-9.]+/)) {
			// it's a lat/lng'
			var latLng = address.split(',');
			// create the lat/lng
			latLng = new google.maps.LatLng(latLng[0], latLng[1]);
			// set the center
			this.mapOptions.center = latLng;
			// create the map
			this.map = new google.maps.Map(div, this.map_options);
			// add in the marker
			this.createMarker(this.mapOptions.center, this.options.draggable);
		} else {
			// it's a address, going to have geocode it
			this.geocode(address, function(result) {
				// set the center based on the geocode results
				this.mapOptions.center = result[0].geometry.location;
				// create the map
				this.map = new google.maps.Map(this.div, this.mapOptions);
				// add in the marker
				this.createMarker(this.mapOptions.center, this.options.draggable);
			}.bind(this), function() {
				// failure
				$('error').show();
				this.mapOptions.center = new google.maps.LatLng(50,0);
				this.mapOptions.zoom = 2;
				// create the map
				this.map = new google.maps.Map(this.div, this.mapOptions);
				// add in the marker
				this.createMarker(this.mapOptions.center, this.options.draggable);
			}.bind(this));
		}
	},

	createMarker: function(pos, draggable) {
		this.marker = new google.maps.Marker({
			position: pos,
			map: this.map,
			draggable: draggable
		});
		// call the drag end
		if (this.options.draggable) {
			google.maps.event.addListener(this.marker, 'dragend', function() {
				this.div.fire('map:dragend', this.marker);
			}.bind(this));
		}
	},

	geocode: function(location, onSuccess, onFailure) {
		geocoder = new google.maps.Geocoder();
		geocoder.geocode({
			'address': location
		}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				// fire an event
				this.div.fire('map:geocoded', results);
				return onSuccess(results);
			} else {
				onFailure();
				return false;
			}
		}.bind(this));
	},

	getLocation: function(latlong, onSuccess) {
		geocoder = new google.maps.Geocoder();
		geocoder.geocode({'latLng': latlong}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				if (results[1]) {
				  onSuccess(results[1]);
				}
			}
		});
	}
});
