
function scalextric_init()
{
	notify = 25;
	scalextric_notify("initialising", 99);
	tracks = $("#tracks");
	tracks.html("");
	fastest_laps_mode = false;


	track1 = new track(1,"a",3);
	track2 = new track(2,"q",6);
	track1.other_track = track2;
	track2.other_track = track1;

	scalextric_setup(true);

	ignore_first_lap = true;
	race_ended = false;

	//$("#lights").css("background-image", "url(images/lights_stop.png)");
	$("#lights").addClass("stop");

	$("#menu a").fancybox({ 
		'overlayOpacity': 0.6, 
		'overlayColor':'#222',
		'titleShow':true
	});

	//$(document).unbind('keydown');
	$(document).keydown(function(event){
		scalextric_keypress(event);	
	});
}

function scalextric_notify(msg, level)
{
	if (level > notify) return;
	$("#notifications UL").prepend("<li>"+msg+"</li>")
}

function scalextric_setup(redraw)
{
	scalextric_notify("setup", 99);

	race_laps = $("#race_laps").val();
	//min_time = $("#min_time").val();
	//max_time = $("#max_time").val();
	numfastestlaps = 10;


	if (redraw)
	{
		track1.draw();
		track2.draw();	
	}
}

function scalextric_start()
{
	//track1.start_time = new Date();
	//track2.start_time = new Date();



	//$("#lights").css("background-image", "url(images/lights_go.png)");
	$("#lights").addClass("go").removeClass("stop");
	$(document).focus();
}

function scalextric_stop()
{
	//$("#lights").css("background-image", "url(images/lights_stop.png)");
	$("#lights").addClass("stop").removeClass("go");
}

function scalextric_show_settings()
{
	$("#settings").show();
}

function scalextric_restart()
{
	scalextric_clear_notify();
	scalextric_stop();
	race_ended = false;

	track1.fastest_laptime = 0;
	track1.last_laptime = 0;
	track1.current_lap = 0;
	track1.previous_abs_laptime = new Date();
	track1.laptimes = new Array();
	track1.start_time = 0;
	track1.total_time = 0;
	track1.end_time = 0;
	track1.best_laptime = 99;
	track1.average_time = 0;
	track1.slowest_time = 0;
	track1.fastest_times = new Array();
	track1.slowest_fasttime = 0;

	track2.fastest_laptime = 0;
	track2.last_laptime = 0;
	track2.current_lap = 0;
	track2.previous_abs_laptime = new Date();
	track2.laptimes = new Array();
	track2.start_time = 0;
	track2.total_time = 0;
	track2.end_time = 0;
	track2.best_laptime = 99;
	track2.average_time = 0;
	track2.slowest_time = 0;
	track2.fastest_times = new Array();
	track2.slowest_fasttime = 0;
	
	track1.draw();
	track2.draw();

	scalextric_start();
}

function scalextric_clear_notify()
{
	$("#notifications").html("<UL></UL>");
}

function scalextric_keypress(event)
{
	switch (event.keyCode)
	{
		case 65: 
			//a
		case 49:
			//1
			track1.lap();
			break;
		case 81: 
			//q
		case 50:
		  //2
			track2.lap();
			break;
		case 78: 
			//n
			scalextric_restart();
			break;
		case 69: 
			//e
			$("#asettings").trigger('click');
			break;
		case 84: 
			//t
			$("#aabout").trigger('click');
			break;
		case 70: 
			//f
			scalextric_show_fastest_laps();
			break;			
		case 88: 
			//x
			$.fancybox.close();
			break;

		default:
			scalextric_notify("unknown keycode="+event.keyCode, 20);
			break;
	}
}

function scalextric_refresh_stylesheet()
{
	var d = Date();
	$(document).append('<link href="style.css?'+d.getTime()+'" rel="stylesheet" type="text/css"></link>')
}


