/* global.js v2 */

// setup the app
var debug_mode = true;
var map;
var center = [30, -30];
var bounds;
var autozoom = [1, 5];
var json = false;
var data;
var current_page;
var total_pages;
var per_page = 9;
var current_location;
var results_counter;
var url = {
	projects:   '/applications/missiondata/data.aspx',
	locations:  '/applications/missiondata/dataLocations.aspx',
	categories: '/applications/missiondata/dataCategory.aspx',
	timeframes: '/applications/missiondata/dataTimeframe.aspx',
	printable:  '/applications/missiondata/printable.aspx'
}

// on dom ready
window.addEvent('domready', function() {
	// hide elements which will be fading in later
	var to_hide = new Array(
		$('map'),
		$('invalid'),
		$('no_results'),
		$('results')
	);
	to_hide.each(function(h_el) {
		h_el.setStyle('opacity', 0);
	});
	
	// prevent double-clicks
	var no_dbl = new Array(
		$('get_projects'),
		$('prev_page'),
		$('next_page')
	);
	no_dbl.each(function(n_el) {
		n_el.addEvent('dblclick', function() {
			return false;
		});
	});
	
	// form buttons click
	$('get_projects').addEvent('click', function() {
		getProjects();
	});
	$('clear_form').addEvent('click', function() {
		clearForm();
	});
	
	// about us click events
	$('show_about').addEvent('click', function() {
		aboutUs(true);
	});
	$('hide_about').addEvent('click', function() {
		aboutUs(false);
	});
	$$('a.email').addEvent('click', function() {
		noSpam(this.innerHTML);
	});
	
	// info window elements click
	$$('a.tab').addEvent('click', function() {
		changeTab(this.id);
	});
	$('close_window').addEvent('click', function() {
		closeWindow();
	});
	
	// load locations, categories, and time-frames
	getLocations();
	getCategories();
	getTimeframes();
	
	// pre-load target and results images
	var to_preload = new Array(
		'/beonmission/_img/target_1.png',
		'/beonmission/_img/target_2.png',
		'/beonmission/_img/target_3.png',
		'/beonmission/_img/target_4.png',
		'/beonmission/_img/target_5.png',
		'/beonmission/_img/target_6.png',
		'/beonmission/_img/target_7.png',
		'/beonmission/_img/target_8.png',
		'/beonmission/_img/target_9.png',
		'/beonmission/_img/target_shadow.png',
		'/beonmission/_img/result_1.png',
		'/beonmission/_img/result_2.png',
		'/beonmission/_img/result_3.png',
		'/beonmission/_img/result_4.png',
		'/beonmission/_img/result_5.png',
		'/beonmission/_img/result_6.png',
		'/beonmission/_img/result_7.png',
		'/beonmission/_img/result_8.png',
		'/beonmission/_img/result_9.png',
		'/beonmission/_img/result_view.png'
	);
	new Asset.images(to_preload);
});

// on load
window.addEvent('load', function() {

	// load the map
	loadMap();
	
	// show map
	new Fx.Style('map', 'opacity').start(0, 1);
});

// on unload
window.addEvent('unload', GUnload);

// build the map
function loadMap() { // build the map
	if (GBrowserIsCompatible()) {
		map = new GMap2($('map'));
		map.addControl(new GLargeMapControl());
		//map.addControl(new GMapTypeControl());
		map.setCenter(new GLatLng(center[0], center[1]), 2); // lat, lng, zoom
		map.setMapType(G_NORMAL_MAP); // options: G_NORMAL_MAP, G_HYBRID_MAP, G_SATELLITE_MAP
		
		// make the info window stay where it should upon zooming
		GEvent.addListener(map, "zoomend", function() {
			if ($('info_window').getStyle('display') != 'none') {
				positionWindow(current_project);
			}
		});
	}
}

// clear the form
function clearForm() {
	// reset fields
	$('location').value = '';
	$('category').value = '';
	$('timeframe').value = '';
	
	// hide alerts
	$$('.alert').each(function(a_el) {
		if (a_el.getStyle('opacity') > 0) {
			new Fx.Style(a_el, 'opacity', {onComplete: function() {
				a_el.setStyle('display', 'none');
			}}).start(1, 0);
		}
	});
}

