import m from 'mithril';
import { Gauge } from 'components/widgets/gauge';
import { Pipe } from 'utilities/pipe';

require('./gauge-circular.css');

export class GaugeCircular extends Gauge {
	constructor(vnode: any) {
		super(vnode);
	}
	
	createSvg(svgElement: SVGElement) {
		let w = Math.round(svgElement.clientWidth);
		let h = Math.round(svgElement.clientHeight);
		
		svgElement.classList.add('gauge-circular');
		
		svgElement.setAttribute('viewBox', "0 0 "+w+" "+h);
		
		let svgRound = (v: number) => Math.round(v * 100.0) / 100.0;
		
		const arcRatio = 0.75; // from 0.5 for half circle to 1.0 for full circle
		const gaugeWidthRatio = 0.15; // relative to the smallest dimension of the drawing area
		const lineThickness = 1;
		
		let gaugeWidth = Math.round(Math.min(w, h) * gaugeWidthRatio);
		let gaugeRadius = Math.round(Math.min(w, h) * 0.5 - gaugeWidth * 0.5 - lineThickness - 1);
		let cx = Math.round(w * 0.5); let cy = Math.round(h * 0.5);
		
		let openingHalfAngle = Math.PI * (1.0 - arcRatio);
		let arcLength = Math.PI * 2.0 * gaugeRadius * arcRatio;
		let startx = svgRound(cx - Math.sin(openingHalfAngle) * gaugeRadius);
		let starty = svgRound(cy + Math.cos(openingHalfAngle) * gaugeRadius);
		let dx = svgRound(2.0 * Math.sin(openingHalfAngle) * gaugeRadius);
		
		let outlineArcRatio = (arcLength + lineThickness*2.0) / (Math.PI * 2.0 * gaugeRadius);
		let outlineOpeningHalfAngle = Math.PI * (1.0 - outlineArcRatio);
		let outlineStartx = svgRound(cx - Math.sin(outlineOpeningHalfAngle) * gaugeRadius);
		let outlineStarty = svgRound(cy + Math.cos(outlineOpeningHalfAngle) * gaugeRadius);
		let outlineDx = svgRound(2.0 * Math.sin(outlineOpeningHalfAngle) * gaugeRadius);

		let bgOutline = document.createElementNS('http://www.w3.org/2000/svg', 'path');
		bgOutline.setAttribute('d', 'M'+outlineStartx+' '+outlineStarty+' a'+gaugeRadius+' '+gaugeRadius+' 0 1 1 '+outlineDx+' 0');
		bgOutline.setAttribute('style', 'stroke-width: '+(gaugeWidth+lineThickness*2));
		bgOutline.classList.add('gauge-bg-outline');
		svgElement.append(bgOutline);

		let bg = document.createElementNS('http://www.w3.org/2000/svg', 'path');
		bg.setAttribute('d', 'M'+startx+' '+starty+' a'+gaugeRadius+' '+gaugeRadius+' 0 1 1 '+dx+' 0');
		bg.setAttribute('style', 'stroke-width: '+(gaugeWidth));
		bg.classList.add('gauge-bg');
		svgElement.append(bg);
		
		let barHeight = 10;
		const barGap = barHeight * 0.2;
		let numBars = Math.round(arcLength / (barHeight + barGap));
		
		barHeight = (arcLength - (numBars+1)*barGap) / numBars;
		
		let computeCircleCoords = function(d: number, r: number, out: {x: number, y: number}) {
			let a = outlineOpeningHalfAngle + (2.0 * Math.PI - outlineOpeningHalfAngle * 2.0) * (d / arcLength);
			out.x = svgRound(cx - Math.sin(a) * r);
			out.y = svgRound(cy + Math.cos(a) * r);
		};
		
		let points: {x: number, y: number}[] = [];
		for(let idx = 0; idx < 4; ++idx) { points[idx] = {x: 0, y: 0}; }
		for(let barIdx = 0; barIdx < numBars; ++barIdx) {
			let bar = document.createElementNS('http://www.w3.org/2000/svg', 'path');
			bar.classList.add('gauge-bar');
			bar.classList.toggle('lit', false);
			
			let barStartLen = barGap + barIdx * (barHeight + barGap);
			let barEndLen = barStartLen + barHeight;
			computeCircleCoords(barStartLen, gaugeRadius - gaugeWidth*0.5 + barGap, points[0]);
			computeCircleCoords(barStartLen, gaugeRadius + gaugeWidth*0.5 - barGap, points[1]);
			computeCircleCoords(barEndLen, gaugeRadius + gaugeWidth*0.5 - barGap, points[2]);
			computeCircleCoords(barEndLen, gaugeRadius - gaugeWidth*0.5 + barGap, points[3]);
			
			bar.setAttribute('d', 'M'+points[0].x+' '+points[0].y+' L'+points[1].x+' '+points[1].y+' L'+points[2].x+' '+points[2].y+' L'+points[3].x+' '+points[3].y+' Z');
			
			svgElement.append(bar);
			
			this.bars.push(bar);
		}
	}
	
	oncreate(vnode: any) {
		let svgElement: SVGElement = vnode.dom.querySelector('svg');
		this.createSvg(svgElement);
		
		super.oncreate(vnode);
	}
}
