var currentElectionYear = '08';

var graph;
var infoid;
var offsetX;
var offsetY;
var tooltipOffsetX;
var tooltipOffsetY;
var statusCode;
var statusString;
var cachedate ="";
var currentid;
var graphviz;
var debug = 0; //debugging mode on or off
var tooltip;
var lastType = "";
var current= new Array();
current['candidate'] = '';
current['company']='';	
current['congress_num']='';	
current['view'] = 'graphs';

var qparams = window.location.search.toQueryParams();
	function getFormData() {
		//Element.extend($('form'));
		var data="";
		data = Form.serialize($('form'));
		return data;
		for (var i =0; i < document.form.elements.length; i++) {
			var field = document.form.elements[i];
			if(field.name != 'undefined') {
				data += "&"+field.name+'='+field.value;
			}
		}
		return data.substring(1, data.length);
	}

	//Catches mousemove events
	function mousemove(e) {
		//var tempnodes = new Array();
		var mousepos = { 'x': Event.pointerX(e), 'y': Event.pointerY(e) };
		//$('debug').innerHTML = mousepos['y'] +' '+ mousepos['x'] + ' ' +(mousepos['y']- offsetY) +','+ (mousepos['x'] - offsetX);
		//tooltip.style.top = (mousepos['y'] -20 )+'px';
		//tooltip.style.left = (mousepos['x'] + 60 - Position.cumulativeOffset($('graphs'))[0]) +'px';
		tooltip.style.left = (mousepos['x']  - tooltipOffsetX) + 'px';
			//console.log(mousepos['x'] + ' '+ mousepos['y'] + ' '+tooltip.style.top+ ' ' +tooltip.style.left + ' ' + tooltipOffsetX);
			//$('debug').innerHTML = mousepos['y']+tooltip.style.top;
		tooltip.style.top = (mousepos['y']- tooltipOffsetY) + 'px';
	}

	function catchTimeout(request) {
		if ($('error').visible()) {
			$('error').hide();
			toggleDisplay('graphs');
		}
		requesttimeout = new PeriodicalExecuter(
			function() {
				if (request.readyState > 0 && request.readyState < 4) {
					statusCode=10;
					statusString = "Server took too long to return data, it is either busy or there is a connection problem";
					request.abort();
					reportError(statusCode, statusString);
				}
			}
		, 90);
	}

	function catchFailure(response) {
			reportError(-1, "There was a problem contacting the server:"+response.status+":"+response.statusText);
	}

	function checkResponse(response) {
		var statusCode = null;
		var statusString = "something went wrong";  
		try {   //need this incase there is giberish and eval() throws js errors
			if (eval(response.responseText)) { 
			} else { //probably means it was stopped by time out
			   reportError(statusCode,statusString);
			}
		} catch (e) {}
			
		//console.log(statusCode);
		if (!statusCode){  //NO STATUS CODE
		   reportError(-1, "Unknown response from server:\n\n"+response.responseText);
		} else if(statusCode == 1) { //EVERYTHING OK
			return 1;
		} else {  //STATUS INDICATES AN ERROR
		   reportError(statusCode, statusString);
		}
		return 0;	
	}

	function highlight(id, text) {
		setOffsets();
		if(typeof graphviz[id] == 'undefined') { id = currentid; }
		if (graphviz[id] && (infoid != id || $('info').style.display == 'none')) {
			var node = graphviz[id];
			currentid = id;
			//$('debug').innerHTML += node['label'];
			showTooltip(text); //Set the tooltip contents
			//tooltip.style.top = parseFloat(node['posy'])-10 + offsetY - tooltip.clientHeight + 'px'; //Move the tooltip, offset 10 pixels from the point
			//tooltip.style.left = parseFloat(node['posx'])+ 10 + offsetX + 'px'; 
			$('highlight').style.width = parseFloat(node['width']) +6 +'px';
			$('highlight').style.height = parseFloat(node['height']) +6 +'px';
			$('highlight').style.top = parseFloat(node['posy']) -3 + offsetY + 'px';
			$('highlight').style.left = parseFloat(node['posx']) -3 + offsetX + 'px';
			$('highlight').style.visibility = 'visible';
			if (node['shape'] != 'circle') { 
				$('highlight').addClassName('selected');
				$('highlightimg').style.visibility = 'hidden';
			} else {
				$('highlight').removeClassName('selected');
				$('highlightimg').style.visibility = 'visible';
			}
			//$('debug').innerHTML += '('+node['posx']+' '+ offsetX;
		}
	}

	function showTooltip(label) {
		setOffsets;
		if(label) { 
			tooltip.innerHTML = label;
		}
		tooltip.style.visibility='visible'; //show the tooltip
	};
	
	function hideTooltip() { 
		$('highlight').style.visibility = 'hidden';
		$('highlightimg').style.visibility = 'hidden';
		tooltip.style.visibility='hidden'; //hide the tooltip first - somehow this makes it faster
		$('images').style.cursor = 'default';	
		currentid = "";
	}

	//Catches click events
	function showInfo(id) {
		if (!$(id)) { return; }
		setOffsets();
		if(typeof graphviz == 'undefined' || graphviz == null ) { return; }
		if(typeof graphviz[id] == 'undefined') { id = currentid; }
		if (graphviz[id] && (infoid != id || $('info').style.display == 'none')) {
			var node = graphviz[id];
			$('info').style.display = 'none'; 
			//toggleTabs('pvs');
			//$('debug').innerHTML = closest;	
			$('tooltip').style.visibility = 'hidden';
			Effect.Appear('info', {duration: .8, to: .9});
			var width = parseFloat(node['width']);
			var diff = ((width/2)*Math.sqrt(2)) - (width/2);
			if (node['shape'] != 'circle') {
				$('info').style.left = (parseFloat(node['posx']) +  offsetX - 62 + width) + 'px';
				$('info').style.top = (parseFloat(node['posy']) + offsetY- 184) + 'px';
				current['candidate'] = id;
			} else {
				//console.log(diff);
				$('info').style.left = (parseFloat(node['posx']) +  offsetX - 60 + width) - diff + 'px';
				$('info').style.top = (parseFloat(node['posy']) + offsetY- 186) + diff + 'px';
				current['company'] = id;
			}
			getInfo(id);
			
		}
		updateLink();
	}

	function getInfo(id) {
		if(typeof graphviz[id] == 'undefined') { id = currentid; }
		var node = graphviz[id];
		loading($('infocontenttext'));
		//document.getElementById('infocontenttext').innerHTML ="<p>looking up "+node['label']+"...</p>";
		var response = "lookup error";
		var params = getFormData();
		params += '&id='+id+'&action=show'+node['type']+'Info'+"&setupfile="+setupfile;
		new Ajax.Request('request.php', {
			method: 'get',
			parameters: params,
			onComplete: function(resp) {
				pageTracker._trackPageview('request.php?'+params);
				$('infocontenttext').innerHTML =  resp.responseText;
			}
		});
	}

	//Fetches the mouse position, returns an array object containing the x and y coords
	function getMouseXY(e) {
		var mousepos = new Array();
		return mousepos;
	}

	//This function runs once the page has loaded, and sets the ball rolling
	function setupTooltips() {
		tooltip = document.getElementById('tooltip');
		//var xmlDoc = importXML(); 	//fetch the xml doc
		//nodes = parseXML(xmlDoc);	//parse the xml, setting up the event listeners
		var img = $('img0');
		graph = new Array();
		graph['items'] = new Array();
		graph['img'] = img;	//store a reference to the image in the nodes object
		graph['mouserange'] = 8;
		Event.observe(img, 'mousemove', mousemove);
		Event.observe($('info'), 'mousemove', mousemove);
//		Event.observe($('img0'), 'mousedown', function() {Effect.Fade($('info'), {duration: .5}); });
		Event.observe($('highlight'), 'mousemove', mousemove);
		Event.observe($('tooltip'), 'mousemove', mousemove);
//		Event.observe($('G'), 'mousemove', mousemove);
		Event.observe($('highlight'), 'mouseover', highlight);
		//Event.observe($('img0'), 'mouseout', function() { tooltip.style.visibility = 'hidden'; } );
		//Event.observe($('tail'), 'mouseout', function() { tooltip.style.visibility = 'hidden'; } );
		Event.observe($('highlightimg'), 'mouseout', hideTooltip);
		Event.observe($('highlight'), 'mouseout', hideTooltip);
		Event.observe($('tooltip'), 'mouseout', hideTooltip);
		//Event.observe($('img0'), 'mousedown', click );
		//Event.observe($('tail'), 'mousedown', click );
		Event.observe($('highlight'), 'mousedown', showInfo);
		Event.observe(window, 'resize', setOffsets );
		//Event.observe($('graphs'), 'mouseout', hideTooltip);
		window.setTimeout("setOffsets()", 250);
	}

