﻿/**
 *	map.js -> http://locusonus.org/
 */



var map 		= document.getElementById( "map_img" );		// the map element
//var loc			= position( map );							// the map element position
var current		= null;										// the current active card
var sizes		= new Array();								// all cards height
var scaleprop	= { w:3, h:13 };							// the reduce/expand scale properties
var iconsize	= { w:6, h:6 };								// the stream icon dimension

// timers setup ( in milliseconds )
// for the scale effect, increase or decrease the speed process
var timer		= { update:{ streams: null, img:null}, expand:null, reduce: null };
var delay		= { update:{ streams: 1000*60, img:1000*60*7}, expand:7, reduce:3 };
// a dummy counter to force the map's image to be refresh,
// not from being loading from cache
var dummyC		= 0;






/**
 * Setup the map :
 * add mouse Events, strore all card height for the growing effect, load background…
 *
 * @param boolean	show day and night (or not)
 * @param boolean	show clouds (or not)
 * @param boolean	update the image and streams during the process ?
 * @param boolean	use effect or not
 * @param int		the number of cards
 */
function mapsetup( daynight, clouds, refresh, effect, cnt ) {

	
	// set timers, if needed
	if ( refresh ) {
		timer.update.streams = setInterval( 'mapupdate_streams()', delay.update.streams );
		timer.update.img = setInterval( 'mapupdate_img('+daynight+','+clouds+')', delay.update.img );
	}
	
	// add background image
	mapupdate_img( daynight, clouds );
	
	
	if ( !effect ) return; // <-- exit 
	
	
	// store card's dimensions .
 	for( var i=0; i<cnt; i++ ) {
 		var elem = document.getElementById( "stream_"+(i+1) );
 		if ( elem ) {
 			//sizes.push( { w: elem.offsetWidth, h: elem.offsetHeight } );
			sizes.push( { w:170, h: elem.offsetHeight } );		// <-- force width for Safari ??? sometimes on low CPU
 			reduce(i+1);
			elem.style.visibility = "visible";
		}
		else sizes.push( null );
 	}
	
	// register the map events
	// set the map capture events
	try {
		map.onmousemove	= mapmousemove;
		//map.onclick 	= mapmousemove;
		map.onmouseout	= mapinfo;
		if ( map.captureEvents ) map.captureEvents( Event.MOUSEMOVE | Event.CLICK );
	}
	catch(e) {;}

}

/**
 * Update the current map streams.
 */
function mapupdate_streams() {
	
	var xhr = new XHR(
		function( html ) {
			if ( html!="error" ) document.getElementById("map_streams").innerHTML = html;
		},
		{ method:"POST", url:"php/map.php" }
	);
	xhr.error( function(){;} );
	xhr.send( "refresh=1" );
}

/**
 * Update the current map background image.
 * 
 * 		request available values:
 *			-img=learth.evif  &
 *			-imgsize=940 &
 *			-daynight=-d &
 *			-opt=-p & 
 *			-lat=47 & 
 *			-ns=North & 
 *			-lon=7 & 
 *			-ew=East & 
 *			-alt=35785 & 
 *			-bird=From+elements+below & 
 *			-tle=LAGEOS+1%0D%0A & 
 *			-date=0 &
 *			-utc=2069-07-20+20%3A17%3A43 &
 *			-jd=2476948.34564
 *
 * @param boolean	show day and night (or not)
 * @param boolean	show clouds (or not)
 */
function mapupdate_img( daynight, clouds ) {

	var rq	= "imgsize=940&dynimg=y&opt=-p&date=0";
	var img = new Image();
	
	// update the query string, if needed
	if ( !daynight ) rq += "&daynight=-d";
	if ( clouds )	 rq += "&img=cloudy.bmp";
	
	// load image
	try {
		rq += "&cnt="+(dummyC++); // <-- force refresh
		img.src = "http://www.fourmilab.ch/cgi-bin/Earth?"+rq;
		if ( img.src ) document.getElementById( "map_img" ).src = img.src;
	}
	catch(e) {;}
}

/**
 * Retrieves the mouse coordinates, the latitude and the longitude according to the mouse position
 * on the map. This function must be call element's event registration.
 *
 * @param Event
 * @return Object
 */
function trace(e) {

	if (!e) e = window.event;
	
	// decimal map coordinates
	var mx = (!e.layerX ? e.x : e.layerX);
	var my = (!e.layerY ? e.x : e.layerY);
	// geographic map coordinates
	var la = (((my/map.height)*180) - 90)*-1;
	var lo = ((mx/map.width) *360) - 180;
	
	return { x:mx, y:my, lat:la, lon:lo };
}

/**
 * Dump mouse's traces and perform all action onmousemove
 */
function mapmousemove(e) {
	try { // <-- error if the document is loading
		var info = trace(e);
		mapinfo( info.x+" "+info.y+" "+info.lat+" "+info.lon );
	}
	catch(e){;}
}

/**
 * Dump the given message onto the "map_dump" element. Only is the dump element is present.
 *
 * @param String	the message to be displayed
 */
function mapinfo( msg ) {
	try {
		document.getElementById("map_dump").innerHTML =
			typeof(msg)=="string" ? "<small>"+msg+"</small>" : "";
	}
	catch(e) {;}
}

/**
 * Expand the given card element with a growing effect or not.
 *
 * @param Object	the card ID to be expanded
 * @param boolean	use scale effect or not
 */
function expand( id, scale ) {

	var elem = document.getElementById( "stream_"+id );
	
	var i = Number(id)-1;
	var w = elem.offsetWidth;
	var h = elem.offsetHeight;
	
	// register the active card
	// and reduce the prvious
	if ( current!=null && current!=id ) {
		reduce( current, scale );
		if ( timer.expand!=null ) {
			clearInterval( timer.expand );
			timer.expand=null;
		}
	}
	current = id;
	
	// no effect
	if ( !scale ) {
		w = sizes[i].w;
		h = sizes[i].h;
	}
	// scale effect
	else {
		// set timer
		if ( w>=sizes[i].w && h>=sizes[i].h ) {
			clearInterval( timer.expand );
			timer.expand=null;
		}
		else {
			if ( timer.expand==null ) 
				timer.expand = setInterval( 'expand('+id+',true)', delay.expand);
		}
		// new dimensions
		w = Math.min( w+(sizes[i].w/scaleprop.w), sizes[i].w );
		h = Math.min( h+(sizes[i].h/scaleprop.h), sizes[i].h );
	}
	
	// set styles
	elem.style.width	= w+"px";
	elem.style.height	= h+"px";
}

/**
 * Reduce the given card element.
 *
 * @param Object	the card ID to be reduced
 */
function reduce( id ) {

	if ( id==current && timer.expand!=null ) {
		clearInterval(timer.expand);
		timer.expand=null;
		current=null;
	}
	
	var elem = document.getElementById("stream_"+id);
	
	elem.style.width	= iconsize.w+'px';
	elem.style.height	= iconsize.h+'px';
	elem.style.zIndex	= id+100;
	
}


