/* global.js v3 */


// setup the app
var debug_mode = false;
var map;
var center = [30, -30];
var zoom = 2;
var bounds;
var autozoom = [1, 5];
var json = false;
var data;
var markers = null;
var current_page;
var total_pages;
var per_page = 9999999;
var current_location;
var results_counter;
var url = {
	'locations'  : './api/?locations',
	'categories' : './api/?categories',
	'durations' : './api/?durations',
	'projects'   : './api/?projects',
	'print'      : './print?'
};


window.addEvent('domready', function() {
	
	// jquery
	//jQuery.noConflict();
	
	// navigation
	//$('primary-navigation').empty().grab($('primary-nav-replace').set('id', 'primary-nav').setStyle('visibility', 'visible'));
	if ($('primary-nav-add') && $('primary-nav-add').getChildren().length) $('primary-nav').adopt($('primary-nav-add').getChildren());
	$$('li#menu-item-14200 a').addClass('appear').set('rel', 'bom-search');
	$$('a.appear').addEvent('click', function(e) {
		e.stop();
		
		$$('div.appear').setStyle('display', 'none');
		//$(this.get('href').split('#').join('')).setStyle('display', 'block');
		$(this.get('rel')).setStyle('display', 'block');
	});
	
	// hide elements which will be fading in later
	var to_hide = [
		$('map'),
		$('invalid'),
		$('no-results'),
		$('results')
	];
	to_hide.each(function(h_el) {
		h_el.setStyle('opacity', 0);
	});
	
	// prevent double-clicks
	/*[$('get-projects'), $('prev-page'), $('next-page')].each(function(n_el) {
		n_el.addEvent('dblclick', function() {
			return false;
		});
	});*/
	$('get-projects').addEvent('dblclick', function() {
		return false;
	});
	
	// form buttons click
	$('get-projects').addEvent('click', function(e) {
		e.stop();
		getProjects();
	});
	
	// specialized search buttons
	$$('a.special-search').addEvent('click', function(e) {
		e.stop();
		if (this.get('rel') == 'disaster') {
			$('location').set('value', '');
			$('category').set('value', '9');
			$('duration').set('value', '');
			getProjects();
		} else if (this.get('rel') == 'church2church') {
			$('location').set('value', '');
			$('category').set('value', '26');
			$('duration').set('value', '');
			getProjects();
		}
	});
	
	// email
	$$('a.email').addEvent('click', function(e) {
		e.stop();
		noSpam(this.innerHTML);
	});
	
	// info window elements click
	$$('a.tab').addEvent('click', function(e) {
		e.stop();
		changeTab(this.id);
	});
	$('close-window').addEvent('click', function(e) {
		e.stop();
		closeWindow();
	});
	
	// load locations, categories, and time-frames
	getLocations();
	getCategories();
	getDurations();
	
	// pre-load target and results images
	new Asset.images([
		'./_img/marker-red.png',
		'./_img/marker-red-shadow.png',
		'./_img/marker-green.png',
		'./_img/marker-green-shadow.png',
		'./_img/marker-blue.png',
		'./_img/marker-blue-shadow.png',
		'./_img/marker-shadow.png',
		//'./_img/pin.png',
		//'./_img/pin-shadow.png',
		//'./_img/pin-ball.png',
		/*'./_img/target_1.png',
		'./_img/target_2.png',
		'./_img/target_3.png',
		'./_img/target_4.png',
		'./_img/target_5.png',
		'./_img/target_6.png',
		'./_img/target_7.png',
		'./_img/target_8.png',
		'./_img/target_9.png',
		'./_img/target_shadow.png',
		'./_img/result_1.png',
		'./_img/result_2.png',
		'./_img/result_3.png',
		'./_img/result_4.png',
		'./_img/result_5.png',
		'./_img/result_6.png',
		'./_img/result_7.png',
		'./_img/result_8.png',
		'./_img/result_9.png',
		'./_img/result_view.png',*/
		'./_img/window_bottom.png',
		'./_img/window_close.png',
		'./_img/window_middle.png',
		'./_img/window_tab.png',
		'./_img/window_top.png',
	]);
	
	// toggle marker buttons
	$$('.toggle-marker').addEvent('click', function(e) {
		e.stop();
		toggleMarkers(this.get('rel'));		
	});
	
});