function setOffsets() {
	if ($('img0')) {
		offsetX = Position.positionedOffset($('img0'))[0];
		offsetY = Position.positionedOffset($('img0'))[1];
		//tooltip.style.top = '0px';
		//tooltip.style.left = '0px';
		tooltipOffsetX = Position.cumulativeOffset($('graphs'))[0] -65;
		tooltipOffsetY = 25;
		//tooltipOffsetY = 25;
	}
}


function lookupGraph(params) {
	//$('title').innerHTML = "";
	$('info').style.display='none';
	$('imagescreen').style.display = 'none';
	$('imagescreen').style.width = '0px';
	$('imagescreen').style.height = '0px';
	$('images').style.height = 'auto';
	$('images').style.display =  'block';
        $('images').innerHTML = "<span id='loading'><img src='images/loading.gif' width='220' height='19' style='vertical-align: middle; border:none;' alt='loading file icon'><br/><span id='message'>Loading...</span></span>";
	img = "";
	imagemap = "";
	nodeX = 0;
	count = 0;
	var requesttimeout;
	//params = getFormData();
	//params = $('form').serialize(true);
	new Ajax.Request('request.php', {
		method: 'post', 
		parameters: params,
		//parameters: "",
		onLoading: catchTimeout,
		onComplete: function(response,json) {
			pageTracker._trackPageview('request.php?'+params);
			if (requesttimeout && requesttimeout.currentlyExecuting) { requesttimeout.stop(); }
			if (checkResponse(response)) {
				$('images').innerHTML = "";
				//if (cachedate) { cachedate = "<br><span style='font-size: .7em;'>Image cached on "+cachedate+"</span>"; }	
				//$('images').innerHTML = "<img id='img0' border=0 src='"+img+"' usemap='#G'/>"+cachedate+"<!--<br><a href='"+dotfile+"'>  Download Graphviz .dot file</a> | <a href='unfluence.html?"+getFormData()+"'>Link to this graph</a></p>-->"+imagemap;
				$('images').update("<img id='img0' border=0 src='"+img+"' usemap='#G'/>"+imagemap);
				setupTooltips();
				cachedate = "";
				$('G').descendants().each(function(a) { 
					if (a.id.search('_') != -1) { 
						Event.observe($(a), 'mouseout', hideTooltip, 1); 
						Event.observe($(a), 'mousemove', mousemove);
					}
				});
			}
		},
		onFailure: catchFailure
	});
}