// populate search fields
function getLocations() {
	var json = new Json.Remote(url.locations, {method: 'get', onComplete: function(response) {
		debug('getLocations', response);
		var continents = response.locations;
		for (var i in continents) { // add continents as optgroups
			var continent = i;
			if (continent) {
				c_el = new Element('optgroup', {'label': continent+' - '}).injectInside('location');
				var regions = continents[i];
				regions.each(function(region) { // add regions as options
					if (region) {
						r_el = new Element('option', {'value': region}).setHTML(region);
						r_el.injectInside(c_el);
					}
				});
			}
			$('location').setStyle('width', '100%');
		}
		c_el = null;
		r_el = null;
	}}).send();
}
function getCategories() {
	var json = new Json.Remote(url.categories, {method: 'get', onComplete: function(response) {
		debug('getCategories', response);
		var categories = response.categories;
		categories.each(function(category) { // add categories as options
			if (category) {
				c_el = new Element('option', {'value': category}).setHTML(category);
				c_el.injectInside('category');
			}
			$('category').setStyle('width', '100%');
		});
		c_el = null;
	}}).send();
}
function getTimeframes() {
	var json = new Json.Remote(url.timeframes, {method: 'get', onComplete: function(response) {
		debug('getTimeframes', response);
		var timeframes = response.timeframes;
		timeframes.each(function(timeframe) { // add time-frames as options
			if (timeframe) {
				tf_el = new Element('option', {'value': timeframe}).setHTML(timeframe);
				tf_el.injectInside('timeframe');
			}
			$('timeframe').setStyle('width', '100%');
		});
		tf_el = null;
	}}).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').getValue()) || 0;
	var category = escape($('category').getValue()) || 0;
	var timeframe = escape($('timeframe').getValue()) || 0;
	if (!location && !category && !timeframe) { // you must choose at least one search param
		// show invalid message
		$('invalid').setStyle('display', 'block');
		new Fx.Style('invalid', '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').each(function(a_el) {
		if (a_el.getStyle('opacity') > 0) {
			new Fx.Style(a_el, 'opacity', {onComplete: function() {
				a_el.setStyle('display', 'none');
			}}).start(1, 0);
		}
	});
	
	// scroll to top
	//new Fx.Scroll(window).toTop();
	
	// hide results
	if ($('results').getStyle('opacity') > 0) {
		new Fx.Style('results', 'opacity').start(1, 0);
	}
	
	// hide map
	new Fx.Style('map', 'opacity', {onComplete: function() {
														 
		// reset the app
		resetResults();
		closeWindow();
		map.clearOverlays();
		map.setCenter(new GLatLng(center[0], center[1]), 2);
		bounds = new GLatLngBounds();
		
		// we're using json; pass parameters via 'send' method
		var post = 'inLocation='+location+'&inCategory='+category+'&inTimeframe='+timeframe+'&pageNum='+page_num;
		debug('post', post);
		debug('current_page', current_page);
		json = new Ajax(url.projects, {method: 'post', data: post, onComplete: buildProjects}).request();
		//json = new Ajax(url.projects+'?'+post, {method: 'get', onComplete: buildProjects}).request();
		
	}}).start(1, 0);
}

// set up each location one by one
function buildProjects(response) { // auto-passed the resulting object from our json call
	debug('getProjects', response);
	// set some variables
	data = Json.evaluate(response);
	total_pages = data.total_pages;
	var i = 0;
	
	if (!data.projects.length) { // no results found
		
		// show no results message
		$('no_results').setStyle('display', 'block');
		new Fx.Style('no_results', 'opacity').start(0, 1);
		$('location').focus();
		
	} else { // results found
		
		data.projects.each(function(project) { // for each project
			debug('project.id', project.id);
			
			// assemble html tabs & project results
			project.tabs = new Array(); // holds tab html
			project.results = new Hash(); // holds who, what, when, where, contact; also other snippets as we see fit
			
			// tab 1: details (where, when, who, what)
			var html = new Array();
			// 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 = project.name;
			html.push('<tr><td class="tbl_left" valign= "top">What:</td><td valign="top">'+project.name+' - '+project.description+'</td></tr>');		
			// when
			// not necessary with pre-formatted dates:
			/////var date_start = parseFloat(project.date.start.substring(5, 7))+'/'+parseFloat(project.date.start.substring(8, 10))+'/'+project.date_start.substring(0, 4);
			// not necessary with pre-formatted dates:
			/////var date_end = parseFloat(project.date.end.substring(5, 7))+'/'+parseFloat(project.date.end.substring(8, 10))+'/'+project.date.end.substring(0, 4);
			// remove seconds
			if (project.date.start) {
				project.date.start = project.date.start.substring(0, project.date.start.indexOf(' '));
			}
			if (project.date.end) {
				project.date.end = project.date.end.substring(0, project.date.start.indexOf(' '));
			}
			// formulate time frame
			if (project.timeframe) {
				project.results.when = project.timeframe;
				if (project.date.start) {
					project.results.when += ' - '+project.date.start;
					if (project.date.end) {
						project.results.when += ' to '+project.date.end;
					}
				} else if (project.date.end) {
					project.results.when += ' - '+project.date.end;
				}
			} else if (project.date.start) {
				project.results.when = project.date.start;
				if (project.date.end) {
					project.results.when += ' to '+project.date.end;
				}
			} else if (project.date.end) {
				project.results.when = project.date.end;
			} else {
				project.results.when = 'To be determined';
			}
			html.push('<tr><td class="tbl_left" valign= "top">When:</td><td valign="top">'+project.results.when+'</td></tr>');		
			// where
			if (project.location.city) {
				project.results.where = project.location.city;
				if (project.location.state) {
					project.results.where += ', '+project.location.state;
				} else if (project.location.country) {
					project.results.where += ', '+ project.location.country;
				}
			} else if (project.location.state) {
				project.results.where = project.location.state;
				if (project.location.country) {
					project.results.where += ', '+project.location.country;
				}
			} else if (project.location.country) {
				project.results.where = project.location.country;
			} else {
				project.results.where = "To be determined";
			}
			html.push('<tr><td class="tbl_left" valign= "top">Where:</td><td valign="top">'+project.results.where+'</td></tr>');		
			// who
			project.results.who = project.organization;
			html.push('<tr><td class="tbl_left" valign= "top">Who:</td><td valign="top">'+project.results.who+'</td></tr>');		
			// finish
			html.push('</table>');
			project.tabs.push(html.join(''));
			
			// tab 2: pray (prayer requests)
			var html = new Array();
			// heading
			html.push('<p class="heading">Here\'s how you can pray...</p>');
			// ul
			html.push('<ul class="prayer_requests">');
			var no_pr = true;
			for (var j = 0; j < project.prayer.length; j++) {
				if (project.prayer[j]) { // valid prayer request
					if (project.prayer[j].contains('http://')) { // prayer request has a url; make it a hyperlink
						var url_start = project.prayer[j].indexOf('http://');
						var before = project.prayer[j].substr(0, url_start);
						var url_end;
						var url = project.prayer[j].substr(url_start);
						if (url.contains(' ')) {
							url_end = url.indexOf(' '); // go to next space
							url = url.substr(0, url_end);
						}
						if (url.contains(',')) {
							url_end = url.indexOf(','); // or comma
							url = url.substr(0, url_end);
						}
						if (url.contains(';')) {
							url_end = url.indexOf(';'); // or semicolon
							url = url.substr(0, url_end);
						}
						html.push('<li><span>'+before+'[<a href="'+url+'" target="blank">more</a>]</span></li>');
						url_start = null;
						url_end = null;
						url = null;
						before = null;
					} else { // no url found in prayer request
						html.push('<li><span>'+project.prayer[j]+'</span></li>');
					}
					var no_pr = false;
				}
			}
			if (no_pr) { // there are no prayer requests at all
				html.push('<li><span>Please pray for this ministry.</span></li>');
			}
			// finish
			html.push('</ul>');
			project.tabs.push(html.join(''));
	
			// tab 3: go/give/partner (contact info)
			var html = new Array();
			// heading
			html.push('<p class="heading">For info on how to give, go, or partner...</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.name+'</td></tr>');
			// address
			project.results.address = '';
			project.contact.address.each(function(line) {
				if (line) {
					project.results.address += line+'<br />';
				}
			});
			html.push('<tr><td class="tbl_left" valign="top">Address:</td><td valign="top">'+project.results.address+'</td></tr>');
			// phone
			project.results.phone = project.contact.phone.substring(0, 3)+'.'+project.contact.phone.substring(3, 6)+'.'+project.contact.phone.substring(6, 10);
			html.push('<tr><td class="tbl_left" valign="top">Phone:</td><td valign="top">'+project.results.phone+'</td></tr>');
			// email
			project.results.email = '<a class="email" href="javascript:;">'+project.contact.email.split('@').join(' [at] ')+'</a>';
			html.push('<tr><td class="tbl_left" valign="top">Email:</td><td valign="top">'+project.results.email+'</td></tr>');
			// website (optional)
			if (project.contact.url) {
				project.results.website = '<a href="'+project.contact.url+'" target="_blank">open in a new window</a>';
				html.push('<tr><td class="tbl_left" valign="top">Website:</td><td valign="top">'+project.results.website+'</td></tr>');
			}
			// finish
			html.push('</table>');
			project.tabs.push(html.join(''));								   
			
			// set marker latlng and opts in project
			project.latlng = new GLatLng(project.location.lat, project.location.lng);
			project.opts = {
				title: project.results.where,
				icon:  chooseTargetIcon(i + 1)
			};
			
			// kill html
			html = null;
			
			// place the marker on the map
			project.tabs = project.tabs;
			addMarker(project);
			buildResult(project);
			
			// iterate
			i ++;
		});
		
		// show results list
		publishResults(data.projects.length);
	
	} // end results found
	
	// zoom to the boundary
	if (!bounds.isEmpty()) {
		map.setCenter(bounds.getCenter());
		var zoom_to = map.getBoundsZoomLevel(bounds) - 1;
		if (zoom_to < autozoom[0]) {
			zoom_to = autozoom[0];
		} else if (zoom_to > autozoom[1]) {
			zoom_to = autozoom[1];
		}
		debug('zoom_to', zoom_to);
		map.setZoom(zoom_to);
	}
	
	// show map
	new Fx.Style('map', 'opacity').start(0, 1);
	
	// re-click-able-ize button
	$('get_projects').addEvent('click', function() {
		getProjects();
	});
}

// get the appropriate icon for the marker number
function chooseTargetIcon(number) {
	var icon = new GIcon();
	icon.image = "_img/target_"+number+".png";
	icon.shadow = "_img/target_shadow.png";
	icon.iconSize = new GSize(22, 34);
	icon.shadowSize = new GSize(38, 40);
	icon.iconAnchor = new GPoint(11, 32);
	icon.infoWindowAnchor = new GPoint(11, 32); // same as iconAnchor
	return icon;
}

// add a marker to the map
function addMarker(project) {
	// make a new marker and extend boundary to accommodate it
	project.marker = new GMarker(project.latlng, project.opts);
	bounds.extend(project.latlng);
	
	// on marker click, open the info window
	GEvent.addListener(project.marker, "click", function() {
		this.openCustomInfoWindow(project);
	});
	
	map.addOverlay(project.marker);
}

// get the apprropriate icon for the result number
function chooseResultIcon(number) { 
	return '<img class="result_icon" id="result_'+number+'" src="/beonmission/_img/result_'+number+'.png" title="View this project" />';
}

// create a result line for the project
function buildResult(project) {
	var html = new Array();
	
	// 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 = new Array();
	tds.push(new Element('td', {'class': 'icon_td'}).setHTML(chooseResultIcon(results_counter + 1)));
	tds.push(new Element('td').setHTML(project.results.what));
	tds.push(new Element('td').setHTML(project.results.when));
	tds.push(new Element('td').setHTML(project.results.where));
	tds.push(new Element('td').setHTML(project.results.who));
	tds.push(new Element('td', {'class': 'rightmost_td'}).setHTML(project.results.email));
	
	// finish tr
	tds.each(function(td_el) {
		td_el.injectInside(tr_el);
	});
	
	// set results in table
	var tbody_el = $$('#results_wrap table tbody')[0];
	tr_el.injectInside(tbody_el);
	
	// iterate
	results_counter++;
	
	// kill vars
	html = null;
	tr_el = null;
	tds = null;
	tbody_el = null;
}

// display results html
function publishResults() {
	// unhide results
	$('results').setStyle('display', 'block');
	
	// while you're at it, make the icons clickable
	$$('.result_icon').addEvent('click', function() {
		new Fx.Scroll(window).toElement('menu');
		var project = data.projects[this.id.split('result_').join('') - 1];
		project.marker.openCustomInfoWindow(project);
	});
	
	// update page navigation
	$('current_page').setHTML(current_page);
	$('total_pages').setHTML(total_pages);
	if (current_page != 1) {
		$('prev_page').addEvent('click', function() {
			getProjects(current_page - 1);
		});
		$('prev_page').removeClass('dead');
	} else {
		$('prev_page').addClass('dead');
	}
	if (current_page != total_pages) {
		$('next_page').addEvent('click', function() {
			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.Style('results', 'opacity').start(0, 1);
	
	// reset the results min-height to auto
	//$('results').setStyle('min-height', 0);
}

// clear the results list
function resetResults() {
	var html = new Array();
	
	// 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').getSize().size.y);
	
	// reset results counter
	results_counter = 0;
	
	// begin results table with column headers
	html.push('<table cellpadding="0" cellspacing="0" border="0">');
	html.push('<tr class="header"><td class="icon"><img class="result_view" src="/beonmission/_img/result_view.png" /></td><td>What:</td><td>When:</td><td>Where:</td><td>Who:</td><td class="rightmost">Contact:</td></tr>');
	html.push('</table>');
	
	// set table on page
	$('results_wrap').setHTML(html.join(''));
	
	// kill html
	html = null;
}

// get the map point (for info window placement)
function getMapPoint(project) {
	return map.fromLatLngToDivPixel(project.marker.getPoint());
}

// extend google code to ease use of our custom info window
GMarker.prototype.openCustomInfoWindow = function(project) {
	var info_window = $('info_window');
	var map_point = getMapPoint(project);
	
	// close any open window
	closeWindow();
	
	// set the current project & default tab; set the printable button href; show the info window
	current_project = project;
	changeTab(1);
	$('printable').setProperty('href', url.printable+'?printID='+project.id);
	info_window.setStyle('display', 'block');
	
	// position the window and pin it to the map
	positionWindow(project);
	map.getPane(G_MAP_MARKER_PANE).appendChild(info_window);
	
	// center the map (almost; let us see the info window)
	map.panTo(map.fromDivPixelToLatLng(new GPoint(map_point.x, map_point.y - 130)));
	
	debug('project.id', project.id);
}

// info window tab navigation
function changeTab(num) {
	// clear selection
	$$('a.tab').removeClass('selected');
	
	if (num == 0) { // pass 0 if resetting info window
		$('project_body').setHTML('');
		$$('a.tab')[0].addClass('selected');
		
	} else { // pass 1, 2, or 3 for tab number (details, pray, go/give)
		$('project_body').setHTML(current_project.tabs[num - 1]);
		$$('a.tab')[num - 1].addClass('selected');
		positionWindow(current_project);
				
	}
	// add email click function
	$$('#info_window a.email').addEvent('click', function() {
		noSpam(this.innerHTML);
	});
}

// position the info window
function positionWindow(project) { // position the window over the corresponding marker
	var info_window = $('info_window');
	var map_point = getMapPoint(project);
	
	var vert_pos = parseInt(map_point.y) - info_window.offsetHeight - 26; // - 15 ??
	info_window.setStyle('top', vert_pos + 'px');
	
	var horiz_pos = parseInt(map_point.x) - 143; // - 50 ??
	info_window.setStyle('left', horiz_pos + 'px');
}

// hide the info window
function closeWindow() {
	// reset the window and close it
	changeTab(0);
	$('info_window').setStyle('display', 'none');
}

// prevent email harvesting
function noSpam(string) {
	window.location = "mailto:" + string.split(' [at] ').join('@');
}

// about us
function aboutUs(show) { // action is true/on (show) or false/off (hide)
	var fade = new Fx.Style('sidebar', 'opacity');
	fade.addEvent('onComplete', function() {
		if (show) { // show
			$('intro').setStyle('display', 'none');
			$('search').setStyle('display', 'none');
			$('about_us').setStyle('display', 'block');
		} else { // hide
			$('about_us').setStyle('display', 'none');
			$('intro').setStyle('display', 'block');
			$('search').setStyle('display', 'block');
		}
		if (window.webkit) {
			var to = .9999999;
		} else {
			var to = 1;
		}
		new Fx.Style('sidebar', 'opacity').start(0, to);	
	});
	fade.start(1, 0);
}

// debug function
function debug(name, msg) {
	if (debug_mode && window.console) {
		console.log(name);
		console.log(msg);
	}
}