// on load
window.addEvent('load', function() {

	// load the map
	loadMap();
	
	// show map
	//new Fx.Tween('map', {'property': 'opacity'}).start(0, 1);
	//new Fx.Tween('map', {'property': 'opacity'}).start(1);
	
	// get all projects
	getProjects();
	
});


// build the map
function loadMap() {
	
	// build the map
	map = new google.maps.Map($('map'), {
		'zoom': zoom,
		'center': new google.maps.LatLng(center[0], center[1]),
		'mapTypeId': google.maps.MapTypeId.ROADMAP,
		'disableDefaultUI': true,
		'navigationControl': true,
		'mapTypeControl': false,
		'scaleControl': false
	});
	
	// make the info window stay where it should upon zooming
	google.maps.event.addListener(map, "zoomend", function() {
		if ($('info-window').getStlye('display') != 'none') {
			current_project.info_window.draw();
		}
	});
}


// clear the form
function clearForm() {
	// reset fields
	$('location').set('value', '');
	$('category').set('value', '');
	$('duration').set('value', '');
	$$('.toggle-marker').removeClass('selected');
	//$$('input.toggle-marker').set('checked', 'checked');
	
	// hide alerts
	$$('.alert span').each(function(a_el) {
		if (a_el.getStyle('opacity') > 0) {
			new Fx.Tween(a_el, {
				'property': 'opacity',
				'onComplete': function() {
					a_el.setStyle('display', 'none');
				}
			//}).start(1, 0);
			}).start(0);
		}
	});
}


// populate search fields
function getLocations() {
	var json = new Request.JSON({
		'url': url.locations,
		'method': 'get',
		'onSuccess': function(response) {
			debug('getLocations', response);
			if (!response.error) {
				var continents = response.data.continents;
				Object.each(continents, function(continent) { // add continents as optgroups
					var cont_el = new Element('optgroup', {
						'label': continent.continent_name
					}).inject('location');
					Object.each(continent.regions, function(region, i) {
						new Element('option', {
							'value': i,
							'html': region
						}).inject(cont_el);
					});
				});
				//$('location').setStyle('width', '100%');
			}
		}
	}).send();
}
function getCategories() {
	var json = new Request.JSON({
		'url': url.categories,
		'method': 'get',
		'onSuccess': function(response) {
			debug('getCategories', response);
			if (!response.error) {
				var categories = response.data.categories;
				Object.each(categories, function(category, i) { // add categories as options
					new Element('option', {
						'value': i,
						'html': category
					}).inject('category');
					//$('category').setStyle('width', '100%');
				});
			}
		}
	}).send();
}
function getDurations() {
	var json = new Request.JSON({
		'url': url.durations,
		'method': 'get',
		'onSuccess': function(response) {
			debug('getDurations', response);
			if (!response.error) {
				var durations = response.data.durations;
				Object.each(durations, function(duration, i) { // add time-frames as options
					new Element('option', {
						'value': i,
						'html': duration
					}).inject('duration');
					//$('duration').setStyle('width', '100%');
				});
			}
		}
	}).send();
}


