/*
	Web Widget Interface
	Copyright 2014-2019 Harry Whitfield

	This program is free software; you can redistribute it and/or modify it under
	the terms of the GNU General Public License as published by the Free Software
	Foundation; either version 2 of the License, or (at your option) any later
	version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
	PARTICULAR PURPOSE.	 See the GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along with
	this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
	St, Fifth Floor, Boston, MA	 02110-1301	 USA

	Web Widget Interface - browser version 1.1.3
	13 February, 2019
	Copyright 2014-2019 Harry Whitfield
	mailto:g6auc@arrl.net
*/

/*jslint browser, for, devel, this */

/*global alert, document */

/*property
    PI, add, appendChild, body, clearRect, cols, createElement, createTextNode,
    ctx, div, drawImage, fillText, filter, font, forEach, getContext, hOffset,
    hRegP, height, indexOf, innerHTML, left, length, match, maxHeight, maxWidth,
    naturalHeight, naturalWidth, onload, onmousedown, onmouseenter, onmouseout,
    onmouseup, opacity, remove, replace, restore, rotate, round, rows, save,
    scale, setAttribute, size, split, src, srcDown, srcUp, style, text,
    toUpperCase, top, translate, type, vOffset, vRegP, value, width, within,
    zOrder
*/

//////////////////////////////////// webWidget globals ///////////////////////////////////

var scale = 1.0;
var vtop = 0;
var left = 0;
var fScale = 6.0;	  	// was 6.67
var hScale = 6.3;		// hScale was 6.0
var vScale = 16;
var textType = "input";	// "div" or "input" - see function newText below

var Image;

///////////////////////////////// Start of the setStyle function /////////////////////////////////

var setStyle = function (obj, styleString) {
	"use strict";
    var items = styleString.split(";");
	var last = items[items.length - 1];
	var that = obj.style;

	function trim(s) {
		return s.replace(/^\s+|\s+$/g, "");
	}

	function toCamelCase(s) {
		var t = "";
		var ok = /^-?[a-z]+(-[a-z]+)*$/;
		var f = false;

		function doThis(c) {
		    if (c === "-") {
		        f = true;
		    } else {
		        t += (
		        	f
		            ? c.toUpperCase()
		            : c
		        );
		        f = false;
		    }
		}

		if (s.match(ok) === null) {
			alert("Badly formed css attribute: " + s);
			return "";
		}

		s.split("").forEach(doThis);

		return t;
	}

    if ((last === "") || (last.indexOf(":") === -1)) {
    	items.length -= 1;
    } 	// remove empty entry

    function doThat(ele) {
        var item = ele.split(":");
		var key = trim(item[0]);
		var value = trim(item[1]);

        key = toCamelCase(key);
        if (key !== "") {
			that[key] = value;
		}
    }

    items.forEach(doThat);

};

///////////////////////////////// End  of  the setStyle function /////////////////////////////////

//////////////////////////// Start of the webWidget functions ////////////////////////////

function newFrame(hOffset, vOffset, width, height, src, zOrder, opacity) {
	"use strict";
	var iframe = document.createElement("iframe");

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	iframe.setAttribute(
		"style",
		"position: absolute; left: " + String(hOffset + left) +
		"px; top: " + String(vOffset + vtop) + "px; z-index: " + String(zOrder) + ";"
	);

	iframe.setAttribute("src", src);
    iframe.style.width = Math.round(scale * width) + "px";
    iframe.style.height = Math.round(scale * height) + "px";

    document.body.appendChild(iframe);

	iframe.width = Math.round(scale * width);
	iframe.height = Math.round(scale * height);

	if (opacity === undefined) {
		opacity = 1.0;
	}
	iframe.style.opacity = opacity;
	iframe.style.filter = "alpha(opacity=" + Math.round(100 * opacity) + ")";
	return iframe;
}

function newElement(tagName, hOffset, vOffset, zOrder) {
	"use strict";
	var div = document.createElement("div");
	var ele;

	div.setAttribute(
		"style",
		"position: absolute; left: " + String(hOffset + left) +
		"px; top: " + String(vOffset + vtop) + "px; z-index: " + String(zOrder) + ";"
	);

	document.body.appendChild(div);

	ele = document.createElement(tagName);
	ele.left = hOffset;
	ele.top = vOffset;
	ele.div = div;
	ele.zOrder = zOrder;
	div.appendChild(ele);

	return ele;
}

function newDiv(hOffset, vOffset, zOrder, id) {
	"use strict";
	var div = document.createElement("div");

	hOffset = Math.round(scale * hOffset);	// new 20190212
	vOffset = Math.round(scale * vOffset);	// new 20190212

	div.setAttribute(
		"style",
		"position: absolute; left: " + String(hOffset + left) +
		"px; top: " + String(vOffset + vtop) + "px; z-index: " + String(zOrder) + ";"
	);

	if (id !== undefined) {
		div.setAttribute("id", id);
	}

	div.zOrder = zOrder;

	document.body.appendChild(div);
	return div;
}

