/*
JQuery plugin for rendering weathergauges using Weather Display's clientraw.txt-file (http://weather-display.com) by Brian Hamilton. The plugin assumes the data is a single value and draws a gauge with needle from that. Data is updated by ajax in realtime so it fits great for ex. realtime weathermonitoring. Ajax is stopped after x updates.

* Initial create by Henkka (http://www.nordicweather.net), Jan 2010
* v. 1.0

Originally based on the Flot graphpackage and the pie-plugin for it by Ole Laursen & Brian Medendorp. 

Released under the MIT license by Henkka, December 2007.

*/

(function(){jQuery.color={};jQuery.color.make=function(E,D,B,C){var F={};F.r=E||0;F.g=D||0;F.b=B||0;F.a=C!=null?C:1;F.add=function(I,H){for(var G=0;G<I.length;++G){F[I.charAt(G)]+=H}return F.normalize()};F.scale=function(I,H){for(var G=0;G<I.length;++G){F[I.charAt(G)]*=H}return F.normalize()};F.toString=function(){if(F.a>=1){return"rgb("+[F.r,F.g,F.b].join(",")+")"}else{return"rgba("+[F.r,F.g,F.b,F.a].join(",")+")"}};F.normalize=function(){function G(I,J,H){return J<I?I:(J>H?H:J)}F.r=G(0,parseInt(F.r),255);F.g=G(0,parseInt(F.g),255);F.b=G(0,parseInt(F.b),255);F.a=G(0,F.a,1);return F};F.clone=function(){return jQuery.color.make(F.r,F.b,F.g,F.a)};return F.normalize()};jQuery.color.extract=function(C,B){var D;do{D=C.css(B).toLowerCase();if(D!=""&&D!="transparent"){break}C=C.parent()}while(!jQuery.nodeName(C.get(0),"body"));if(D=="rgba(0, 0, 0, 0)"){D="transparent"}return jQuery.color.parse(D)};jQuery.color.parse=function(E){var D,B=jQuery.color.make;if(D=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10))}if(D=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10),parseFloat(D[4]))}if(D=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55)}if(D=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55,parseFloat(D[4]))}if(D=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(E)){return B(parseInt(D[1],16),parseInt(D[2],16),parseInt(D[3],16))}if(D=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(E)){return B(parseInt(D[1]+D[1],16),parseInt(D[2]+D[2],16),parseInt(D[3]+D[3],16))}var C=jQuery.trim(E).toLowerCase();if(C=="transparent"){return B(255,255,255,0)}else{D=A[C];return B(D[0],D[1],D[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})();

(function($) {
    function Ga(placeholder, data_, options_, plugins) {
    
    	// define gauge specific options and their default values
        var series = [],
        options = {
                hooks: {}
            },
        canvas = null,      // the canvas for the plot itself
        overlay = null,     // canvas for interactive stuff on top of plot
        eventHolder = null, // jQuery object that events should be bound to
        ctx = null, octx = null,
        target = null,
        //options = null,
        maxRadius = null,
        centerLeft = null,
        centerTop = null,
        total = 0,
        redraw = true,
        redrawAttempts = 10,
        shrink = 0.95,
        legendWidth = 0,
        processed = false,
        raw = false;
        axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} },
        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
        canvasWidth = 0, canvasHeight = 0,
        plotWidth = 0, plotHeight = 0,
        hooks = {
            processOptions: [],
            processRawData: [],
            processDatapoints: [],
            draw: [],
            bindEvents: [],
            drawOverlay: []
        },
        ga = this;

        ga.draw = draw;
        ga.getPlaceholder = function() { return placeholder; };
        ga.getCanvas = function() { return canvas; };
        ga.getPlotOffset = function() { return plotOffset; };
        ga.width = function () { return plotWidth; };
        ga.height = function () { return plotHeight; };
        ga.offset = function () {
            var o = eventHolder.offset();
            o.left += plotOffset.left;
            o.top += plotOffset.top;
            return o;
        };
        ga.getData = function() { return series; };
        ga.getAxes = function() { return axes; };
        ga.getOptions = function() { return options; };
        
        // public attributes
        ga.hooks = hooks;
        
        // initialize
        parseOptions(options_);
        constructCanvas();
        draw(ga, ctx);

        function executeHooks(hook, args) {
            args = [ga].concat(args);
            for (var i = 0; i < hook.length; ++i)
                hook[i].apply(this, args);
        }

        
        function parseOptions(opts) {
            $.extend(true, options, opts);

            for (var n in hooks)
                if (options.hooks[n] && options.hooks[n].length)
                    hooks[n] = hooks[n].concat(options.hooks[n]);
            executeHooks(hooks.processOptions, [options]);
        }

		
		    function constructCanvas() {
            function makeCanvas(width, height) {
                var c = document.createElement('canvas');
                c.width = width;
                c.height = height;
                if (window.G_vmlCanvasManager) { // excanvas hack
                    c = window.G_vmlCanvasManager.initElement(c);
                    }
                return c;
            }
            
            canvasWidth = placeholder.width();
            canvasHeight = placeholder.height();
            placeholder.empty();
            placeholder.html(""); // clear placeholder
            
            if (placeholder.css("position") == 'static')
                placeholder.css("position", "relative"); // for positioning labels and overlay

            if (canvasWidth <= 0 || canvasHeight <= 0)
                throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;

            if (window.G_vmlCanvasManager) { // excanvas hack
                window.G_vmlCanvasManager.init_(document); // make sure everything is setup
            }
            // the canvas
            
            canvas = $(makeCanvas(canvasWidth, canvasHeight)).appendTo(placeholder).get(0);
            
            ctx = canvas.getContext("2d");
           
        }

		ga.hooks.draw.push(draw);
		
		function setupgauge()
		{
			// calculate maximum radius and center point
			maxRadius =  Math.min(canvas.width,canvas.height)/2;
			centerTop = (canvas.height/2);
			centerLeft = (canvas.width/2);
			
			if (centerLeft<maxRadius)
				centerLeft = maxRadius;
			else if (centerLeft>canvas.width-maxRadius)
				centerLeft = canvas.width-maxRadius;
		}
		
		function draw(ga, newCtx)
		{			
			ctx = newCtx;		
			setupgauge();
			drawgauge();
			
			// we're actually done at this point, just defining internal functions at this point
			
			function clear()
			{
				ctx.clearRect(0,0,canvas.width,canvas.height);
				target.children().filter('.gaugeLabel, .gaugeLabelBackground').remove();
			}
						
			function drawgauge(ga)
			{
				startAngle = Math.PI*-0.5;
				
				// set radius
				if (options.radius>1)
					var rawradius = options.radius;
				else
					var rawradius = maxRadius * options.radius;
					
					var shadowoffset = 4;
					var radius = maxRadius - shadowoffset;
					centerLeft = centerLeft-shadowoffset/2;
          centerTop = centerTop-shadowoffset/2;
          var raingauge = options.raingauge;
          if (raingauge) {
          var gh = options.raingaugeheight;
          }
          ctx.clearRect(0,0,canvas.width,canvas.height);
					
					if(options.notusebgimage) {
					// Gradien color background
					var gradient = ctx.createLinearGradient(radius, 0,radius,radius*2);
					var gradientColors = options.gradient.colors;
					var ca = (1 / (gradientColors.length-1))*1;
					var cc = ca; 
					
					gradient.addColorStop(0, gradientColors[0]);           
					for (var i = 1, l = gradientColors.length; i < l-2; ++i) {
					    gradient.addColorStop(cc, gradientColors[i]);
					    cc = cc+ca;
					}
					gradient.addColorStop(1, gradientColors[i]);
					
					
					// First shadow
          var round = 10; // The roundness of the corners
          ctx.lineJoin = "round";
          ctx.globalAlpha = 1;
          ctx.beginPath();
          if (raingauge) {
          ctx.arc(radius*2-(round/2), round+1+shadowoffset, round, -Math.PI/2, 0, 0); // right-top
          ctx.arc(radius*2-(round/2), gh-(round/2), round, 0, Math.PI/2, 0); // right-bottom
          ctx.arc(round+1+shadowoffset, gh-(round/2), round, Math.PI/2, Math.PI, 0); // left-bottom
          ctx.arc(round+1+shadowoffset, round+1+shadowoffset, round, Math.PI, 3*Math.PI/ 2, 0); // left-top
          } else {
          ctx.arc(radius*2-(round/2), round+1+shadowoffset, round, -Math.PI/2, 0, 0); // right-top
          ctx.arc(radius*2-(round/2), radius*2-(round/2), round, 0, Math.PI/2, 0); // right-bottom
          ctx.arc(round+1+shadowoffset, radius*2-(round/2), round, Math.PI/2, Math.PI, 0); // left-bottom
          ctx.arc(round+1+shadowoffset, round+1+shadowoffset, round, Math.PI, 3*Math.PI/ 2, 0); // left-top
          }
          var alpha = 0.2;
          ctx.globalAlpha = alpha;
          var shadow = ctx.createLinearGradient(0, 0,radius*2,radius*2);
          shadow.addColorStop(0, 'rgba(0,0,0,0.1)');
          shadow.addColorStop(1, 'rgba(0,0,0,0.1)');
          ctx.fillStyle = shadow;
          ctx.closePath();
          ctx.fill();
          ctx.globalAlpha = 1;
          ctx.save();
          ctx.restore();
          
          // then the main background
          ctx.beginPath();
          
          if (raingauge) {
          ctx.arc(radius*2-(round/2)-shadowoffset, round+1, round, -Math.PI/2, 0, 0); // right-top
          ctx.arc(radius*2-(round/2)-shadowoffset, gh-round-shadowoffset, round, 0, Math.PI/2, 0); // right-bottom
          ctx.arc(round+1, gh-round-shadowoffset, round, Math.PI/2, Math.PI, 0); // left-bottom
          ctx.arc(round+1, round+1, round, Math.PI, 3*Math.PI/ 2, 0); // left-top
          } else {
          ctx.arc(radius*2-(round/2)-shadowoffset, round+1, round, -Math.PI/2, 0, 0); // right-top
          ctx.arc(radius*2-(round/2)-shadowoffset, radius*2-(round/2)-shadowoffset, round, 0, Math.PI/2, 0); // right-bottom
          ctx.arc(round+1, radius*2-(round/2)-shadowoffset, round, Math.PI/2, Math.PI, 0); // left-bottom
          ctx.arc(round+1, round+1, round, Math.PI, 3*Math.PI/ 2, 0); // left-top
          }
          // main thing
          ctx.fillStyle = gradient;
          ctx.closePath();
          ctx.fill();
          
          // restore ctx
          ctx.globalAlpha = 1;
          ctx.save();
          ctx.restore();
          }
          ctx.translate(centerLeft,centerTop);

					// Some basic settings
					currentAngle = startAngle;
          var angle = 360;
          var radians = function (deg) { return deg * Math.PI/180; };
          var a = 135;
          var html = '';
          //var cr = options.clientraw.split(' ');
          var minData = options.gaugeMin;
          var maxData = options.gaugeMax;
          var range = (maxData-minData);
          var angleSpan = 1.50;
          var startAngle = 0.75;
          var gaugeValue = options.crvalue;
          var uom = options.uom;
          var numbersoffset = options.numbersoffset;
          var dotsoffset = options.dotsoffset;
          var dotintervall = options.dots;
          var windgauge = options.windgauge;
          var snowv = options.snowvalue;
          
					//alert(wdirs);
                    
					var halfAngle = ((currentAngle+angle) + currentAngle)/2;
					var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
					var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.tilt;
					
					var xx = centerLeft + Math.round(Math.cos(halfAngle));
					var yy = centerTop + Math.round(Math.sin(halfAngle)) * options.tilt;
					
          // IE detector
          function isIE() {
          return /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent);
          }
					
            // DOTS & NUMBERS
            
            // RAIN & SNOWGAUGE
            if(raingauge) {
            
            if(uom == 'in') {
            gaugeValue = (gaugeValue * .0393700787).toFixed(2);
            }
            var rainvalue = gaugeValue;
           
            //alert(rainvalue);
            if(snowv) { var rainvalue = snowv;}
            if (rainvalue < 10) { var rainmax = 10; }
            if (rainvalue > 10) { var rainmax = 50; }
            if (rainvalue > 50) { var rainmax = 100; }
            if (rainvalue > 100) { var rainmax = 500; }
            if (rainvalue > 500) { var rainmax = 1000; }
            if (rainvalue > 1000) { var rainmax = 5000; }
            var bh = ((gh*0.4)+(gh/2*0.70)-8*1);
            
            // Main box & ticks
            ctx.beginPath();
            // we need the rectangle only for rain
            if(!snowv) { 
					  ctx.rect(-radius/6, -gh*0.4, 40,gh*0.75);
					  }
            ctx.strokeStyle = 'rgba(52,52,52,0.8)';
					  ctx.closePath();
					  ctx.lineWidth = 1;
					  ctx.moveTo(-radius/4, -gh*0.4);
					  ctx.lineTo(-radius/4, gh/2*0.62);
					  for (var i = 0; i < 11; i++) {
					  var to = (bh/10*i);
					  ctx.moveTo(-radius/3, gh/2*0.62-to);
					  ctx.lineTo(-radius/4, gh/2*0.62-to);
					  }
					  ctx.closePath();
					  ctx.stroke();
					  ctx.save();
					  ctx.restore();
					  
					  ctx.beginPath();
					  ctx.fillStyle = 'rgba(52,52,52,1)';
					  ctx.fillRect(-radius/6, (gh/2*0.70)-8, 40,8);
					  ctx.closePath();
					  ctx.fill();
					  ctx.save();
					  ctx.restore();
					  
					  var raintop = ((gh/2*0.70)-7) - (bh/rainmax*rainvalue)*1;
					  if (raintop < 0) {var huh = raintop - raintop - raintop; }
					  else {var huh = raintop;}
					  if(rainvalue > 0) {
					  ctx.beginPath();
					  var rain = ctx.createLinearGradient(radius, -gh*0.4,radius,gh*0.75*(rainvalue/rainmax)-1);
					  if(snowv) {
					  rain.addColorStop(0, 'rgba(255,255,255,1)');
            rain.addColorStop(1, 'rgba(255,255,255,1)');
					  } else {
            rain.addColorStop(0, 'rgba(79,148,205,1)');
            rain.addColorStop(1, 'rgba(135,206,255,1)');
            }
            ctx.fillStyle = rain;
					  ctx.fillRect(-radius/6, raintop, 40,gh*0.75*(rainvalue/rainmax)-3);
					  ctx.closePath();
					  ctx.fill();
					  ctx.save();
					  ctx.restore();
					  }
					  //alert(raintop);
					  
					  // Value
					  var html = '<span  class="valuelabel" id="gaugeLabel99" style="position:absolute;top:' + (gh*0.87) + 'px;left:' + (radius-10) + 'px; width: 50px;"><div style="width: 50px;">' + rainvalue + " "+uom+"</div></span>";
            placeholder.append(html);
            
					  // Numbers
					  for (var i = 0; i < 6; i++) {
					  var move = 12 + (bh/5*i)*1;
					  var numb = rainmax - (i*(rainmax/5));
					  var html = '<span class="gaugeLabel" id="gaugeLabel'+i+'" style="position:absolute;top:' + (move) + 'px;left:' + Math.floor(radius-radius/1.5) + 'px;width: 15px;"><div style="text-align: right;">' + numb + "</div></span>";
           placeholder.append(html);
					  }

            // WINDGAUGE
            } else if(windgauge) {
            if(uom == 'm/s') {
            gaugeValue = (gaugeValue * 0.514444).toFixed(1);
            } else if(uom == 'kmh') {
            gaugeValue = (gaugeValue * 1.85200).toFixed(1);
            }
            else if(uom == 'mph') {
            gaugeValue = (gaugeValue * 1.1507794).toFixed(1);
            }
            var wdirs = options.winddirs.split(',');
            
            var b = -90;
            var t = 0*1;
            
            // light circle
            ctx.beginPath();
					  ctx.arc(0, 0, radius-dotsoffset, 0, Math.PI * 2, true);
            ctx.strokeStyle = 'rgba(52,52,52,0.1)';
					  ctx.closePath();
					  ctx.lineWidth = 1;
					  ctx.stroke();
					  ctx.save();
					  ctx.restore();
 
            // Dir-words
            for (var i = 1; i < 360;) {
					  var ao = 0;var bo = 0;
					  if(b == -90) { var ao = 4;var bo = 2;var font ='font-size: 10px;'; }
					  else if(b == 90) { var ao = 4;var font ='font-size: 10px;'; }
					  else if(b == 0) { var ao = 2;var font ='font-size: 10px;';}
					  else if(b == 180) {var ao = 4;var font ='font-size: 10px;';}
					  else {var font = '';}
					  var labelx = (centerLeft + Math.cos(radians(b)) * (radius-numbersoffset));
            var labely = (centerTop + Math.sin(radians(b)) * (radius-numbersoffset));
            var html = '<span  class="gaugeLabel" id="gaugeLabel'+i+'" style="position:absolute;top:' + (bo+labely-6*1) + 'px;left:' + (ao+labelx-6*1) + 'px;"><div>' + wdirs[t] + "</div></span>";
            placeholder.append(html);
            t++;
            t++;
            b += 90;
            i = i+90*1;
            }
            
            // The star
            ctx.save();
					  ctx.restore();
            ctx.moveTo(0,0);
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.fillStyle = 'rgba(180,180,180,1)';
            ctx.strokeStyle = 'rgba(200, 0, 0 ,1.0)';
            
            for (var i = 0; i < 8;i++) {
            var value = (Math.PI*(2 / 8));
            ctx.rotate(value);
            ctx.lineWidth = 2;
            ctx.lineCap = "round";
            ctx.lineTo(10, 10);
            if(i % 2 != 0) {
            ctx.lineTo((radius-13), 0);
            } else {
            ctx.lineTo((radius-20), 0);
            }
            ctx.lineTo(10, -10);
					  //i = i+45*1;
            }
            
            ctx.closePath();
            ctx.fill();
            // and a rectangle in middle
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.fillStyle = 'rgba(180,180,180,1)';
            ctx.fillRect(-17, -17, 34, 34);
            ctx.closePath();
            ctx.fill();
          
            // Arrow
            if(gaugeValue < 7.5) { ctx.fillStyle = "green";}
            else if((gaugeValue >= 7.5) && (gaugeValue < 15)) { ctx.fillStyle = "rgb(255,127,0)";}
            else {ctx.fillStyle = "rgb(255,48,48)"};
            var wdir = options.dircrvalue;
            var wdir = (Math.PI*(-0.5 + wdir * 2 / 360));
            ctx.rotate(wdir);
            ctx.beginPath();
            ctx.moveTo(20, 0);
            ctx.lineTo(47, -9);
            ctx.bezierCurveTo(40, -3, 40, 3, 47, 9); 
            ctx.lineTo(20, 0);
            ctx.fill();
            
            // Text in the middle
            if (gaugeValue == 0.0) {
            gaugeValue = 'Stille';
            var fonts = 'font-size: 11px;';
            var topp = Math.floor(centerTop-8);
            } else {
            gaugeValue = gaugeValue + '<br/>'+uom;
            var fonts = 'font-size: 11px;';
            var topp = Math.floor(centerTop-12);
            }

            var html = '<span  class="valuelabel" id="gaugeLabel99" style="position:absolute;text-align: center;display:block;width:30px;top:' + topp + 'px;left:' + Math.floor(centerLeft-20) + 'px;"><div style="'+fonts+'color: #f2f2f2;">' + gaugeValue +'</div></span>';
            placeholder.append(html);
            
            } else {  // EOF WINDGAUGE
            
            // TEMPGAUGE
            // Dirty fix for negative values ;)
            var numbers = minData;
            
            if(uom == '&deg;F') {
            gaugeValue = ((gaugeValue  * 1.8) + 32 * 1).toFixed(1);
            }
            if(uom == 'in') {
            gaugeValue = (gaugeValue / 33.86388158 * 1).toFixed(2);
            }
            
            var needlevalue = gaugeValue;
            if(minData < 0) {
            var huh = minData - minData - minData;
            var hum = needlevalue - needlevalue - needlevalue;
            minData = '0';
            maxData = maxData + huh;
            var needlevalue = huh - hum;
            }
           
            if(uom == 'uvi') { range = 100; }
           
					  for (var i = 0; i <= range; ++i) {
					  
					  // "DOTS" We draw the gradient halfcircle
					  var xx = (Math.cos(radians(a)) * (radius-dotsoffset));
            var yy = (Math.sin(radians(a)) * (radius-dotsoffset));
            if(uom == 'uvi') { a += 270/(100); }
					  else { a += 270/(maxData-minData); }
					 
					  ctx.beginPath();
					  ctx.arc(xx, yy, 8, 0, Math.PI * 2, true);
					  var startc = options.startcolor.split(',');
					  var stopc = options.stopcolor.split(',');
					  
					  // check if middlecolor & change the sttings
					  if(options.middlecolor) {
					  var middlec = options.middlecolor.split(',');
					  crange = range/2*1;
					  var middle = true;
					  } else  { 
					  crange = range*1; 
					  var middle = false;
					  var y = i;
					  }
					  if(middle && (i <= crange)) { var stop = stopc; var stopc = middlec; var y = i;}
					  if(middle && (i == crange)) { var y = 1*1;var startc = middlec;}
					  if(middle && (i > crange)) { var stopc = stop; var startc = middlec; var y = y+1*1;}
					  
					  // Calc the right gradient
					  if((startc[0]-stopc[0]) < 0) {
					  var crangea = ((stopc[0]-startc[0])/crange*1);
					  var f = (crangea*y)*1;
					  var colora = Math.floor((startc[0]*1+f*1));
					  }else{
					  var crangea = ((startc[0]-stopc[0])/crange*1);
					  var colora = Math.floor(startc[0]-crangea*y);
					  }
					  if((startc[1]-stopc[1]) < 0) {
					  var crangeb = ((stopc[1]-startc[1])/crange*1);
					  var f = (crangeb*y)*1;
					  var colorb = Math.floor((startc[1]*1+f*1));
					  }else{
					  var crangeb = ((startc[1]-stopc[1])/crange*1);
					  var colorb = Math.floor(startc[1]-crangeb*y);
					  }
					  if((startc[2]-stopc[2]) < 0) {
					  var crangec = ((stopc[2]-startc[2])/crange*1);
					  var f = (crangec*y)*1;
					  var colorc = Math.floor((startc[2]*1+f*1));
					  }else{
					  var crangec = ((startc[2]-stopc[2])/crange*1);
					  var colorc = Math.floor(startc[2]-crangec*y*1);
					  }
					  // Finally, plot it
					  ctx.fillStyle = 'rgb(' + colora + ',' + colorb + ',' + colorc + ')';
					  ctx.closePath();
					  ctx.fill();
					  ctx.save();
					  
					  // Numbers
					  if(uom == 'uvi') { var dotintervall = 10; }
            if( i % dotintervall == 0) {
            var labelx = (centerLeft + Math.cos(radians(a-2)) * (radius-numbersoffset));
            var labely = (centerTop + Math.sin(radians(a-2)) * (radius-numbersoffset));
            //alert(numbers.length);
            if(numbers < 10) { var offset = 0; }
            if(numbers <= -10) { var offset = 2; }
            if(numbers >= 10) { var offset = 2; }
            if(numbers >= 100) { var offset = 4; }
            if(numbers >= 1000) { var offset = 8; }
            if(uom == 'uvi') { var number = numbers/10; var offset = -3;} else { var number = numbers; }
            var html = '<span  class="gaugeLabel" id="gaugeLabel'+i+'" style="position:absolute;top:' + (labely-6) + 'px;left:' + (labelx-6-offset) + 'px;"><div>' + number + "</div></span>";
           placeholder.append(html);
            } 
             ++numbers;
            } // Dots & numbers
            
            //alert(clo);
          
          // Needle
          var outvalue = (Math.PI*(startAngle + needlevalue * angleSpan / (maxData - minData)));
          ctx.beginPath();
          ctx.translate(0,0);
          ctx.moveTo(0,0);
          ctx.fillStyle = 'rgba(125,125,125,1.0)';
          ctx.strokeStyle = 'rgba(200, 0, 0 ,1.0)';
          ctx.rotate(outvalue);
          ctx.lineWidth = 2;
          ctx.lineCap = "round";
          ctx.lineTo(0, 3);
          ctx.lineTo((radius-20), 0);
          ctx.lineTo(0, -3);
          ctx.closePath();
          ctx.stroke();
          
          // Cap
          ctx.restore();
          ctx.beginPath();
          ctx.translate(0,0);
          ctx.arc(0,0, radius/10, 0, Math.PI * 2, true);
          var radgrad = ctx.createRadialGradient(0,0,2,0,0,9);  
          radgrad.addColorStop(0, '#777');   
          radgrad.addColorStop(1, '#333');
          ctx.closePath();
          ctx.fillStyle = radgrad;
          ctx.fill();
          ctx.save();
          
          // Value in the low middle
          var html = '<span  class="valuelabel" id="gaugeLabel99" style="position:absolute;text-align: center;display:block;width:30px;top:' + Math.floor(centerTop +radius/4.1) + 'px;left:' + Math.floor(centerLeft-20) + 'px;"><div>' + gaugeValue + '<div style="padding-top: 8px;">'+uom+'</div></div></span>';
          placeholder.append(html);
          
        } //EOF if other gauge 
      // EOF our code
			} // end drawgauge function
		} // end draw function	
	} // end init (plugin body)
	

	    $.ga = function(placeholder, data, options) {
        var ga = new Ga($(placeholder), data, options);
        /*var t0 = new Date();
        var t1 = new Date();
        var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime())
        if (window.console)
            console.log(tstr);
        else
            alert(tstr);*/
        return ga;
    };
	
	var showtemp = false;
  var showhum = false;
  var showwind = false;
  var showrain = false;
  var showsnow = false;

})(jQuery);