// get the data
function getProjects(page_num) { // page_num is the page we want to see
	// die if json is already running
	if (json && json.running) {
		return false;
	}
	// default values
	if (!page_num) { // if no page num defined (or zero), set it to 1 (first page)
		page_num = 1;
	}
	current_page = page_num; // reset current page to requested page number

	// validate
	var location = escape($('location').get('value')) || 0;
	var category = escape($('category').get('value')) || 0;
	var duration = escape($('duration').get('value')) || 0;
	//if (!location && !category && !duration) { // show invalid message; you must choose at least one search parameter
	//	$('invalid').setStyle('display', 'inline');
	//	new Fx.Tween('invalid', {'property': 'opacity'}).start(0, 1);
	//	return false;
	//}
	
	// un-click-able-ize button and nav links
	$('get-projects').removeEvents('click');
	//$('prev-page').removeEvents('click');
	//$('next-page').removeEvents('click');
	
	// hide alerts
	$$('.alert span').each(function(a_el) {
		if (a_el.getStyle('opacity') > 0) {
			new Fx.Tween(a_el, {
				'property': 'opacity',
				'onComplete': function() {
					a_el.setStyle('display', 'none');
				}
			//}).start(1, 0);
			}).start(0);
		}
	});
	
	// scroll to top
	//new Fx.Scroll(window).toTop();
	
	// hide results
	if ($('results').getStyle('opacity') > 0) {
		//new Fx.Tween('results', {'property': 'opacity'}).start(1, 0);
		new Fx.Tween('results', {'property': 'opacity'}).start(0);
	}
	
	// hide map
	new Fx.Tween('map', {
		'property': 'opacity',
		'onComplete': function() {
															 
			// reset the app
			resetResults();
			closeWindow();
			clearMarkers();
			map.setCenter(new google.maps.LatLng(center[0], center[1]), 2);
			bounds = new google.maps.LatLngBounds();
			
			// we're using json; pass parameters via 'send' method
			var data = 'location='+location+'&category='+category+'&duration='+duration+'&page='+page_num+'&per_page='+per_page;
			debug('project request', data);
			debug('current-page', current_page);
			json = new Request.JSON({
				'url': url.projects,
				'method': 'get',
				'data': data,
				'onSuccess': buildProjects
			}).send();
			
		}
	//}).start(1, 0);
	}).start(0);
}