function scalextric_getdrawoptions(track)
{
		scalextric_notify("get draw options", 99);
		var min_time = 0;
		var max_time = 7.5;

		if (track1.best_laptime != 99 && track1.best_laptime < track2.best_laptime) min_time = track1.best_laptime;
		if (track2.best_laptime != 99 && track1.best_laptime >= track2.best_laptime) min_time = track2.best_laptime;
		//min_time -= 0.5;
		
		if (fastest_laps_mode == true)
		{
			min_time *= 0.95;
		} else {
			min_time = Math.floor(min_time);
		}
		if (min_time < 0) min_time = 0;

		if (fastest_laps_mode == true)
		{
			if (track1.slowest_fasttime != 0 && track1.slowest_fasttime > track2.slowest_fasttime) max_time = track1.slowest_fasttime;
			if (track2.slowest_fasttime != 0 && track1.slowest_fasttime <= track2.slowest_fasttime) max_time = track2.slowest_fasttime;
		} else {
			if (track1.slowest_time != 0 && track1.slowest_time > track2.slowest_time) max_time = track1.slowest_time;
			if (track2.slowest_time != 0 && track1.slowest_time <= track2.slowest_time) max_time = track2.slowest_time;
		}
		//max_time += 0.5;
		if (fastest_laps_mode == true)
		{
			max_time *= 1.05;
		} else {
			max_time = Math.ceil(max_time);
		}
		
		scalextric_notify("track1.slowest_fasttime="+track1.slowest_fasttime, 99);
		scalextric_notify("track2.slowest_fasttime="+track2.slowest_fasttime, 99);
		scalextric_notify("min_time="+min_time, 99);
		scalextric_notify("max_time="+max_time, 99);
		scalextric_notify("race_laps="+race_laps, 99);

		scalextric_options = {
			series: {
				bars: {show:true, barWidth:0.5, align:"center"}
			},
			yaxis: { min:min_time, max:max_time},
			xaxis: {tickSize:5,tickDecimals:0, min:1, max:race_laps},
			grid: { hoverable:false }
		
		
		};
		//alert(typeof(scalextric_options));
		//alert(scalextric_options.series);

		return scalextric_options;
}


function track(id, listenkey, color)
{
	this.id = id;
	this.listenkey = listenkey;
	this.color = color;
	this.fastest_laptime = 0;
	this.last_laptime = 0;
	this.start_time = 0;
	this.total_time = 0;
	this.end_time = 0;
	this.average_time = 0;
	this.current_lap = 0;
	this.previous_abs_laptime = new Date();
	this.laptimes = new Array();
	this.best_laptime = 99;
	this.slowest_time = 0;
	this.fastest_times = new Array();
	this.slowest_fasttime = 0;
	this.initdraw();

	//this.draw();
}

track.prototype.lap = function()
{

	if (this.current_lap == 0) 
	{
		this.start_time = new Date();
		this.previous_abs_laptime = this.start_time;
		this.current_lap = 1;
		return;
	}
	
	if (this.current_lap > race_laps) return; // don't count further laps once a track has finished the race

	/* Calculate This Lap Time */
	this.current_abs_laptime = new Date();
	this.current_laptime = (this.current_abs_laptime.getTime() - this.previous_abs_laptime.getTime())/1000;
	if (this.current_laptime < 0.5) return; // false "2nd trigger" so ignore	
	this.previous_abs_laptime = this.current_abs_laptime;

	/* Record Laptime */
	this.last_laptime = this.current_laptime;
	this.laptimes[this.laptimes.length] = [this.current_lap, this.current_laptime];


	if (this.current_laptime > this.slowest_time ) this.slowest_time = this.current_laptime;	
	
	var current_time = new Date();
	this.total_time = (current_time.getTime() - this.start_time.getTime())/1000

	if (this.current_lap >= 1)
		this.average_time = Math.round((this.total_time / this.current_lap)*1000)/1000;

	/* Best laptime ? */
	if (this.current_lap > 0 && this.current_laptime < this.best_laptime ) 
	{
		if (this.best_laptime != 99)
		{
			scalextric_notify_fastest_lap(this);
		}
		this.best_laptime = this.current_laptime;	
	}

	/* Detect Winner */
	scalextric_notify(this.current_lap+"="+race_laps+"&&"+race_ended, 120);
	if (this.current_lap == parseInt(race_laps) && !race_ended)
	{
		this.end_time = new Date();
		scalextric_notify_winner(this);
		this.end_race();	
	}



	/* Increment Lap Counter */
	this.current_lap++;	

	this.draw();
}



function scalextric_notify_fastest_lap(track)
{
	scalextric_notify("<span class=\"track heading\"><span class=\"label\">Track:</span><span class=\"value\">"+track.id+"</span></span><span class=\"time heading\"><span class=\"label\">Time:</span><span class=\"value\">"+track.total_time+"</span></span><span class=\"msg\">Fastest Lap :: "+track.current_laptime+"</span>",1);
	$.sound.play("sounds/fastest_lap1.mp3");
}

function scalextric_notify_winner(track)
{
	scalextric_notify("<span class=\"track heading\"><span class=\"label\">Track:</span><span class=\"value\">"+track.id+"</span></span><span class=\"time heading\"><span class=\"label\">Time:</span><span class=\"value\">"+track.total_time+"</span></span><span class=\"msg\">Winner :: "+track.total_time+"</span>",1);
	$.sound.play("sounds/small_cheer.mp3");
	//$.sound.play("sounds/large_cheer.mp3");
	//alert("Winner in Lane "+track.id); 
}