function loading(element) {
	$(element).innerHTML = "<div class='loading' id='loading"+element+"' style='text-align: center; margin: 20px; background-color: white;'><img src='images/loading.gif' width='220' height='19' style='vertical-align: middle; border:none;margin: 15px;' alt='Loading Data'><br/><span id='message'>Loading..</span></div>";
}

function toggleTabs(id) {
	var offid = (id == 'pvs') ? 'nimsp' : 'pvs';
	$(offid).style.display = 'none';
	Effect.Appear($(id), {duration: .5});
	$(id+'tab').style.height = '21px';
	$(offid+'tab').style.height = '20px';
}

function loadform() {
	params = getFormData()+"&setupfile="+setupfile;
	lookupGraph(params);
	loadTable(params, 'candidate');
	loadTable(params, 'company');
	loadtitle(current['congress_num']);
	updateLink();
}

function initSearch() {
	$('ViewChooser').hide();
	$('graphcontent').hide();
	$('viewcotables').hide();
	$('viewtables').innerHTML = 'Table View';
	$('viewhelp').setStyle({'left': '25em'}); 
	Event.observe($('zipcode'), "keydown",
		function(event) {
			if (event.keyCode == 13) {
				$('submitbutton').click();
			}		
		}); 
	Event.observe($('name'), "keydown",
		function(event) {
			if (event.keyCode == 13) {
				$('submitbutton').click();
			}		
		}); 	
	if (qparams['zip']) { 
		$('form').zip.value = qparams['zip']; 
		findCandidates();
	} else if (qparams['can']) { findCandidates(); }

}