function moveDiv(div, hOffset, vOffset) {
	"use strict";
	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	div.setAttribute(
		"style",
		"position: absolute; left: " + String(hOffset + left) +
		"px; top: " + String(vOffset + vtop) + "px; z-index: " + String(div.zOrder) + ";"
	);
}

function moveObj(obj, hOffset, vOffset) {
	"use strict";
	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	obj.div.setAttribute(
		"style",
		"position: absolute; left: " + String(hOffset + left) +
		"px; top: " + String(vOffset + vtop) + "px; z-index: " + String(obj.zOrder) + ";"
	);
}

function move(obj) {
	"use strict";
	obj.div.setAttribute(
		"style",
		"position: absolute; left: " + String(obj.left + left) +
		"px; top: " + String(obj.top + vtop) + "px; z-index: " + String(obj.zOrder) + ";"
	);
}

function newImage(hOffset, vOffset, width, height, src, zOrder, opacity) {
	"use strict";
	var img;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	img = newElement("img", hOffset, vOffset, zOrder);

	img.hOffset = hOffset;	// new 20190212
	img.vOffset = vOffset;	// new 20190212

	img.src = src;

	if ((width === 0) || (height === 0)) {
		img.onload = function () {
			img.width = Math.round(scale * img.naturalWidth);
			img.height = Math.round(scale * img.naturalHeight);
		};
	} else {
		img.width = Math.round(scale * width);
		img.height = Math.round(scale * height);
	}

	if (opacity === undefined) {
		opacity = 1.0;
	}
	img.style.opacity = opacity;
	img.style.filter = "alpha(opacity=" + Math.round(100 * opacity) + ")";
	return img;
}

function newButton(hOffset, vOffset, width, height, src, srcDown, zOrder, opacity, clickAction) {
	"use strict";
	var o = newImage(hOffset, vOffset, width, height, src, zOrder, opacity);

	o.srcUp = src;
	o.srcDown = srcDown;
	o.within = false;
	o.onmouseup = function () {
		if (this.within) {
			this.src = src;
			clickAction();
		}
	};
	o.onmousedown = function () {
		this.within = true;
		this.src = srcDown;
	};
	o.onmouseenter = function () {
		this.within = true;
		this.src = srcDown;
	};
	o.onmouseout = function () {
		this.within = false;
		this.src = src;
	};
	return o;
}

function newTextX(hOffset, vOffset, width, height, value, zOrder, style) {
	"use strict";
	var text;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	text = newElement("input", hOffset, vOffset, zOrder);
	text.type = "text";

	text.width = Math.round(scale * width);
	text.size = Math.round(scale * width / hScale);
	text.style.maxWidth = Math.round(scale * width) + "px";
	text.height = Math.round(scale * height);
	text.style.maxHeight = Math.round(scale * height) + "px";
	text.value = value;
	if (style !== undefined) {	// style is an optional parameter
		setStyle(text, style);
	}
	return text;
}

function newText(hOffset, vOffset, width, height, value, zOrder, style) {
	"use strict";
	var text;

//	vOffset = vOffset - 2 * height / 3;			???

	text = newDiv(hOffset, vOffset, zOrder);
	text.innerHTML = value;

	width = Math.round(scale * width);
	height = Math.round(scale * height);

	setStyle(text, "width:" + width + "px; height:" + height + "px;");

	if (style !== undefined) {	// style is an optional parameter
		setStyle(text, style);
	}
	return text;
}

function newPara(hOffset, vOffset, ignore, height, value, zOrder, style) {
	"use strict";
	var para;
	var text;

	vOffset = vOffset - 9 * height / 16;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	para = newElement("p", hOffset, vOffset, zOrder);
	text = document.createTextNode(value);
	if (style !== undefined) {	// style is an optional parameter
		setStyle(para, style);
	}
	para.appendChild(text);
	return para;				// para.innerHTML = value to change the text
}

function newTextArea(hOffset, vOffset, width, height, value, zOrder, style) {
	"use strict";
	var textarea;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	textarea = newElement("textarea", hOffset, vOffset, zOrder);

	textarea.cols = Math.round(width / hScale);
	textarea.rows = Math.round(height / vScale);
	textarea.value = value;

	textarea.style.maxWidth = Math.round(scale * width) + "px";
	textarea.style.maxHeight = Math.round(scale * height) + "px";

	if (style !== undefined) {	// style is an optional parameter
		setStyle(textarea, style);
	}
	return textarea;
}

function newInput(hOffset, vOffset, width, height, value, zOrder, style) {
	"use strict";
	var input;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	input = newElement("input", hOffset, vOffset, zOrder);
	input.type = "text";

	input.width = Math.round(scale * width);
	input.size = Math.round(scale * width / fScale);
	input.height = Math.round(scale * height);
	input.value = value;
	if (style !== undefined) {	// style is an optional parameter
		setStyle(input, style);
	}
	return input;
}

