//--------------------------------------------------------------------------
// _infoBox	
//..........................................................................
//	eine data info box in der Titelzeile
//												|<--- width ---->|
//												|                |
//												| label  val dim |
//												^                ^
//											  left()           anchor
function _infoBox ( ctx, top, bot, lab ) {
	this.width	= 0;
	this.anchor	= 0;
	this.labGap	= 5;
	this.dimGap	= 2;
	this.label	= { color:"#444",font:"12px sans-serif",align:"left" ,txt:"",width:0};
	this.val	= { color:"#000",font:"14px sans-serif",align:"right",txt:"",width:0};
	this.dim	= { color:"#666",font:"12px sans-serif",align:"right",txt:"",width:0};

	//----------------------------------------------------------------------
	//	left	
	//......................................................................
	//	left x coordinate
	this.left = function ( ) {
		return this.anchor - this.width;
	}

	//----------------------------------------------------------------------
	//	setLabel, setDimension, setValue
	//......................................................................
	//	set the text for the box items
	//	measure the width of the text
	//	update the box width
	this.setLabel = function ( label ) {
		var gap = 5;
		this.label.txt = ( label ? label : "" );
		ctx.font = this.label.font;
		if (Browser.Explorer)
			this.label.width = 100;
		else
			this.label.width = ctx.measureText(this.label.txt).width;
		if ( this.label.width )
			this.label.width += gap;
		this.width = this.label.width + this.dim.width + this.val.width;
	}
	this.setDimension = function ( dim ) {
		var gap = 2;
		this.dim.txt = ( dim ? dim : "" );
		ctx.font = this.dim.font;
		if (Browser.Explorer)
			this.dim.width = 100;
		else
			this.dim.width = ctx.measureText(this.dim.txt).width;
		if ( this.dim.width )
			this.dim.width += gap;
		this.width = this.label.width + this.dim.width + this.val.width;
	}
	this.setValue = function ( value ) {
		this.val.txt = ( value ? value : "" );
		this.clear();
		ctx.font = this.val.font;
		if (Browser.Explorer)
			var w = 50;
		else
			var w = ctx.measureText(this.val.txt).width;
		if ( w > this.val.width ) {
			this.val.width = w;
			this.width = this.label.width + this.dim.width + this.val.width;
		}
	}

	//----------------------------------------------------------------------
	//	draw functions
	//......................................................................
	//	set the text for the box items
	//	measure the width of the text
	//	update the box width
	this.draw = function( ) {
		this.drawLabel ( );
		this.drawDimension ( );
		this.drawValue ( );
	}
	this.drawLabel = function() {
		drawTxt( this.label, this.left() );
	}
	this.drawDimension = function() {
		drawTxt( this.dim, this.anchor );
	}
	this.drawValue = function() {
		drawTxt( this.val, this.anchor - this.dim.width );
	}
	this.clear = function() {
		ctx.clearRect( this.anchor - this.width, top, this.width, bot - top );
	}

	//----------------------------------------------------------------------
	//	private functions
	//......................................................................
	function drawTxt ( item, x ) {
		if ( item.txt ) {
			ctx.fillStyle = item.color;
			ctx.font = item.font;
			ctx.textBaseline = 'bottom';
			ctx.textAlign = item.align;
			ctx.fillText( item.txt, x, bot );
		}
	}
	this.setLabel ( lab );
}