function showQuery() {
	$('showQuery').style.display = 'none';
	$('info').style.display = 'none';
	$('querycontainer').style.position = 'absolute';
	if ($('images').clientHeight < 260) {
		$('images').style.height = '260px';
	}
	Position.clone($('images'), $('imagescreen'));
	Position.clone($('images'), $('querycontainer'));
	//Effect.Fade($('images'), {to: .5});
	Effect.Appear($('imagescreen'), {to: .7});
	Effect.BlindDown($('query'), {duration: .7});
}

function showInset() {
	$('screen').style.height = document.body.getHeight() + 'px';
	showDetails(arguments[0], arguments[1], arguments[2]);	
	Effect.Appear($('screen'), {to: .7, duration: .3, afterFinish: function(obj) {
		Effect.BlindDown($('inset'), {duration: .5, afterFinish: function(obj){ 
			$('inset').style.overflowY = 'auto';
			$('screen').style.height = (document.body.getHeight() + $('inset').getHeight()) + 'px';
		}});
	}});
}	

function hideInset() {
	Effect.BlindUp($('inset'), {duration: .5, afterFinish: function(obj) {
		$('insetContent').update();
		Effect.Fade($('screen'), {duration: .3});
	}});
}

function toggleDisplay(type) {
	if (type != current['view']) {
		if ($('viewcotables').style.display == 'none' && type =='cotables') { type = 'tables'; } //FIXME
		$('view'+type).removeClassName('unselectedtab');
		if(! $('error').visible()) { $(type).show(); }
		$('view'+current['view']).addClassName('unselectedtab');
		$(current['view']).hide();
		current['view'] = type;	
	}
	if($('error').visible()) { return; }
	if (type == 'tables') { 
		//if (current['candidate']) { 
			$('info').style.display = 'none'; 
			lastType = 'candidate';
			window.setTimeout("showDetails('"+current['candidate']+"', 'candidate')", 500);
		//}
	} else if (type == 'cotables') { 
		//if (current['company']) { 
			$('info').style.display = 'none'; 
			lastType = 'company';
			window.setTimeout("showDetails('"+current['company']+"', 'company')", 500);
		//}
	} else if ( type == 'graphs') { 
		if ($('t'+current['candidate'])) { $('t'+current['candidate']).removeClassName('selected'); };
		if ($('t'+current['company'])) { $('t'+current['company']).removeClassName('selected') };
		if ($('c'+current['candidate'])) { $('c'+current['candidate']).removeClassName('selected'); };
		if ($('c'+current['company'])) { $('c'+current['company']).removeClassName('selected'); };
	}
	if (type == 'graphs' && current[lastType]) {
		window.setTimeout("setOffsets()", 500);
		window.setTimeout("setOffsets()", 2500);
		window.setTimeout("showInfo('"+current[lastType]+"')", 500);
	}
	updateLink();
}

function findCandidates() {
	loading('foundCandidates');
	$('searchresults').show();
	$('images').innerHTML = "";
	$('candidateInfo').innerHTML = "";
	$('candidateList').innerHTML = "";
	$('candidatedetails').innerHTML = '';
	$('title').innerHTML = "";
	$('graphcontent').hide();
	$('ViewChooser').hide();

	//$('foundCandidates').innerHTML = "";
	//$('companyInfo').innerHTML = "";
	//$('candidateList').innerHTML = "";

	//$('infoTable').innerHTML = "";
	params = $('form').serialize(true);
	if (qparams['can']) { params['gotocan'] = qparams['can']; } 
	new Ajax.Request('takeaction.php', {
	method: 'post',
	parameters: params,
		onComplete: function(resp) { 
			pageTracker._trackPageview('takeaction.php');
			$('foundCandidates').innerHTML = resp.responseText; 
			if (qparams['can']) { 
				if (qparams['congress_num']) {  
					showCandidateDetails(qparams['can']);
				}
				delete qparams['can'];
			} 
		} });
}

