CanvasRenderingContext2D.prototype.fillRoundedRect = fillRoundedRect;
function fillRoundedRect(x, y, w, h, r) {
	this.beginPath();
	this.moveTo(x+r, y);
	this.lineTo(x+w-r, y);
	this.quadraticCurveTo(x+w, y, x+w, y+r);
	this.lineTo(x+w, y+h-r);
	this.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
	this.lineTo(x+r, y+h);
	this.quadraticCurveTo(x, y+h, x, y+h-r);
	this.lineTo(x, y+r);
	this.quadraticCurveTo(x, y, x+r, y);
	this.fill();      
}
function drawCanvasGauge( cont, parts, drawPercents ){
	var width = parseInt( cont.style.width );
	var height = parseInt( cont.style.height );
	if( !width || !height ){
		if( width && !height ){ if( width < 300 ) width = 300; height = ( width - 90 ) / 2 + 60; }
		else if( !width && height ){ if( height < 165 ) height = 165;  width = 2 * ( height - 60 ) + 90; }
			 else { width = 336; height = 183; }
	}
	else { if( width < 300 ) width = 300; if( height < 165 ) height = 165; }	
	var sum = getSum();	
	var angles = getAngles();
	var ctx = getCanvasContext();	
	var farRadius = getFarRadius();	
	var nearRadius = farRadius / 2;	
	var partFirstColor = ( navigator && navigator.userAgent.toLowerCase().indexOf('chrome') != -1 ? 'rgba(255,255,255,0)' : 'rgba(255,255,255,1)' );	
	var curAngle = Math.PI;
	var fullTime = 2000;
	var duration;
	var startTime;
	var newAngle;
	var intervalID = null;
	var statusIntervalID = null;
	var gaugeOldValue = 0;
	var gaugeNewValue = 0;
	var numberStatus = true;
	var blinkColor = 0;
	var valueLabel='';
	var gaugeTitle='';
	
	drawGauge();
	
	function getCanvasContext(){
		cont.innerHTML = '<canvas width="' + width + '" height="' + height + '"></canvas>';
		var canvas = cont.firstChild;
		if( typeof G_vmlCanvasManager != 'undefined' ) canvas = G_vmlCanvasManager.initElement( canvas );
		var ctx = canvas.getContext('2d');
		return ctx;
	}
	function getAngles(){
		var sum = getSum();
		var angles = [ Math.PI ];
		for( var i = 0; i < parts.length-1; i++ ) angles[i+1] = angles[i] - ( parts[i].value / sum ) * Math.PI;
		angles[angles.length] = 0;
		return angles;
	}
	function getSum(){
		var sum = 0;
		for( var i = 0; i < parts.length; i++ ) sum += parts[i].value;		
		return sum;
	}	
	function getFarRadius(){
		var r1 = ( width - 90 ) / 2;
		var r2 = height - 60;
		var farRadius = ( r1 <= r2 ? r1 : r2 );
		return farRadius;
	}	
	function drawGauge(){
		drawBackground();
		drawDial();
		drawNumbers();
		drawTicks();
		drawValue();
		drawArrow();
	}
	function drawBackground(){
		ctx.save();
		var linearGradient = ctx.createLinearGradient( 0, 0, width, 0 );  
	//	linearGradient.addColorStop( 0, '#009999' );  
	//	linearGradient.addColorStop( 1, '#333333' ); 
		linearGradient.addColorStop( 0, '#EEF5FD' );  
		linearGradient.addColorStop( 1, '#CCDFFA' ); 
		ctx.fillStyle = linearGradient;	
		ctx.fillRect( 0, 0, width, height );
		ctx.fillStyle = '#000000';
		ctx.font = '10px tahoma'; 
		ctx.fillText( gaugeTitle,5, 12 );
		ctx.restore();	
		
	}	
	function drawDial(){
		ctx.save();
		ctx.translate( width / 2, height - 20 );
		if( navigator && navigator.userAgent.toLowerCase().indexOf('chrome') != -1 )
		    ctx.globalCompositeOperation = 'copy';
		ctx.lineWidth = 3;
		for( var i = 0; i < parts.length; i++ ) 
			drawPart( angles[i], angles[i+1], parts[i].color );		
		ctx.restore();		
	}	
	function drawNumbers(){
		ctx.save();
		ctx.fillStyle = '#000000';
		ctx.font = '10px tahoma'; 
		ctx.translate( width / 2, height - 20 );		
		for( var i = 0; i < 5; i++ ){
			ctx.textAlign  = i < 2 ? 'right' : i == 2 ? 'center' : 'left';
			var text = '';
			if( drawPercents == true ) text = i*25 + '%';
			else {
				var number = i * ( sum / 4 );
				text = number < 1000 ? number : number / 1000 + 'K';
			}
			ctx.fillText( text, ( farRadius + 10 ) * Math.cos( ( 1 - i / 4 ) * Math.PI ), -( farRadius + 10 ) * Math.sin( ( 1 - i / 4 ) * Math.PI ) );
		}
		ctx.restore();
	}	
	function drawTicks(){
		ctx.save();
		ctx.translate( width / 2, height - 20 );
		ctx.strokeStyle = '#FFFFFF';
		ctx.beginPath(); 
		for( var i = 0; i <= 20; i++ ){ 
			ctx.moveTo( ( farRadius + 1 ) * Math.cos( ( 1 - i / 20 ) * Math.PI ), -( farRadius + 1 ) * Math.sin( ( 1 - i / 20 ) * Math.PI ) );	
			ctx.lineTo( ( farRadius - ( i % 5 == 0 ? 15 : 7 ) ) * Math.cos( ( 1 - i / 20 ) * Math.PI ), -( farRadius - ( i % 5 == 0 ? 15 : 7 ) ) * Math.sin( ( 1 - i / 20 ) * Math.PI ) );
		}
		ctx.closePath();
		ctx.stroke();
		ctx.restore();		
	}		
	function drawValue(){
		ctx.save();
		ctx.translate( width / 2, height - 20 );
		ctx.fillStyle = numberStatus == true ? '#7EA802' : '#E96C5B';
		ctx.fillRoundedRect( -35, -0.57 * nearRadius, 70, 20, 4 );
		ctx.fillStyle = '#FFFFFF';	
		ctx.font = 'bold 15px verdana'; 
		ctx.textAlign  = 'center';
		ctx.textBaseline  = 'top';
		var curValue = Math.round( sum * ( 1 - curAngle / Math.PI ) );
		if( ( gaugeNewValue >= gaugeOldValue && curValue > gaugeNewValue ) || ( gaugeNewValue <= gaugeOldValue && curValue < gaugeNewValue ) )
			curValue = gaugeNewValue;
		var margin = ( navigator && ( navigator.userAgent.toLowerCase().indexOf('firefox') != -1 ||
									  navigator.userAgent.toLowerCase().indexOf('msie') != -1 ) ? 3 : 0 );	
	    var drawedValue;
		if(curValue==0){
			drawedValue="N/A";
			
		}else{
			drawedValue= Math.round(curValue)
		}
		ctx.fillText(drawedValue +valueLabel, 0, -0.56 * nearRadius + margin );
		ctx.restore();
	}	
	function drawPart( startAngle, endAngle, color ){
		ctx.beginPath();  
		ctx.moveTo( nearRadius * Math.cos( startAngle ), -nearRadius * Math.sin( startAngle ) );		
		ctx.arc( 0, 0, nearRadius, -startAngle, -endAngle, false );
		ctx.lineTo( farRadius * Math.cos( endAngle ), -farRadius * Math.sin( endAngle ) );
		ctx.arc( 0, 0, farRadius, -endAngle, -startAngle, true );
		ctx.closePath(); 
		var radgrad = ctx.createRadialGradient( 0, 0, nearRadius, 0, 0, farRadius );  
		radgrad.addColorStop( 0, partFirstColor );  
		radgrad.addColorStop( 1, color ); 	
		ctx.fillStyle = ( typeof G_vmlCanvasManager != 'undefined' ? color : radgrad );
		ctx.strokeStyle = color;
		ctx.stroke(); 
		ctx.fill();			
	}
	function drawArrow(){
		ctx.save();
		ctx.translate( width / 2, height - 20 );
		ctx.rotate( ( Math.PI / 2 ) - curAngle );
		ctx.fillStyle = 'RGBA(231,235,208,0.6)';
		ctx.strokeStyle =  'RGBA(68,68,68,0.4)';
		ctx.save();
		ctx.shadowColor =  'RGBA(0,0,0,0.6)';
	    ctx.shadowOffsetX = 3;
		ctx.shadowOffsetY = 3;
		ctx.shadowBlur = 5;
		ctx.beginPath(); 
		ctx.moveTo( -nearRadius * 0.1, 15 );
		ctx.lineTo( nearRadius * 0.1, 15 );
		ctx.lineTo( 0, -(farRadius * 0.75) );
		ctx.closePath();
		ctx.stroke(); 
		ctx.fill();	
		ctx.restore();
		ctx.fillStyle = '#aaaaaa';
		ctx.beginPath(); 
		ctx.arc( 0, 0, nearRadius * 0.15 , 0, -2 * Math.PI, true );
		ctx.closePath();
		ctx.fill();		
		ctx.restore();
	}
	function rotateArrow(){
		var passedTime = new Date().getTime() - startTime;
		if( passedTime > duration ){	
			clearInterval( intervalID );
			intervalID = null;
			curAngle = newAngle;
			drawGauge();
			gaugeOldValue = gaugeNewValue;
			if( numberStatus == false ) statusIntervalID = setInterval( blink, 1000 );
		}
		else {
			var originAngle = curAngle;
			var t = passedTime;
			var b = curAngle;
			var c = newAngle - curAngle;
			var d = duration;
			var s = 0.85158;
			curAngle = c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;	
			drawGauge();
			curAngle = originAngle;
		}
	}	
	function blink(){
		ctx.save();
		ctx.translate( width / 2, height - 20 );
		ctx.fillStyle = blinkColor == 0 ? '#E96C5B' : '#AAAAAA';
		ctx.strokeStyle = '#AAAAAA';
		ctx.beginPath(); 
		ctx.arc( 0, 0, nearRadius * 0.15 , 0, -2 * Math.PI, true );
		ctx.closePath();
		ctx.fill();	
		if(blinkColor != 0)
			ctx.stroke();
		ctx.restore();	
		blinkColor = blinkColor == 0 ? 1 : 0;
	}
	return {
		setArrow: function( value, status ){
			if( intervalID != null || value < 0 || value > sum ) return;
			if( statusIntervalID != null ) clearInterval( statusIntervalID );
			gaugeNewValue = value;
			numberStatus = status;
			newAngle = ( 1 - value / sum ) * Math.PI;
			if( typeof G_vmlCanvasManager != 'undefined' ){ curAngle = newAngle; drawGauge(); }
			else {
				duration = Math.round( ( Math.abs( newAngle - curAngle ) / Math.PI ) * fullTime );
				startTime = new Date().getTime();
				intervalID = setInterval( rotateArrow, 1 );
			}
		},
		setLabel:function(label){
			if(label)
				valueLabel=label;
		},
		setTitle:function(title){
			if(title)
				gaugeTitle=title;
		}
	}
}
