// Copyright 2019 Dmitrij  http://www.atbit.de/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* -------------------------------------------------------------------
* define objects (name space) for this library.
* ----------------------------------------------------------------- */
if( typeof html5 == 'undefined' ) {
	html5 = new Object();
}
(function () {

/* -------------------------------------------------------------------
* constructor
* ----------------------------------------------------------------- */
html5.perspective = function(ctxd, image) {
	// check the arguments
	if( ! ctxd || ! ctxd.strokeStyle ) { return; }
	if( ! image || ! image.width || ! image.height ) { return; }
	// prepare a <canvas> for the image
	var cvso = document.createElement('canvas');
	cvso.width = parseInt(image.width);
	cvso.height = parseInt(image.height);
	var ctxo = cvso.getContext('2d');
	ctxo.drawImage(image, 0, 0, cvso.width, cvso.height);
	// prepare a <canvas> for the transformed image
	var cvst = document.createElement('canvas');
	cvst.width = ctxd.canvas.width;
	cvst.height = ctxd.canvas.height;
	var ctxt = cvst.getContext('2d');
	// parameters
	this.p = {
		ctxd: ctxd,
		cvso: cvso,
		ctxo: ctxo,
		ctxt: ctxt
	}
};

/* -------------------------------------------------------------------
* prototypes
* ----------------------------------------------------------------- */
var proto = html5.perspective.prototype;

/* -------------------------------------------------------------------
* public methods
* ----------------------------------------------------------------- */
proto.draw = function(points, max_scale_rate, step) {
	var d0x = Math.round(points[0][0]);
	var d0y = Math.round(points[0][1]);
	var d1x = Math.round(points[1][0]);
	var d1y = Math.round(points[1][1]);
	var d2x = Math.round(points[2][0]);
	var d2y = Math.round(points[2][1]);
	var d3x = Math.round(points[3][0]);
	var d3y = Math.round(points[3][1]);

	// compute the dimension of each side
	var dims = [
		Math.sqrt( Math.pow(d0x-d1x, 2) + Math.pow(d0y-d1y, 2) ), // top side
		Math.sqrt( Math.pow(d1x-d2x, 2) + Math.pow(d1y-d2y, 2) ), // right side
		Math.sqrt( Math.pow(d2x-d3x, 2) + Math.pow(d2y-d3y, 2) ), // bottom side
		Math.sqrt( Math.pow(d3x-d0x, 2) + Math.pow(d3y-d0y, 2) )  // left side
	];
	//
	var ow = this.p.cvso.width;
	var oh = this.p.cvso.height;
	// specify the index of which dimension is longest
	var base_index = 0;
	//max_scale_rate = 0;  Standard
	var zero_num = 0;
	for( var i=0; i<4; i++ ) {
		var rate = 0;
		if( i % 2 ) {
			rate = dims[i] / ow;
		} else {
			rate = dims[i] / oh;
		}
		if( rate > max_scale_rate ) {
			base_index = i;
			max_scale_rate = rate;
		}
		if( dims[i] == 0 ) {
			zero_num ++;
		}
	}
	if(zero_num > 1) { return; }
	//var step = 2; //Org
	var cover_step = step * 5;
	var ctxo = this.p.ctxo;
	var ctxt = this.p.ctxt;
	ctxt.clearRect(0, 0, ctxt.canvas.width, ctxt.canvas.height);
	if(base_index % 2 == 0) { // top or bottom side
		var ctxl = this.create_canvas_context(ow, cover_step);
		var cvsl = ctxl.canvas;
		for( var y=0; y<oh; y+=step ) {
			var r = y / oh;
			var sx = d0x + (d3x-d0x) * r;
			var sy = d0y + (d3y-d0y) * r;
			var ex = d1x + (d2x-d1x) * r;
			var ey = d1y + (d2y-d1y) * r;
			var ag = Math.atan( (ey-sy) / (ex-sx) );
			var sc = Math.sqrt( Math.pow(ex-sx, 2) + Math.pow(ey-sy, 2) ) / ow;
			ctxl.setTransform(1, 0, 0, 1, 0, -y);
			ctxl.drawImage(ctxo.canvas, 0, 0);
			ctxt.translate(sx, sy);
			ctxt.rotate(ag);
			ctxt.scale(sc, sc);
			ctxt.drawImage(cvsl, 0, 0);
			ctxt.setTransform(1, 0, 0, 1, 0, 0);
		}
	} else if(base_index % 2 == 1) { // right or left side
		var ctxl = this.create_canvas_context(cover_step, oh);
		var cvsl = ctxl.canvas;
		for( var x=0; x<ow; x+=step ) {
			var r =  x / ow;
			var sx = d0x + (d1x-d0x) * r;
			var sy = d0y + (d1y-d0y) * r;
			var ex = d3x + (d2x-d3x) * r;
			var ey = d3y + (d2y-d3y) * r;
			var ag = Math.atan( (sx-ex) / (ey-sy) );
			var sc = Math.sqrt( Math.pow(ex-sx, 2) + Math.pow(ey-sy, 2) ) / oh;
			ctxl.setTransform(1, 0, 0, 1, -x, 0);
			ctxl.drawImage(ctxo.canvas, 0, 0);
			ctxt.translate(sx, sy);
			ctxt.rotate(ag);
			ctxt.scale(sc, sc);
			ctxt.drawImage(cvsl, 0, 0);
			ctxt.setTransform(1, 0, 0, 1, 0, 0);
		}
	}
	// set a clipping path and draw the transformed image on the destination canvas.
	this.p.ctxd.save();
	this.set_clipping_path(this.p.ctxd, [[d0x, d0y], [d1x, d1y], [d2x, d2y], [d3x, d3y]]);
	this.p.ctxd.drawImage(ctxt.canvas, 0, 0);
	this.p.ctxd.restore();
}

proto.create_canvas_context = function(w, h) {
	var canvas = document.createElement('canvas');
	canvas.width = w;
	canvas.height = h;
	var ctx = canvas.getContext('2d');
	return ctx;
};

proto.set_clipping_path = function(ctx, points) {
	ctx.beginPath();
	ctx.moveTo(Math.round(points[0][0]), Math.round(points[0][1]));
	for( var i=1; i<points.length; i++ ) {
		ctx.lineTo(Math.round(points[i][0]), Math.round(points[i][1]));
	}
	ctx.closePath();
	ctx.clip();
};

})();