function showCandidateDetails(id, maxyear) {
	//console.log('candetails');
	$('ViewChooser').show();
	$('graphcontent').show();
	maxyear = 'total';
	loading('candidatedetails');
	if ($('l'+current['candidate'])) { 
		$('l'+current['candidate']).removeClassName('selected');
	}
	current['candidate'] = id;
	var racecode = id.charAt(0);
	params = "candidateids="+id+"&congress_num="+maxyear+"&racecode="+racecode+"&setupfile="+setupfile;
	$('congress_num').setAttribute('value', maxyear);
	$('racecode').setAttribute('value', racecode);
	lookupGraph(params);
	$('candidateList').style.display = 'none';
	$('candidateInfo').setStyle({'float': 'none', 'margin': '0px auto', 'display': 'block'}); 
	$('candidateids').setAttribute('value', id);
	showDetails(id, 'candidate', 1);
	$('l'+id).addClassName('selected');
	new Ajax.Request('takeaction.php', {
	method: 'post',
	parameters: "candidateid="+id,
	onComplete: function(resp) { 
		pageTracker._trackPageview('takeaction.php?candidateid='+id);
		$('candidatedetails').innerHTML = resp.responseText; 
		$(id+maxyear).addClassName('selected');
		loadtitle('total');
		if (qparams['congress_num']) { 
			loadCandidateData(id, qparams['congress_num'], racecode);
			delete qparams['congress_num'];
		}
	} });
	updateLink();
}

function loadCandidateData(id, congress_num, racecode) {
	params = "candidateids="+id+"&congress_num="+congress_num+"&racecode="+racecode+"&setupfile="+setupfile+'&type=candidate';
	if( $(current['candidate']+$('congress_num').getAttribute('value')) ) {
			$(current['candidate']+$('congress_num').getAttribute('value')).removeClassName('selected');
	}
	$('congress_num').setAttribute('value', congress_num);
	$('racecode').setAttribute('value', racecode);
	$(id+congress_num).addClassName('selected');
	loadtitle(congress_num);
	lookupGraph(params);
	$('candidateList').style.display = 'none';
	$('candidateInfo').setStyle({'float': 'none', 'margin': '0px auto'}); 
	showDetails(id, 'candidate', 1);
	if (qparams['com']) { current['company'] = qparams['com'];  delete qparams['com']; }
	if (qparams['v']) { toggleDisplay(qparams['v']); delete qparams['v']; }
	updateLink();
}

function loadtitle(congressnum) {
	var subtitle="";
	var title="";
	if($('search')) {
		title = 'Contributions to '+$('selectedcandidatename').innerHTML;
		if (congressnum == 'total') { 
			title+= " since 1999"; 
		} else if (congressnum == 'pre') { 
			title+= ' before taking office'; 
		} else { 
			title+= ' during the '+congressnum+'th congress'; 
		}
	} else if ($('congress')) { 
		title = $('racecode').options[$('racecode').selectedIndex].innerHTML + ' Members of the ' + $('congress_num').options[$('congress_num').selectedIndex].innerHTML + ' Congress';
		subtitle = 'Showing contributions greater than '+numberFormat($('minContribAmount').options[$('minContribAmount').selectedIndex].value)+', members receiving more than '+numberFormat($('minCandidateAmount').options[$('minCandidateAmount').selectedIndex].value)+', and companies giving more than '+numberFormat($('minCompanyAmount').options[$('minCompanyAmount').selectedIndex].value)+'.';		
	} else {
		title =  $('congress_num').options[$('congress_num').selectedIndex].innerHTML + ' Presidential Race';
		subtitle = 'Showing contributions greater than '+numberFormat($('minContribAmount').options[$('minContribAmount').selectedIndex].value)+', candidates receiving more than '+numberFormat($('minCandidateAmount').options[$('minCandidateAmount').selectedIndex].value)+', and companies giving more than '+numberFormat($('minCompanyAmount').options[$('minCompanyAmount').selectedIndex].value)+'.';
	}	
	$('title').innerHTML = title;
	$('subtitle').innerHTML = subtitle;
}