// set up each location one by one
function buildProjects(response) { // auto-passed the resulting object from our json call
	debug('getProjects', response);
	if (!response.error) {
		
		// set some variables
		markers = [];
		total_pages = response.paging.total_pages;
		data = response.data;
		var i = 0;
		
		if (!response.data.projects) { // no results found
			debug('no projects');
			// show no results message
			$('no-results').setStyle('display', 'inline');
			//new Fx.Tween('no-results', {'property': 'opacity'}).start(0, 1);
			new Fx.Tween('no-results', {'property': 'opacity'}).start(1);
			$('location').focus();
			
		} else { // results found
			
			Object.each(response.data.projects, function(project) { // for each project
				debug('buildProjects project.project_id', project.project_id);
				
				// assemble html tabs & project results
				project.tabs = []; // holds tab html
				project.results = {}; // holds who, what, when, where, contact; also other snippets as we see fit
				
				// tab 1: details (where, when, who, what)
				var html = [];
				// heading
				//html.push('<p class="heading">About this mission project...</p>');
				// table
				html.push('<table cellpadding="0" cellspacing="0" border="0">');
				// what
				project.results.what = '<a class="result-name result-click" id="result_'+project.project_id+'" href="javascript:;">'+project.project_name+'</a>';
				  //html.push('<tr><td class="tbl_left" valign= "top">Project:</td><td valign="top">'+project.project_name+' - '+project.category_name+'<br />'+project.description+'</td></tr>');		
				  html.push('<tr><td valign="top" colspan="2"><strong>'+project.project_name+' - '+project.category_name+'</strong></td></tr>');
				  html.push('<tr><td valign="top" colspan="2">'+project.description+'</td></tr>');		
				// when
				// not necessary with pre-formatted dates:
				/////var date_start = parseFloat(project.start_date.substring(5, 7))+'/'+parseFloat(project.start_date.substring(8, 10))+'/'+project.date_start.substring(0, 4);
				// not necessary with pre-formatted dates:
				/////var date_end = parseFloat(project.end_date.substring(5, 7))+'/'+parseFloat(project.end_date.substring(8, 10))+'/'+project.end_date.substring(0, 4);
				// remove seconds
				if (project.start_date) {
					project.start_date = project.start_date.substring(0, project.start_date.indexOf(' '));
				}
				if (project.end_date) {
					project.end_date = project.end_date.substring(0, project.start_date.indexOf(' '));
				}
				// formulate time frame
				if (project.duration_name) {
					project.results.when = project.duration_name;
					if (project.start_date) {
						project.results.when += ' - '+project.start_date;
						if (project.end_date) {
							project.results.when += ' to '+project.end_date;
						}
					} else if (project.end_date) {
						project.results.when += ' - '+project.end_date;
					}
				} else if (project.start_date) {
					project.results.when = project.start_date;
					if (project.end_date) {
						project.results.when += ' to '+project.end_date;
					}
				} else if (project.end_date) {
					project.results.when = project.end_date;
				} else {
					project.results.when = 'To be determined';
				}
				html.push('<tr><td class="tbl_left" valign= "top">Duration:</td><td valign="top"><strong>'+project.results.when+'</strong></td></tr>');		
				// where
				if (project.city) {
					project.results.where = project.city;
					if (project.state) {
						project.results.where += ', '+project.state;
					} else if (project.country) {
						project.results.where += ', '+ project.country;
					}
				} else if (project.state) {
					project.results.where = project.state;
					if (project.country) {
						project.results.where += ', '+project.country;
					}
				} else if (project.country) {
					project.results.where = project.country;
				} else {
					project.results.where = "To be determined";
				}
				html.push('<tr><td class="tbl_left" valign= "top">Location:</td><td valign="top"><strong>'+project.results.where+'</strong></td></tr>');		
				// who
				project.results.who = project.organizer_name;
				//html.push('<tr><td class="tbl_left" valign= "top">Organizer:</td><td valign="top">'+project.results.who+'</td></tr>');		
				// finish
				html.push('</table>');
				project.tabs.push(html.join(''));
				
				// tab 2: go/give/partner (contact info)
				var html = [];
				// heading
				  //html.push('<p class="heading">For more info...</p>');
				// table
				  html.push('<table cellpadding="0" cellspacing="0" border="0">');
				// contact
				  //html.push('<tr><td class="tbl_left" valign="top">Contact:</td><td valign="top">'+project.contact+'</td></tr>');
				  //html.push('<p>'+project.contact+'</p>');
				  html.push('<tr><td valign="top" colspan="2"><strong>'+project.contact+'</strong></td></tr>');
				// address
				project.results.address = '';
				  //html.push('<tr><td class="tbl_left" valign="top">Address:</td><td valign="top">'+project.address.split("\n").join('<br />')+'</td></tr>');
				  //html.push('<p>'+project.address.split("\n").join('<br />')+'</p>');
				  html.push('<tr><td valign="top" colspan="2">'+project.address.split("\n").join('<br />')+'</td></tr>');
				// phone, email, website
				project.results.phone = project.phone;
				project.results.email = '<a href="mailto:'+project.email+'">'+project.email+'</a>';
				if (project.website) project.results.website = '<a href="'+project.website+'" target="_blank">visit website...</a>';
				  //html.push('<tr><td class="tbl_left" valign="top">');
				  //html.push('P:<br />E:');
				  //if (project.website) html.push('<br />W:');
				  //html.push('</td><td valign="top">');
				  html.push('<tr><td valign="top" colspan="2">');
				  html.push('<strong>'+project.results.phone+'</strong>');
				  html.push('<br /><strong>'+project.results.email+'</strong>');
				  if (project.website) html.push('<br /><strong>'+project.results.website+'</strong>');
				  html.push('</td></tr>');
				// finish
				html.push('</table>');
				project.tabs.push(html.join(''));
				html = null;							   
				//project.tabs = project.tabs;
				
				// set marker latlng and opts in project
				project.coordinates = project.coordinates.split(',');
				project.latlng = new google.maps.LatLng(project.coordinates[0], project.coordinates[1]);
				
				// make a new marker and extend boundary to accommodate it
				if (project.status == 'open') {
					project.color = 'red';
				} else if (project.status == 'completed') {
					project.color = 'blue';
				} else if (project.status == 'ongoing') {
					project.color = 'green';
				} else {
					project.color = 'black';
				}
				project.marker = new google.maps.Marker({
					'color': project.color,
					'map': map,
					'position': project.latlng,
					'title': project.results.where,
					//'icon': './_img/target_'+(i + 1)+'.png'
					'icon': new google.maps.MarkerImage(
						//'./_img/target_'+(i + 1)+'.png', // icon url
						//'./_img/pin.png',               // icon url
						'./_img/marker-'+project.color+'.png',        // icon url
						new google.maps.Size(20, 30),   // icon size
						new google.maps.Point(0, 0),    // icon origin
						new google.maps.Point(10, 30)   // icon anchor
					),
					'shadow': new google.maps.MarkerImage(
						//'./_img/target_shadow.png',   // shadow url
						//'./_img/pin-shadow.png',      // shadow url
						'./_img/marker-shadow.png',   // shadow url
						new google.maps.Size(30, 30), // shadow size
						new google.maps.Point(0, 0),  // shadow origin
						new google.maps.Point(10, 30) // shadow anchor
					)
				});
				markers.push(project.marker);
				bounds.extend(project.latlng);
				
				// on marker click, open the info window
				project.marker.project_id = project.project_id;
				google.maps.event.addListener(project.marker, 'click', function(e) {
					var project = data.projects[this.project_id];
					project.info_window = new infoWindow(project);
				});
				
				// build result table row
				var html = [];
				
				// make a new tr with alternate class if odd-numbered
				var tr_el = new Element('tr');
				if (results_counter % 2 == 0) {
					tr_el.addClass('alternate');
				}
				
				// make new tds
				var tds = [];
				tds.push(new Element('td', {
					'class': 'icon-td',
					'html': '<img class="result-icon result-click" id="result_'+project.project_id+'" src="./_img/marker-'+project.color+'-shadow.png" title="View this project" />'
				}));
				tds.push(new Element('td', {'html': project.results.what}));
				tds.push(new Element('td', {'html': project.results.when}));
				tds.push(new Element('td', {'html': project.results.where}));
				//tds.push(new Element('td', {'html': project.results.who}));
				tds.push(new Element('td', {
					'class': 'rightmost-td',
					'html': project.results.email
				}));
				
				// finish tr
				tds.each(function(td_el) {
					td_el.inject(tr_el);
				});
				
				// set results in table
				var tbody_el = $$('#results-wrap table tbody')[0];
				tr_el.inject(tbody_el);
				
				// iterate
				results_counter++;
				
				// kill vars
				html = null;
				tr_el = null;
				tds = null;
				tbody_el = null;
				
				// iterate
				i ++;
			});
			
			// show results list
			publishResults();
		
		} // end results found
		
		// zoom to the boundary
		if (bounds.isEmpty()) {
			bounds.extend(new google.maps.LatLng(center[0], center[1]));
			map.fitBounds(bounds);
			map.setZoom(zoom);
		} else {
			map.fitBounds(bounds);
		}
		
		// show map
		//new Fx.Tween('map', {'property': 'opacity'}).start(0, 1);
		new Fx.Tween('map', {'property': 'opacity'}).start(1);
		
		// re-click-able-ize button
		$('get-projects').addEvent('click', function(e) {
			e.stop();
			getProjects();
		});
		
		// set marker toggles
		setMarkerToggles();
		
	}
}