//--------------------------------------------------------------------------
//	barograph	
//..........................................................................
function barograph ( trip, id ) {
	var canvas = _$(id);
	var ctx = canvas.getContext("2d");
	var boxes = new Object;
	var start, lowWP, highWP;
	var wpArray		= [];
	var size		= {x:0,y:0};
	var leftMargin	= 50;
	var topMargin	= 20;
	var botMargin	= 10;
	var gridExt		= 6;
	var textMargin	= 2;
	var cursorBarOffset = 0;//gridExt + textMargin;
	var step = { x: 0, y: 0 };
	var mouseTracking = false;

	//----------------------------------------------------------------------
	//	tripID
	//......................................................................
	this.tripID = function() {
		return trip.id;
	}

	//----------------------------------------------------------------------
	//	createBoxes
	//......................................................................
	//	create all info boxes
	this.createBoxes = function() {
		boxes.time	= new _infoBox( ctx, 0, topMargin - 2, "" );
		boxes.alt	= new _infoBox( ctx, 0, topMargin - 2, _s("altitude") );
		boxes.speed	= new _infoBox( ctx, 0, topMargin - 2, _s("speed") );
		boxes.vario	= new _infoBox( ctx, 0, topMargin - 2, _s("vario") );
		boxes.course= new _infoBox( ctx, 0, topMargin - 2, _s("course") );;
	}

	//----------------------------------------------------------------------
	//	drawInfo
	//......................................................................
	//	draw all info boxes
	this.drawInfo = function(index) {
		var wp = wpArray[index];
		boxes.time.setValue  ( wp.time.unixTime() );
		boxes.alt.setValue   ( wp.altitudeString());
		boxes.speed.setValue ( wp.speedString() );
		boxes.vario.setValue ( wp.varioString() );
		boxes.course.setValue( wp.course.toFixed(0) );

		this.setBoxPositions();
		
		boxes.time.draw();
		boxes.alt.draw();
		boxes.speed.draw();
		boxes.vario.draw();
		boxes.course.draw();
	}

	//----------------------------------------------------------------------
	//	drawBar
	//......................................................................
	//	draw the cursor bar
	this.drawBar = function ( x ) {
		var i = 0;
		var n = wpArray.length - 1;
		var width = size.x - leftMargin;
		x = Math.max ( leftMargin, x );
		if ( n ) {
			var rel = ( x - leftMargin ) / width;
			i = Math.round ( rel * n );
			x = Math.round ( i * width / n ) + leftMargin;
		}
		ctx.strokeStyle = "#000";
		ctx.lineWidth = 1;
		ctx.beginPath();
		ctx.moveTo(x,topMargin);
		ctx.lineTo(x,size.y);
		ctx.stroke();
		return i;
	}
	
	//----------------------------------------------------------------------
	//	setBoxPositions
	//......................................................................
	//	arrange the info boxes
	this.setBoxPositions = function ( ) {
		var gap = 20;
		boxes.time.anchor	= size.x - gap / 2;
		boxes.alt.anchor	= boxes.time.left()	- gap;
		boxes.speed.anchor	= boxes.alt.left()	- gap;
		boxes.vario.anchor	= boxes.speed.left()- gap;
		boxes.course.anchor	= boxes.vario.left()- gap;
	}
	
	//----------------------------------------------------------------------
	//	mouseEnter
	//......................................................................
	this.mouseEnter = function ( evt ) {
		mouseTracking = true;
		// in case the window has been resized
		size.x = getWidth(id);
		size.y = getHeight(id);
		this.draw();
		// draw the cursor bar and get the index into the waypoint array
		var mouse = eventMouseToLocalCoord ( evt, canvas );
		var index = this.drawBar(mouse.x - cursorBarOffset);
		// set the dimensions, in case the has changed it
		boxes.alt.setDimension ( dimension.altitude.dim );
		boxes.speed.setDimension ( dimension.hSpeed.dim );
		boxes.vario.setDimension ( dimension.vSpeed.dim );
		boxes.course.setDimension ( "˚" );
		// draw the headline info boxes
		this.setBoxPositions();
		this.drawInfo(index);
		// create a temporary marker to the cursor position
		trip.setTempMarker(wpArray[index]);
	}
	
	//----------------------------------------------------------------------
	//	mouseExit
	//......................................................................
	this.mouseExit = function ( evt ) {
		// remove the temporary marker
		trip.removeTempMarker();
		mouseTracking = false;
	}
	
	//----------------------------------------------------------------------
	//	mouseMove
	//......................................................................
	this.mouseMove = function ( evt ) {
		// could be optimized by just moving the cursor
		this.draw();
		var mouse = eventMouseToLocalCoord ( evt, canvas );
		var index = this.drawBar(mouse.x - cursorBarOffset);
		// update infos
		this.drawInfo(index);
		// move the temporary marker on the map
		trip.moveTempMarker(wpArray[index]);
	}
	
	this.mouseDown = function ( evt ) {
		var mouse = eventMouseToLocalCoord ( evt, canvas );
		var index = this.drawBar(mouse.x);
		trip.centerTempMarker(wpArray[index]);
	}
	
	this.mouseUp = function ( evt ) {
		var mouse = eventMouseToLocalCoord ( evt, canvas );
	}
	
	//----------------------------------------------------------------------
	//	reset
	//......................................................................
	//	collect all waypoints and find top and bottom altitude
	this.reset = function () {
		size.x = getWidth(id);
		size.y = getHeight(id);
	}
	
	//----------------------------------------------------------------------
	//	restore
	//......................................................................
	//	collect all waypoints and find top and bottom altitude
	this.restore = function () {
		start = lowWP = highWP = trip.startWaypoint();
		// skip the zero altitude waypoints
		while ( start.altitude == 0 && start.leading )
			lowWP = highWP = start = start.leading;
		// loop through all waypoints
		var count = 0;
		var wp = start;
		while (wp) {
			wpArray[count] = wp;
			if ( wp.altitude > highWP.altitude )	highWP = wp;
			if ( wp.altitude != 0 && 
				 wp.altitude < lowWP.altitude )		lowWP = wp;
			count++;
			if ( wp.time.getTime() >= trip.currentLocation.time.getTime() )
				break;
			wp = wp.leading;
		}
		this.reset();
		return !mouseTracking;
	}

	//----------------------------------------------------------------------
	//	drawName
	//......................................................................
	//	draw the name on the background of the barograph
	this.drawName = function() {
		var x = ( size.x + leftMargin ) / 2;
		var y = ( size.y + topMargin ) / 2;
		ctx.fillStyle = "#aea";
		ctx.font = 'bold italic 64px sans-serif';
		ctx.textBaseline = 'middle';
		ctx.textAlign = 'center';
		ctx.fillText( trip.name, x, y, size.x - leftMargin );
	}

	//----------------------------------------------------------------------
	//	drawGrid
	//......................................................................
	//	draw altitude gridlines
	this.drawGrid = function ( ) {
		var minimumNumberOfGridlines = 3;
		var band = highWP.altitude - lowWP.altitude;
		var fac = dimension.altitude.factor;
		var pixPerMeter = (size.y - topMargin - botMargin) / Math.max(band, 1);
		// possible grid line gaps
		var stepArray = [1,2,5,10,20,50,100,200,500,1000,2000,5000,10000];
		// make it a local dimension altitude band
		band *= dimension.altitude.factor;
		// set text style
		ctx.fillStyle = "#222";
		ctx.textBaseline = 'middle';
		ctx.textAlign = 'right';
		ctx.font = 'normal 10px sans-serif';
		// set the line style
		ctx.lineWidth = 1;
		ctx.strokeStyle = "#555";
		// draw the frame line
		ctx.beginPath();
		ctx.moveTo(leftMargin,size.y);
		ctx.lineTo(leftMargin,topMargin);
		ctx.lineTo(size.x,topMargin);
		ctx.stroke();
		// draw the grid lines
		ctx.strokeStyle = "#aaa";
		ctx.beginPath();
		for ( var i = stepArray.length - 1; i >= 0; --i ) {
			if ( band / stepArray[i] < minimumNumberOfGridlines && i > 0  ) continue;
			// go back to mks system
			var step = stepArray[i] / fac;
			// get the first grid altitude
			var alt = Math.ceil(( lowWP.altitude * fac ) / stepArray[i]) * stepArray[i] / fac;
			// loop through all gridlines
			while ( alt <= highWP.altitude ) {
				var y = (highWP.altitude - alt ) * pixPerMeter + topMargin;
				ctx.fillText( this.altitudeString(alt), leftMargin - gridExt - textMargin, y );
				ctx.moveTo( leftMargin - gridExt, y );
				ctx.lineTo( size.x, y );
				alt += step;
			}
			break;
		}
		ctx.stroke();
	}
	
	//----------------------------------------------------------------------
	//	drawNoise
	//......................................................................
	//	draw the noise bars
	this.drawNoise = function ( ) {
		var pixPerNoiseUnit = (size.y - topMargin) / 1000;
		var y = size.y;
		var x = leftMargin;
//		var xStep = ( size.x - leftMargin) / Math.max(wpArray.length - 1, 1);
		ctx.beginPath();
		ctx.fillStyle = "#faa";
		ctx.moveTo ( x, y );
		x -= step.x / 2;
		var wp = start;
		var count = 0;
		while ( count++ < wpArray.length ) {
			y = ( 1000 - parseInt(wp.noise,10) ) * pixPerNoiseUnit + topMargin;
			ctx.lineTo(x,y);
			x += step.x;
			ctx.lineTo(x,y);
			wp = wp.leading;
		}
		ctx.lineTo(size.x,size.y);
		ctx.closePath();
		ctx.fill();
	}
	
	//----------------------------------------------------------------------
	//	draw
	//......................................................................
	//	draw the canvas
	this.draw = function ( ) {
		canvas.height = size.y;
		canvas.width = size.x;
		if ( canvas.height > 0 ) {
//console.log('canvas.offsetWidth',canvas.offsetWidth);
//console.log('canvas.width',canvas.width);
//console.log('canvas.style.width',canvas.style.width);
//console.log('canvas.offsetWidth',canvas.offsetWidth);
//console.log('canvas.offsetParent.offsetWidth',canvas.offsetParent.offsetWidth);
//console.log('ctx',ctx);
//			canvas.style.height = canvas.height + 'px';
//			canvas.style.width = canvas.width + 'px';
//			size.x = canvas.offsetWidth;
			var wp = start;
			var top = highWP.altitude;
			step.x = (canvas.width - leftMargin) / Math.max(wpArray.length - 1, 1);
			step.y = (canvas.height - topMargin - botMargin) / Math.max(top - lowWP.altitude, 1);
			// noise background
			this.drawNoise();
			// name
			this.drawName();
			// grid
			this.drawGrid();
			// baro
			var y = (top - wp.altitude ) * step.y + topMargin;
			var x = leftMargin;
			var draw = false;
			ctx.beginPath();
			ctx.strokeStyle = "#44b";
			ctx.lineWidth = 2;
			var count = 0;
			while ( count++ < wpArray.length ) {
				if ( draw )
					ctx.lineTo(x,y);
				else
					ctx.moveTo(x,y);
				if ( wp = wp.leading ) {
					x += step.x;
					if ( draw = wp.altitude != 0 )
						y = (top - wp.altitude ) * step.y + topMargin;
				}
				else
					break;
			}
			ctx.stroke();
		}
	}

	this.altitudeString = function ( altitude ) {
		var alt = altitude * dimension.altitude.factor;
		alt = alt.toFixed(0);
		if (alt > 0)
			return alt + dimension.altitude.dim;
		return "-";
	}
	this.restore();
	this.createBoxes();
}