function newCanvas(hOffset, vOffset, width, height, src, zOrder, opacity, hRegP, vRegP) {
	"use strict";
	var canvas;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	canvas = newElement("canvas", hOffset, vOffset, zOrder);

	hRegP = hRegP || 0;		// hRegP and vRegP are optional parameters
	vRegP = vRegP || 0;

	canvas.src = src;
	if (opacity === undefined) {
		opacity = 1.0;
	}
	canvas.style.opacity = opacity;
	canvas.style.filter = "alpha(opacity=" + Math.round(100 * opacity) + ")";

	canvas.width = Math.round(scale * width);
	canvas.height = Math.round(scale * height);
	canvas.ctx = canvas.getContext("2d");
	canvas.hRegP = Math.round(scale * hRegP);
	canvas.vRegP = Math.round(scale * vRegP);
	return canvas;
}

function newCanvasImage(canvas, callback) {
    "use strict";
    var img = new Image();

    img.width = canvas.width;
    img.height = canvas.height;
    img.src = canvas.src;
    if (callback !== undefined) {
    	img.onload = function () {
    		callback(img);
    	};
    }
    return img;
}

function drawImage(canvas, img, hOff, vOff, ang) {
    "use strict";
    var ctx = canvas.ctx;
	var width = canvas.width;
	var height = canvas.height;
	var hRegP = canvas.hRegP;
	var vRegP = canvas.vRegP;

    ctx.save();
	ctx.clearRect(0, 0, width, height);
    ctx.translate(hRegP, vRegP);
    ctx.rotate(Math.PI * ang / 180);
    ctx.translate(-hRegP, -vRegP);
    ctx.scale(scale, scale);
    ctx.drawImage(img, hOff, vOff);
    ctx.restore();
}

function drawText(canvas, text, hOff, vOff, ang, font) {
	"use strict";
	var ctx = canvas.ctx;
//	var width = canvas.width;
//	var height = canvas.height;
	var hRegP = canvas.hRegP;
	var vRegP = canvas.vRegP;

	ctx.save();
	//ctx.clearRect(0, 0, width, height);
	ctx.translate(hRegP, vRegP);
	ctx.rotate(Math.PI * ang / 180);
	ctx.translate(-hRegP, -vRegP);
	ctx.scale(scale, scale);
	ctx.font = font;
	ctx.fillText(text, hOff, vOff);
	ctx.restore();
}

function newSelector(hOffset, vOffset, width, height, src, zOrder, opacity) {
	"use strict";
	var selector;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	selector = newElement("select", hOffset, vOffset, zOrder);

	selector.width = Math.round(scale * width);
	selector.height = Math.round(scale * height);
	selector.src = src;
	if (opacity === undefined) {
		opacity = 1.0;
	}	// opacity is an optional parameter
	selector.style.opacity = opacity;
	selector.style.filter = "alpha(opacity=" + Math.round(100 * opacity) + ")";

//	selector.style.fontWeight = "bold";
//	selector.style.fontSize = "14px";

	return selector;
}

function addToMenu(selector, strings) {
	"use strict";
	var option;

	strings.forEach(function (ele) {
		option = document.createElement("option");
		option.text = ele;
		selector.add(option);
	});
}

function removeFromMenu(selector, index) {
 	"use strict";
	selector.remove(index);
}

function clearMenu(selector) {
    "use strict";
	var i;

	for (i = selector.length - 1; i >= 0; i -= 1) {
		selector.remove(i);
	}
}

function newFileSelector(hOffset, vOffset, width, height, ignore, zOrder, style) {
	"use strict";
	var input;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	input = newElement("input", hOffset, vOffset, zOrder);
	input.type = "file";

	input.width = Math.round(scale * width);
	input.size = Math.round(scale * width / hScale);
//    input.style.maxWidth = Math.round(scale * width) + "px";
	input.height = Math.round(scale * height);
//    input.style.maxHeight = Math.round(scale * height) + "px";
//	input.value = value;
	if (style !== undefined) {	// style is an optional parameter
		setStyle(input, style);
	}
	return input;
}

function newCheckbox(hOffset, vOffset, width, height, value, zOrder, style) {
	"use strict";
	var input;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	input = newElement("input", hOffset, vOffset, zOrder);
	input.type = "checkbox";

	input.width = Math.round(scale * width);
	input.size = Math.round(scale * width / fScale);
	input.height = Math.round(scale * height);
	input.value = value;
	if (style !== undefined) {	// style is an optional parameter
		setStyle(input, style);
	}
	return input;
}

function newInputButton(hOffset, vOffset, width, height, value, zOrder, style) {
	"use strict";
	var input;

	hOffset = Math.round(scale * hOffset);
	vOffset = Math.round(scale * vOffset);

	input = newElement("input", hOffset, vOffset, zOrder);
	input.type = "button";

	input.width = Math.round(scale * width);
	input.size = Math.round(scale * width / fScale);
	input.height = Math.round(scale * height);
	input.value = value;
	if (style !== undefined) {	// style is an optional parameter
		setStyle(input, style);
	}
	return input;
}

var moveImg = moveObj;	// for backwards compatibility

///////////////////////////// End of the webWidget functions /////////////////////////////