// extend google code to ease use of our custom info window and gmarker.ishidden
function infoWindow(project) {
	this.latlng_ = project.latlng;
	this.bounds_ = new google.maps.LatLngBounds();
	this.map_ = map;
	this.div_ = null;
	this.project = project;
	this.setMap(map);
}
infoWindow.prototype = new google.maps.OverlayView();
infoWindow.prototype.onAdd = function() {
	this.div_ = $('info-window');
	this.map_point = this.getProjection().fromLatLngToDivPixel(this.project.latlng);
	this.bounds_.extend(this.latlng_);
	
	// close any open window
	closeWindow();
	
	// set the current project & default tab;
	// set the printable button href;
	// show the info window
	current_project = this.project;
	changeTab(1);
	$('printable').set('href', url.print+'id='+this.project.project_id);
	this.div_.setStyle('display', 'block');
	
	// pin it to the map
	this.getPanes().floatPane.appendChild(this.div_);
	
	// center the map (almost; let us see the info window)
	this.map_.panTo(this.getProjection().fromDivPixelToLatLng(new google.maps.Point(this.map_point.x, this.map_point.y - 170)));
	
	debug('infoWindow project.project_id', this.project.project_id);
}
infoWindow.prototype.draw = function() {
	// position the window
	var projection = this.getProjection();
	var pixel = projection.fromLatLngToDivPixel(this.latlng_);
	var dimensions = this.div_.getDimensions();
	var vert = pixel.x - (dimensions.width / 2.03); // window width
	var horiz = pixel.y - dimensions.height - 29; // icon height
	this.div_.setStyle('left', vert+'px');
	this.div_.setStyle('top', horiz+'px');
}
infoWindow.prototype.onRemove = function() {
	this.div_.parentNode.removeChild(this.div_);
	this.div_ = null;
}