var UploadPathCross = '';
var isMobile = {
	Android: function () {
		return navigator.userAgent.match(/Android/i);
	},
	BlackBerry: function () {
		return navigator.userAgent.match(/BlackBerry/i);
	},
	iOS: function () {
		return navigator.userAgent.match(/iPhone|iPad|iPod/i);
	},
	Opera: function () {
		return navigator.userAgent.match(/Opera Mini/i);
	},
	Windows: function () {
		return navigator.userAgent.match(/IEMobile/i);
	},
	any: function () {
		return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
	}
};
var lastMove = null;
function Upload(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5) {
	var fontsize = get_fontsize();
	var canvas = document.getElementById("DoorFrame");
	var ctx = canvas.getContext('2d');
	var canvas1 = document.createElement('canvas');
	canvas1.width = canvas.width;
	canvas1.height = canvas.height;
	var ctx1 = canvas1.getContext('2d');
	var canvas2 = document.createElement('canvas');
	canvas2.width = canvas.width;
	canvas2.height = canvas.height;
	var ctx2 = canvas2.getContext('2d');
	var op = null;
	var points = [[x1, y1], [x2, y2], [x3, y3], [x4, y4], [x5, y5]];
	var img = new Image();

	var point_w = 31;
	if (isMobile.any()) {
		point_w = 61;
	}

	console.log('isMobile: ' + isMobile.any() + '  (' + navigator.userAgent + ')' )

	img.src = $('#upload_door').attr('src');
	img.onload = function () {
		op = new html5.perspective(ctx1, img);
		op.draw(points, 20, 1);
		//prepare_lines(ctx2, points, false, true);
		draw_canvas(ctx, ctx1, ctx2);
	};

	var drag = null;
	canvas.addEventListener("mousedown", function (event) {
		event.preventDefault();
		lastMove = event;
		var p = get_mouse_position(event);
		for (var i = 0; i < 5; i++) {
			var x = Math.floor((points[i][0]) * fontsize / 100);
			var y = Math.floor((points[i][1]) * fontsize / 100);
			if (p.x < x + (point_w - 1) / 2 && p.x > x - (point_w - 1) / 2 && p.y < y + (point_w - 1) / 2 && p.y > y - (point_w - 1) / 2) {
				drag = i; 
				break;
			}
		}
	}, false);

	canvas.addEventListener("touchstart", function (event) {
		var mouseEvent = new MouseEvent("mousemove", {});
		event.preventDefault();
		var p = getTouchPos(canvas, event);
		for (var i = 0; i < 5; i++) {
			var x = Math.floor((points[i][0]) * fontsize / 100);
			var y = Math.floor((points[i][1]) * fontsize / 100);
			if (p.x < x + (point_w - 1) / 2 && p.x > x - (point_w - 1) / 2 && p.y < y + (point_w - 1) / 2 && p.y > y - (point_w - 1) / 2) {
				drag = i;
				break;
			}
		}
		canvas.dispatchEvent(mouseEvent);
	}, false);

	canvas.addEventListener("mousemove", function (event) {
		event.preventDefault();
		if (drag == null) { return; }
		var p = get_mouse_position(event);
		if (isMobile.any()) {
			p = getTouchPos(canvas, lastMove);
		}
		if (drag == 4) {
			var org_x = Math.floor(points[4][0] * fontsize / 100);
			var org_y = Math.floor(points[4][1] * fontsize / 100);
			for (var i = 0; i < 4; i++) {
				points[i][0] = (Math.floor(points[i][0] * fontsize / 100) + (p.x - org_x)) * 100 / fontsize;
				points[i][1] = (Math.floor(points[i][1] * fontsize / 100) + (p.y - org_y)) * 100 / fontsize;
			}
		}
		ctx.globalAlpha = 0.5;
		points[drag][0] = p.x * 100 / fontsize;
		points[drag][1] = p.y * 100 / fontsize;
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		ctx1.clearRect(0, 0, canvas.width, canvas.height);
		if (isMobile.any()) {
			prepare_lines(ctx2, points, true, true);
		}
		else {
			op.draw(points, 10, 1);// Tür zeichnen
			prepare_lines(ctx2, points, false, true);
		}
		draw_canvas(ctx, ctx1, ctx2);
	}, false);

	canvas.addEventListener("touchmove", function (event) {
		lastMove = event;
		var mouseEvent = new MouseEvent("mousemove", {});
		canvas.dispatchEvent(mouseEvent);
	}, false);

	canvas.addEventListener("mouseup", function (event) {
		ctx.globalAlpha = 1;
		event.preventDefault();
		if (drag == null) { return; }
		var p = get_mouse_position(event);
		if (isMobile.any()) {
			p = getTouchPos(canvas, lastMove);
		}
		points[drag][0] = p.x * 100 / fontsize;
		points[drag][1] = p.y * 100 / fontsize;
		updateDynLayer('mfUpdate', UploadPathCross, 'cross=' + (drag + 1) + '&x=' + Math.round(points[drag][0]) + '&y=' + Math.round(points[drag][1]));
		if (isMobile.any()) {
			draw_canvas(ctx, ctx1, ctx2);
			op.draw(points, 10, 5);// Tür zeichnen
		}
		else{
			op.draw(points, 10, 5);// Tür zeichnen
		}
		//prepare_lines(ctx2, points, false, true);
		draw_canvas(ctx, ctx1, ctx2);
		drag = null;
	}, false);

	canvas.addEventListener("touchend", function (event) {
		var mouseEvent = new MouseEvent("mouseup", {});
		canvas.dispatchEvent(mouseEvent);
	}, false);

	canvas.addEventListener("mouseout", function (event) {
		prepare_lines(ctx2, points, false, false);
		ctx.globalAlpha = 1;
		event.preventDefault();
		drag = null;
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
		draw_canvas(ctx, ctx1, ctx2);
	}, false);

	canvas.addEventListener("mouseenter", function (event) {
		fontsize = get_fontsize();
		prepare_lines(ctx2, points, false, true);
		draw_canvas(ctx, ctx1, ctx2);
		ctx.globalAlpha = 1;
		event.preventDefault();
		drag = null;
	}, false);

	// Get the position of a touch relative to the canvas
	function getTouchPos(canvasDom, touchEvent) {
		var rect = canvasDom.getBoundingClientRect();
		return {
			x: touchEvent.touches[0].clientX - rect.left,
			y: touchEvent.touches[0].clientY - rect.top
		};
	}

	function prepare_lines(ctx, p, border, centerpoint) {
		ctx.save();
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
		if (border) {
			ctx.beginPath();
			ctx.moveTo(p[0][0], p[0][1]);
			for( var i=1; i<4; i++ ) {
				ctx.lineTo(p[i][0], p[i][1]);
			}
			ctx.closePath();
			ctx.strokeStyle = "red";
			ctx.stroke();
		}

		// Centerpoint
		if (centerpoint) {
			var xs = Math.min(p[0][0], p[2][0]) + Math.round(Math.abs(p[0][0] - p[2][0]) / 2);
			var xm = Math.min(p[1][0], p[3][0]) + Math.round(Math.abs(p[1][0] - p[3][0]) / 2);
			var ys = Math.min(p[0][1], p[1][1]) + Math.round(Math.abs(p[0][1] - p[1][1]) / 2);
			var ym = Math.min(p[2][1], p[3][1]) + Math.round(Math.abs(p[2][1] - p[3][1]) / 2);
			p[4][0] = xs + Math.round((xm - xs) / 2);
			p[4][1] = ys + Math.round((ym - ys) / 2);

			ctx.fillStyle = "red";
			for (var i = 0; i < 5; i++) {
				ctx.beginPath();
				ctx.strokeStyle = 'red';
				ctx.strokeRect(p[i][0] - (point_w - 1) / 2, p[i][1] - (point_w - 1) / 2, point_w, point_w);
				if (isMobile.any()) {
					ctx.strokeRect(p[i][0] - 1, p[i][1] - 1, 2, 2);
				}
				//ctx.fillStyle = "red";
				//ctx.font = "15px Arial";
				//ctx.fillText(p[i][0] + ' - ' + p[i][1], p[i][0], p[i][1]-30);
				//ctx.fill();
			}
		}
		ctx.restore();
	}


	function draw_canvas(ctx, ctx1, ctx2) {
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
		ctx.drawImage(ctx1.canvas, 0, 0);
		ctx.drawImage(ctx2.canvas, 0, 0);
	}

	function get_mouse_position(event) {
		var rect = event.target.getBoundingClientRect();
		return {
			x: event.clientX - rect.left,
			y: event.clientY - rect.top
		};
	}

	function get_fontsize(){
		var fontsize = $('#DisplayImgDiv').css('font-size');
		fontsize = fontsize.substring(0, fontsize.length - 2) * 10;
		return fontsize;
	}

};