track.prototype.initdraw = function()
{	
	scalextric_notify("initialising track draw", 99);
	$("#tracks").append("<div id=\"track"+ this.id +"\" class=\"track\"><div class=\"track_graph\"></div><h2>Track "+ this.id +"</h2><div class=\"track_stats\"></div>");
}

track.prototype.draw = function()
{
	var draw_options = scalextric_getdrawoptions(this);
	//alert(dump(draw_options));
	
	if (fastest_laps_mode == true)
	{
	 //alert("laptimes="+this.fastest_laptimes.length);
   $.plot($("#track"+this.id+" .track_graph"), [{data:this.fastest_laptimes, color:this.color}], draw_options);
  } else {
  	$.plot($("#track"+this.id+" .track_graph"), [{data:this.laptimes, color:this.color}], draw_options);
  }
  
   
	$("#track"+this.id+" .track_graph").bind("plothover", function (event, pos, item) {
        //alert("You clicked at " + pos.x + ", " + pos.y);
        // secondary axis coordinates if present are in pos.x2, pos.y2,
        // if you need global screen coordinates, they are pos.pageX, pos.pageY
		  $("#info").html(item.series[item.seriesIndex][1]);	
        if (item) {
          highlight(item.series, item.datapoint);
          alert("You clicked a point!");
        }
    });	

	var h = "<dl>";

	h += this.draw_item("Lap Number",this.current_lap, (this.current_lap - this.other_track.current_lap));
	h += this.draw_item("Last Lap",this.last_laptime,  Math.round((this.last_laptime - this.other_track.last_laptime)*1000)/1000);
	h += this.draw_item("Best Lap",this.best_laptime,  Math.round((this.best_laptime - this.other_track.best_laptime)*1000)/1000);
	if (fastest_laps_mode == true)
	{
		h += this.draw_item("Average Lap",(Math.round(this.avg_fastest_laptimes*1000)/1000),  Math.round((this.avg_fastest_laptimes - this.other_track.avg_fastest_laptimes)*1000)/1000);
	} else {
		h += this.draw_item("Average Lap",this.average_time,  Math.round((this.average_time - this.other_track.average_time)*1000)/1000);
	}
	h += this.draw_item("Total Time",this.total_time,  Math.round((this.total_time - this.other_track.total_time)*1000)/1000);

		h += "</dl>";
	$("#track"+this.id+" .track_stats").html(h);
}

track.prototype.draw_item = function(item,value,other_value)
{
		var h = "<dt>"+item+":</dt><dd><span class=\"value\">" + value + "</span>";
		h += "<span class=\"other\">"+((other_value > 0)?"+":"")+other_value + "</span></span>";
		h += "</dd>";

		return h;
}

track.prototype.end_race = function()
{
	scalextric_notify("race_ended",99)
	race_ended = true;

}

function scalextric_show_fastest_laps()
{
		//alert(track1.fastest_times);
		if (fastest_laps_mode == false)
		{
			fastest_laps_mode = true;
			track1.calc_fastest_times();
			track2.calc_fastest_times();
		} else {
			fastest_laps_mode = false;

		}
		track1.draw();
		track2.draw();

}

track.prototype.calc_fastest_times = function()
{
	
	// first need to clone the laptimes array (as javascript handles arrays/objects by reference
	
	var laptimes = new Array();
	
	for (var i=0; i < this.laptimes.length; i++)
	{
		laptimes[i] = new Array(this.laptimes[i][0], this.laptimes[i][1]);
	}
	
	laptimes.sort(sortFunction_laptime);
	laptimes.splice(numfastestlaps,laptimes.length); // remove all slower laps
	this.slowest_fasttime = laptimes[laptimes.length-1][1];	
	laptimes.sort(sortFunction_lapindex);
	this.fastest_laptimes = laptimes;
	var avg=0;
	for (var i=0; i < numfastestlaps; i++)
	{
		avg += this.fastest_laptimes[i][1];
	}
	this.avg_fastest_laptimes = avg/numfastestlaps
	
	//alert(this.slowest_fasttime);
	//this.draw();
}

function sortFunction_laptime(a,b)
{
	//this is a neat little trick for numerical sorting in javascript
	return a[1]-b[1];
}

function sortFunction_lapindex(a,b)
{
	//this is a neat little trick for numerical sorting in javascript
	return a[0]-b[0];
}