function reportError(code, message){
	//console.log(code+', '+message);
	$$('.loading').each ( function (e) { $(e).remove(); }); //remove any loading images
	if (code == 2) { 
		$('error').innerHTML = "<span id='loading'><span style='vertical-align: middle;' id='message'>There are no relationships to be shown.</span></span>";
		['graphs', 'tables', 'cotables', 'help'].each(function (div) { $(div).hide(); });
		$('error').show();
		return;
	}
   title = "A problem occurred while processing your request:";
   subtitle = message+" [Error code "+code+" ]" ;
   	$('title').innerHTML = title;
	$('subtitle').innerHTML = subtitle;
	$('images').innerHTML = "<span id='loading'><span style='vertical-align: middle;' id='message'>Network image was not loaded</span></span>";
}

function toggleZipOptions(div) {
	if (div == 'zipcode') { 
		other = 'name'; 
		$('candidatename').value = '';	
	} else { 
		other = 'zipcode'; 
		$('zip').value= '';	
	}
	$(other).hide();
   	$(div).show();
   	$(div+'tab').removeClassName('unselectedtab'); 
	$(other+'tab').addClassName('unselectedtab');
   	$(div+'tab').setStyle({'border-bottom': '1px solid #f2f2f2'});
   	$(other+'tab').setStyle({'border-bottom': ''});
}

function updateOptions() {
	if (qparams['c']) { qparams['congress_num'] = qparams['c']; delete qparams['c']; } //This is because I goofed, and urls went out with this param, so we need to handle it
	if (qparams['congress_num']) {
		congress_num = qparams['congress_num'];
		$('congress_num').value = congress_num;
		current['congress_num'] = congress_num;
	} else { congress_num = $F('congress_num'); }
	if (qparams['racecode']) {
		race = qparams['racecode'];
		$('racecode').value = race;
	} else { race = $F('racecode'); }
	raceopts = advanced_opts[congress_num][race];
	labels = new Array('25', '50', '75');
	for (select in raceopts) {
		options = "";
		for( var x =0; x <  raceopts[select].length; x++) {
			var selected = false;
			if (race == 'P' && select == 'minCandidateAmount') { 
				if (x == 2) { selected = true; }
			} else if (x == 0) { selected = true; }
			//options += "<option value='"+raceopts[select][x][0]+"'>"+raceopts[select][x][1]+"</option>";
			//console.log(select+' '+race+' '+x+' '+selected);
			$(select).options[x] = new Option(labels[x]+'%', raceopts[select][x][0], selected, selected);
		}
		//$(select).op = options;
	}
	var opts = new Array('minCandidateAmount', 'minContribAmount', 'minCompanyAmount');
	for (var opt in opts) {
		option = opts[opt];
		if (qparams[option] && $(option).options[qparams[option]]) {
			$(option).value = $(option).options[qparams[option]].value;
		}
	}
}

// This function formats numbers by adding commas
function numberFormat(nStr){
  nStr += '';
  x = nStr.split('.');
  x1 = x[0];
  x2 = x.length > 1 ? '.' + x[1] : '';
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(x1))
    x1 = x1.replace(rgx, '$1' + ',' + '$2');
  return '$'+x1 + x2;
}

function updateLink() {
	var link = window.location.href.replace(window.location.search, '') + '?';
	if (qparams['type']) { link += 'type=' + qparams['type'] + '&'; }
	if (current['candidate']) { link += 'can=' + current['candidate'] + '&'; }
	if (current['company']) { link += 'com=' + current['company'] + '&'; }
	if (current['view']) { link += 'v=' + current['view'] + '&'; }
	var lform = Form.serialize($('form'), true);
	['candidateids', 'candidatename', 'noheader', 'zip'].each (function(p) { delete lform[p]; });
	['minCandidateAmount', 'minContribAmount', 'minCompanyAmount'].each(function(opt) { 
		if ($(opt)) {
			lform[opt] = $(opt).selectedIndex; 
		}
	});	
	link += Hash.toQueryString(lform);
	$('linklink').value = link;
}
