

var Tools = function(){

	// 水波图表
	var waveMapChart = function(ctn, val, opts){
		opts = opts || {};
		var dpr = window.devicePixelRatio || qf.envir.dpr;
		var dpr = 2;
		var insetMargin = 3 * dpr;
		var devX = (insetMargin - 1) * dpr;	// 波浪起始和结束点偏移
		var textColor = opts.textColor || '#fff';
		var styleColor = opts.styleColor || '#2d99fc';
		var shadowColor = opts.shadowColor || opts.styleColor;

		let M = Math, Sin = M.sin, Cos = M.cos, Sqrt = M.sqrt, Pow = M.pow, PI = M.PI, Round = M.round;
		let lineWidth = 2, nowdata = 0, data = (val || 0) / 100; // 线宽
		let range = .3;							// 浪幅
		let nowrange = range;
		let waveupsp = 0.008;					// 水波上涨速度
		let sp = 0;								// 周期偏移量
		let xoffset = 8 * lineWidth;			// x 轴偏移量
		let sinLength = 1.8;						// sin 长度

		var Widget = function(ctn){
			var ctn = this.ctn = typeof element === "string" ? document.getElementById(ctn) : ctn;
			if(!ctn) return console.log('%c cuCharts Error Element is a invalid param! ', 'color:red');

			var self = this, setDpr = 1;
			self.dpr = dpr * setDpr;
			self.Cache = {};
			
			var canvas = this.canvas = document.createElement("canvas");
			canvas.style.cssText = 'position:absolute;height:100%;width:100%;';
			this.ctx = canvas.getContext("2d");
			ctn.appendChild(canvas);

			return this.init();
		}; Widget.prototype = {
			init: function(){
				// 圆动画初始参数
				let arcStack = [];				// 圆栈
				let bR = this.r - 2 * lineWidth;
				let soffset = -(PI / 2);		// 圆动画起始位置

				this.setModule();
				this.onresize();

				// 获取圆动画轨迹点集
				for (var i = soffset; i < soffset + 2 * PI; i += 1 / (8 * PI)) {
					arcStack.push([
						this.r + bR * Cos(i),
						this.r + bR * Sin(i)
					])
				};
				// 圆起始点
				let cStartPoint = arcStack.shift();
				this.ctx.strokeStyle = "#1c86d1";
				this.ctx.moveTo(cStartPoint[0], cStartPoint[1]);
				this.render();
				return this
			},
			setModule: function(){
				this.ctx.clearRect(0, 0, this.SumWidth, this.SumHeight);
				var canvas = this.canvas;
				var SumWidth = this.SumWidth = (this.ctn.clientWidth*this.dpr);
				var SumHeight = this.SumHeight = (this.ctn.clientHeight*this.dpr);
				this.width = canvas.width = SumWidth;
				this.height = canvas.height = SumHeight;

				canvas.style.cssText = 'position:absolute;top:0;left:0;height:'+(SumHeight/this.dpr)+'px;width:'+(SumWidth/this.dpr)+'px;user-select: none;-webkit-tap-highlight-color:rgba(0,0,0,0);padding:0;margin:0;border-width:0;box-sizing: border-box;';

				var r = this.r = SumWidth / 2;
				this.cR = r - 0 * dpr * lineWidth;
				this.axisLength = sinLength * r * lineWidth;	// Sin 图形长度
				this.unit = this.axisLength / 9;				// 波浪宽
				this.drawChart();
			},
			onresize: function(){
				qf.resize(() => {if(this.ctn.clientWidth){this.setModule();}});
			},
			drawChart: function(){
				//最外面淡黄色圈
				this.drawCircle();
				//灰色圆圈
				this.grayCircle();

				//橘黄色进度圈
				this.orangeCircle();

				//裁剪中间水圈
				this.clipCircle();
				
				// 阴影
				this.drwaInsetShadow();

				if (data >= 0.85) {
					if (nowrange > range / 4) {
						var t = range * 1.02;
						nowrange -= t;
					}
				} else if (data <= 0.3) {
					nowrange = 0.15
					/* if (nowrange < 0.01 * 1.5) {
						var t = 0.1 * 1.01;
						nowrange += t;
					} */
				} else {
					if (nowrange <= range) {
						var t = range * 1.01;
						nowrange += t;
					}
					if (nowrange >= range) {
						var t = range * 1.01;
						nowrange -= t;
					}
				}
				if ((data - nowdata) > 0) {
					nowdata += waveupsp;
				}else{
					nowdata = data;
				};
				sp += 0.07;

				// 开始水波动画
				this.drawSine();

				// 写字
				this.drawText();
			},
			drawWave: function(){
			},
			render: function(){
				if(!isNaN(this.ctn.clientWidth)){
					this.ctx.clearRect(0, 0, this.width, this.height);
					this.drawChart();
					this.requestFrame = requestAnimationFrame(this.render.bind(this))
				}else{
					this.clear();
					this.render = null;
					this.setModule = null;
				}
			},
			drawCircle: function(){
				var lineWidth = 1 * dpr;
				var mg = 0 * dpr - lineWidth;
				this.ctx.beginPath();
				this.ctx.lineWidth = lineWidth;
				this.ctx.strokeStyle = styleColor;
				this.ctx.arc(this.r, this.r, this.cR + mg, 0, 2 * Math.PI);
				this.ctx.stroke();
				this.ctx.restore();
			},
			grayCircle: function(){
				var lineWidth = 1 * dpr;
				var mg = insetMargin * dpr;
				this.ctx.beginPath();
				this.ctx.lineWidth = lineWidth;
				this.ctx.strokeStyle = '#eaeaea';
				this.ctx.arc(this.r, this.r, this.cR - mg, 0, 2 * Math.PI);
				this.ctx.stroke();
				this.ctx.restore();
				this.ctx.beginPath();
			},
			orangeCircle: function(){
				var mg = insetMargin * dpr;
				this.ctx.beginPath();
				this.ctx.strokeStyle = styleColor;
				//使用这个使圆环两端是圆弧形状
				this.ctx.lineCap = 'round';
				var startRadian = 0 * (Math.PI / 180.0) - (Math.PI / 2);
				var endtRadian = (nowdata * 360) * (Math.PI / 180.0) - (Math.PI / 2);
				this.ctx.arc(this.r, this.r, this.cR - mg, startRadian, endtRadian);
				this.ctx.stroke();
				this.ctx.save()
			},
			clipCircle: function(){
				this.ctx.beginPath();
				this.ctx.arc(this.r, this.r, this.cR-devX, 0, 2 * Math.PI, false);
				this.ctx.clip();
			},
			drawSine: function(){
				this.ctx.beginPath();
				this.ctx.save();
				var Stack = []; // 记录起始点和终点坐标
				
				// 波幅修正, 解决过高和过底的问题
				var a = 100 / 2 - nowdata.toFixed(4) * 100;		// 方向
				var b = (insetMargin+2) / 50;					// 基数
				var c = a * b;
				for (var i = xoffset; i <= xoffset + this.axisLength; i += 20 / this.axisLength) {
					var x = sp + (xoffset + i) / this.unit;
					var y = Sin(x) * nowrange;
					var dy = 2 * this.cR * (1 - nowdata) + (this.r - this.cR - c) - (this.unit * y);
					this.ctx.lineTo(i+devX, dy);
					Stack.push([i-devX, dy])
				};

				// 获取初始点和结束点
				var startP = Stack[0];
				var endP = Stack[Stack.length - 1];
				this.ctx.lineTo(xoffset + this.axisLength, this.width);
				this.ctx.lineTo(xoffset, this.width);
				this.ctx.lineTo(startP[0], startP[1]);
				this.ctx.fillStyle = styleColor;
				this.ctx.fill();
				this.ctx.restore();
			},
			drwaInsetShadow: function(){
				var mg = insetMargin * dpr;
				var r = this.r;
				var rgrd = this.ctx.createRadialGradient(r+mg, r+mg, 0, r, r, r);
				var colorRgb = this.colorToRgb(shadowColor);
				rgrd.addColorStop(1, 'rgba('+colorRgb+', 1)');
				rgrd.addColorStop(0.8, 'rgba('+colorRgb+', .7)');
				rgrd.addColorStop(0.1, "transparent");
				this.ctx.fillStyle = rgrd;
				this.ctx.fillRect(0, 0, r*2, r*2);
			},
			drawText: function(){
				this.ctx.globalCompositeOperation = 'source-over';
				var size = opts.fontSize || 0.38 * this.cR;
				this.ctx.font = 'bold ' + size + 'px Microsoft Yahei';
				var txt = (nowdata.toFixed(4) * 100).toFixed(2) + '%';
				var fonty = this.r + size / 2;
				var fontx = this.r - size * 0.8;
				this.ctx.fillStyle = textColor;
				this.ctx.textAlign = 'center';
				this.ctx.fillText(txt, this.r, this.r + this.height/10)
			},
			colorToRgb: function(sColor){		// 16进制颜色转rgb
				sColor = sColor.toLowerCase();
				var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
				if (sColor && reg.test(sColor)) {
					if (sColor.length === 4) {
						var sColorNew = "#";
						for (var i=1; i<4; i+=1) {
							sColorNew += sColor.slice(i, i+1).concat(sColor.slice(i, i+1));    
						};sColor = sColorNew;
					}
					//处理六位的颜色值
					var sColorChange = [];
					for (var i=1; i<7; i+=2) {
						sColorChange.push(parseInt("0x"+sColor.slice(i, i+2)));    
					}
					return sColorChange.join(",");
				};return sColor
			},
			clear: function(){
				this.render = null;
				cancelAnimationFrame(this.requestFrame);
				delete this.requestFrame
			},
		};return new Widget(ctn);
	};

	// 单窗口无缝滚动
	var singleViewSeamlessScroll = function(el, opts){
		el = typeof el === "string" ? document.getElementById(el) : el;
		if(!el) return console.log('%c sliderPlate Error Element is a invalid param! ', 'color:red');

		var ul = el.firstElementChild;
		el.style.cssText = 'position:absolute;top:0;left:0;height:100%;width:100%;';
		ul.style.cssText = 'position:relative;height:100%;overflow:hidden;';
		
		var Widget = function(ul){
			var self = this, pointer = 0;
			var timerA = new qf.Async.timerCtrl(5000, 'timerA');
			self.scrollBox = ul, 
			self.list = self.scrollBox.children;
			self.listnum = self.list.length;
			self.run = function(){
				var firstEl = self.list[pointer];
				firstEl && (firstEl.className = 'is-animating scroll-in');
				var timer = timerA(function(){
					var index = pointer, newi = ++pointer, pi = index ? index -1 : self.listnum-1;
					pointer = newi % (self.listnum);
					var target = self.list[index];
					var previous = self.list[pi];
					var next = self.list[pointer];
					if(previous && previous.classList.contains('is-animating')){
						previous.classList.remove('scroll-in');
						previous.classList.add('scroll-out');
						(function(a){
							setTimeout(() => {
								a.className = '';
							}, 800)
						})(previous);
					};
					target.classList.add('scroll-in');
					setTimeout(() => {
						next.classList.add('is-animating');
					}, 1000)
				}); return self.run = function(){};
			};
			(self.listnum > 1) && self.run();
		}; Widget.prototype = {
			update: function(){
				this.list = this.scrollBox.children;
				this.listnum = this.list.length;
				(this.listnum > 1) && this.run();
			},
		};return new Widget(ul);
	};

	return {
		waveMapChart, singleViewSeamlessScroll
	}
};

export var Tools = Tools();

/* exports = {
	HttpReq: HttpReq(),
	Dates: Dates(),
	Tools: Tools(),
}; */
