// teamap.js
// Copyright (c) 2008 Michael Geary
// http://mg.to/
// Free Beer and Free Speech License (any OSI license)
// http://freebeerfreespeech.org/

// TEMP
log = _log = function() {};  log.reset = function() {};

// Outer wrapper function
(function( $ ) {

var $window = $(window);
var states = PolyMap.states;
var polyTimer;

function S() {
	return Array.prototype.join.call( arguments, '' );
}

function htmlEscape( str ) {
	var div = document.createElement( 'div' );
	div.appendChild( document.createTextNode( str ) );
	return div.innerHTML;
}

function optionHTML( value, name, selected, disabled ) {
	var id = value ? 'id="option-' + value + '" ' : '';
	var style = disabled ? 'color:#AAA; font-style:italic; font-weight:bold;' : '';
	selected = selected ? 'selected="selected" ' : '';
	disabled = disabled ? 'disabled="disabled" ' : '';
	return S(
		'<option ', id, 'value="', value, '" style="', style, '" ', selected, disabled, '>',
			name,
		'</option>'
	);
}

function randomColor() {
	return '#' + hh() + hh() + hh();
}

function randomGray() {
	var h = hh();
	return '#' + h + h + h;
}

function hh() {
	var xx = Math.floor( Math.random() *128 + 96 ).toString(16);
	return xx.length == 2 ? xx : '0'+xx;
}

(function() {
	var index = 0;
	function option( value, name, selected, disabled ) {
		var html = optionHTML( value, name, selected, disabled );
		++index;
		return html;
	}
	function stateOption( state, selected ) {
		state.selectorIndex = index;
		return option( state.abbr, state.name, selected );
	}
	
	stateSelector = function() {
		return S(
			'<select id="stateSelector">',
				option( 'us', '50 States and Puerto Rico', true ),
				option( 'counties', 'All 3199 Counties (slow in IE!)' ),
				states.map( function( state ) {
					return stateOption( state, false );
				}).join(''),
			'</select>'
		);
	}
})();

TeaMap = function( id ) {
	var state, region, frameStart, $maptip;
	
	var pm = new PolyMap({
		container: $('#'+id)[0],
		shapes: 'resources/json/map/shapes/',
		events: {
			load: function( region_ ) {
				region = region_;
				customize( region );
			},
			//drew: function() {
			//	if( $('#chkAnimate').attr('checked') ) {
			//		clearTimeout( polyTimer );
			//		polyTimer = setTimeout( function() {
			//			log.reset();
			//			customize( region );
			//			pm.redraw();
			//			var time = +new Date;
			//			if( frameStart )
			//				log( 'Frame time ' + ( ( time - frameStart ) / 1000 ).toFixed(3) + ' seconds' );
			//			frameStart = time;
			//		}, 25 );
			//	}
			//},
			over: function( place ) {
			  
			  // #status update
			  // currently not in use, so commented out
			  /*
			  if (place){
  				var update = place.update;
  				$('#status').html(
  					update && update.hoverhtml ?
  						update.hoverhtml :
  						'No reports for ' + placename(place)
  				);
        }
        */
				
				// add hover class to links
				$('#regions a.hover').removeClass('hover');
				if( place ) {
					$('#regions a#regionlink'+place.fips).addClass('hover');
				}
				showTip( place );
			},
			click: function( place ) {
				var update = place && place.update;
				if( update && update.clickurl )
					location = update.clickurl;
			}
		}
	});
	
	this.load = function( abbr, subset, factor, county, size ) {
		if( ! $('#maptip').length ) {
			$('body').append( '<div id="maptip"></div>' );
			$maptip = $('#maptip');
		}

		var state = PolyMap.stateByAbbr( abbr );
		$.getJSON(
			'json/map.json.php?state=' + abbr + 
			'&subset=' + subset +
			'&factor=' + factor +
			'&county=' + county +
			'&size=' + size, 
		  function( data ) {
  			state.custom = data;
  			loadState( abbr, county );
  		});
	};
	
	$('#stateSelector')
		.change( stateSelectorChange )
		.keyup( stateSelectorChange );
	
	$('#chkAnimate').click( function() {
		if( this.checked ) {
			pm.redraw();
		}
		else {
			clearTimeout( polyTimer );
			polyTimer = null;
		}
	});
	
	function customize( region ) {
		var updates = region.custom.places;
		region.places.forEach( function( place ) {
			var update = place.update = updates[place.fips];
			if( update && update.color ) {
				place.fillColor = update.color;
				place.fillOpacity = update.opacity;
			}
			else {
				//alert( 'No database row for ' + place.fips + ' ' + place.name );
				place.fillColor = '#FFFFFF';
				place.fillOpacity = 0.0;
			}
			place.strokeColor = '#000000';
			place.strokeOpacity = 1;
			place.strokeWidth = 1;
		});
	}
	
	function placename( place ) {
		return ! place ? 'nowhere' :
			place.name +
			( place.type != 'county' ? '' : ' County, ' + place.state.toUpperCase() );
	}
	
	function stateSelectorChange() {
		loadState( this.value.replace('!','').toLowerCase() );
	}
	
	function loadState( value, county ) {
		if( value == state ) return;
		state = value;
		pm.load({ region:state, place:county });
	}
	
	var tipOffset = { x:10, y:20 };
	var tipHtml;
	$('body').bind( 'mousemove', moveTip );
	
	function showTip( place ) {
		var update = place && place.update;
		//tipHtml = update && update.tooltip;  // use this if you don't want place names
		tipHtml = update && ( update.tooltip || update.name );
		if( tipHtml ) {
			$maptip.html( tipHtml ).show();
		}
		else {
			$maptip.hide();
		}
	}
	
	function moveTip( event ) {
		if( ! tipHtml ) return;
		var x = event.pageX, y = event.pageY;
		if(
		   x < pm.mapOffset.left  ||  x > pm.mapOffset.left + pm.mapWidth  ||
		   y < pm.mapOffset.top  ||  y > pm.mapOffset.top + pm.mapHeight
		) {
			showTip( false );
		}
		else {
			x += tipOffset.x;
			y += tipOffset.y;
			var width = $maptip.width();
			if( x + width > $window.width() - 30 )
				x -= width + tipOffset.x * 2;
			$maptip.css({ left:x, top:y });
		}
	}
}

})( jQuery );
// end outer wrapper function