// hide the info window
function closeWindow() {
	// reset the window and close it
	changeTab(0);
	$('info-window').setStyle('display', 'none');
}


// info window tab navigation
function changeTab(num) {
	// clear selection
	$$('a.tab').removeClass('selected');
	
	if (num == 0) { // pass 0 if resetting info window
		$('project-body').set('html', '');
		$$('a.tab')[0].addClass('selected');
		
	} else { // pass 1, 2, or 3 for tab number (details, pray, go/give)
		$('project-body').set('html', current_project.tabs[num - 1]);
		$$('a.tab')[num - 1].addClass('selected');
		current_project.info_window.draw();
				
	}
	// add email click function
	$$('#info-window a.email').addEvent('click', function() {
		noSpam(this.innerHTML);
	});
}


// display results html
function publishResults() {
	// unhide results
	$('results').setStyle('display', 'block');
	
	// while you're at it, make the icons clickable
	$$('.result-click').addEvent('click', function() {
		new Fx.Scroll(window).toElement('search');
		var project = data.projects[this.id.split('result_').join('')];
		project.info_window = new infoWindow(project);
	});
	
	// update page navigation
	/*$('current-page').set('html', current_page);
	$('total-pages').set('html', total_pages);
	if (current_page != 1) {
		$('prev-page').addEvent('click', function(e) {
			e.stop();
			getProjects(current_page - 1);
		});
		$('prev-page').removeClass('dead');
	} else {
		$('prev-page').addClass('dead');
	}
	if (current_page != total_pages) {
		$('next-page').addEvent('click', function(e) {
			e.stop();
			getProjects(current_page + 1);
		});
		$('next-page').removeClass('dead');
	} else {
		$('next-page').addClass('dead');
	}*/
	
	// add email click action to results
	$$('#results a.email').addEvent('click', function() {
		noSpam(this.innerHTML);
	});
	
	// show results
	//new Fx.Tween('results', {'property': 'opacity'}).start(0, 1);
	new Fx.Tween('results', {'property': 'opacity'}).start(1);
	
	// reset the results min-height to auto
	//$('results').setStyle('min-height', 0);
}


// toggle markers by type (color)
function toggleMarkers(color) { // show/hide, red/blue/green/black
	if (markers && markers.length) {
		markers.each(function(marker) {
			if (marker.color == color) {
				if (marker.getVisible()) {
					marker.setVisible(false);
					$('bom-toggle-marker-'+color).removeClass('selected');
				} else {
					marker.setVisible(true);
					$('bom-toggle-marker-'+color).addClass('selected');
				}
			}
		});
	}
}
function setMarkerToggles() {
	if (markers && markers.length) {
		$$('.toggle-marker').removeClass('selected');
		var colors = [];
		markers.each(function(marker) {
			colors.push(marker.color);
		});
		colors.each(function(color) {
			$('bom-toggle-marker-'+color).addClass('selected');
		});
	}
}


// clear markers
function clearMarkers() {
	if (markers && markers.length) {
		markers.each(function(marker) {
			marker.setMap(null);
		});
	}
	markers = null;
	$$('.toggle-marker').removeClass('selected');
}


// clear the results list
function resetResults() {
	var html = [];
	
	// hide the results
	//$('results').setStyle('display', 'none');
	
	// set the results min-height (so it doesn't knock us around every time we click 'next' or 'search'
	$('results').setStyle('min-height', $('results').getDimensions().height);
	
	// reset results counter
	results_counter = 0;
	
	// begin results table with column headers
	html.push('<table cellpadding="0" cellspacing="0" border="0">');
	html.push('<t><th class="icon-td">&nbsp;</th><th>Project</th><th>Duration</th><th>Location</th><!--<th>Organizer</th>!--><th class="rightmost">Contact</th></tr>');
	html.push('</table>');
	
	// set table on page
	$('results-wrap').set('html', html.join(''));
	
	// kill html
	html = null;
}


// prevent email harvesting
function noSpam(string) {
	window.location = "mailto:" + string.split(' [at] ').join('@');
}


// debug function
function debug(name, msg) {
	if (debug_mode && window.console) {
		console.log(name);
		console.log(msg);
	}
}




