"use strict";
(function (window, undefined) {
	var addEvent = System.addEvent,
		hasClass = System.hasClass,
		addClass = System.addClass,
		removeClass = System.removeClass,
		jsApiRequest = System.jsApiRequest,

		activeElem = '.',
		floors = {
			'.':{ className:'floorNone',	left:0, top:0 },
			'0':{ className:'floor0',		left:1, top:0 },
			'a':{ className:'floor0 off',	left:1, top:1 },
			'A':{ className:'floor0 on',	left:1, top:2 },
			'1':{ className:'floor1',		left:2, top:0 },
			'b':{ className:'floor1 off',	left:2, top:1 },
			'B':{ className:'floor1 on',	left:2, top:2 },
			'2':{ className:'floor2',		left:3, top:0 },
			'c':{ className:'floor2 off',	left:3, top:1 },
			'C':{ className:'floor2 on',	left:3, top:2 },
			'3':{ className:'floor3',		left:4, top:0 },
			'd':{ className:'floor3 off',	left:4, top:1 },
			'D':{ className:'floor3 on',	left:4, top:2 }
		},

		viewport = document.getElementById('viewport'),
		world = document.getElementById('world'),
		editor = document.getElementById('editor'),
		drawMode = false,
		sizeMode = false,
		sizeMap, sizeWidth, sizeHeight, sizeY, sizeElem;

	window['Editor'] = {
	};

	// Initialization
	(function () {
		var i, j = 0, elem, subElem;

		// FLOORS

		for (i in floors) {
			elem = document.createElement('div');

			subElem = document.createElement('div');
			subElem.className = floors[i].className;
			elem.appendChild(subElem);

			elem.className = (activeElem === i ? 'select active' : 'select');
			elem.style.left = ((floors[i].left * 108) + 32) + 'px';
			elem.style.top = ((floors[i].top * 112) + 32) + 'px';

			addEvent(elem, 'mousedown', (function (elem, elemType) { return function () {
				removeClass(document.querySelector('#editor .select.active'), 'active');
				addClass(elem, 'active');
				activeElem = elemType;
			}; })(elem, i));

			editor.appendChild(elem);
			j++;
		}

		// ROBOT

		elem = document.createElement('div');
		subElem = document.createElement('div');
		subElem.className = 'robot dir2';
		elem.appendChild(subElem);

		elem.className = (activeElem === '$' ? 'select active' : 'select');
		elem.style.left = ((0 * 108) + 32) + 'px';
		elem.style.top = ((1 * 112) + 32) + 'px';

		addEvent(elem, 'mousedown', (function (elem) { return function () {
			removeClass(document.querySelector('#editor .select.active'), 'active');
			addClass(elem, 'active');
			activeElem = '$';
		}; })(elem));

		editor.appendChild(elem);

		// SIZE

		elem = document.createElement('div');
		elem.className = 'sizer';
		subElem = document.createElement('div');
		sizeElem = elem.appendChild(subElem);

		addEvent(elem, 'mousedown', function (e) {
			if (e.button === 0) {
				sizeMode = true;

				var w = Math.ceil((e.layerX + 1) / 10),
					h = Math.ceil((e.layerY + 1) / 10);

				sizeElem.style.width = (w * 10) + 'px';
				sizeElem.style.height = (h * 10) + 'px';

				sizeMap = Level.map;
				sizeWidth = Level.width;
				sizeHeight = Level.height;
				sizeY = Level.y;
				Level.map = resizeMap(sizeMap, Level.width, Level.height, w, h);
				Level.width = (w > 12 ? 12 : w);
				Level.height = (h > 12 ? 12 : h);
				Level.y = sizeY + (Level.height - sizeHeight);
				Draw.initLevel();
				Draw.resetLevel();
			}
		});
		addEvent(elem, 'mousemove', function (e) {
			if (sizeMode) {
				var w = Math.ceil((e.layerX + 1) / 10),
					h = Math.ceil((e.layerY + 1) / 10);

				sizeElem.style.width = (w * 10) + 'px';
				sizeElem.style.height = (h * 10) + 'px';

				Level.map = resizeMap(sizeMap, sizeWidth, sizeHeight, w, h);
				Level.width = (w > 12 ? 12 : w);
				Level.height = (h > 12 ? 12 : h);
				Level.y = sizeY + (Level.height - sizeHeight);
				Draw.initLevel();
				Draw.resetLevel();
			}
		});
		addEvent(elem, 'mouseup', function (e) {
			if (e.button === 0) {
				sizeMode = false;

				var w = Math.ceil((e.layerX + 1) / 10),
					h = Math.ceil((e.layerY + 1) / 10);

				Level.map = resizeMap(sizeMap, sizeWidth, sizeHeight, w, h);
				Level.width = (w > 12 ? 12 : w);
				Level.height = (h > 12 ? 12 : h);
				Level.y = sizeY + (Level.height - sizeHeight);
				Draw.initLevel();
				Draw.resetLevel();
			}
		});

		editor.appendChild(elem);

		// BUTTONS

		addEvent(document.getElementById('editorClear'), 'click', function () {
			var y, map = '';
			for (y = 0; y < Level.height; y++) {
				map += '000000000000'.substr(0, Level.width);
			}
			Level.map = map;
			Draw.initLevel();
			Draw.resetLevel();
		});
		addEvent(document.getElementById('editorReset'), 'click', function () {
			Level.setLevel(Level.idx);
			Draw.initLevel();
			Draw.resetLevel();
		});
		addEvent(document.getElementById('editorGetCode'), 'click', function () {
			alert(
				'map: ' + Level.map + '\n' +
				'width: ' + Level.width + '\n' +
				'height: ' + Level.height + '\n' +
				'x: ' + Level.x + '\n' +
				'y: ' + Level.y + '\n' +
				'dir: ' + Level.dir
			);
		});

		// DRAW MODE

		addEvent(viewport, 'mousedown', function (e) {
			if (e.button === 0 && hasClass(world, 'edit')) {
				drawMode = true;
			}
		});
		addEvent(world, 'mousedown', function (e) {
			if (e.button === 0 && hasClass(world, 'edit')) {
				drawMode = true;
			}

			if (drawMode) {
				var x = e.pageX - ((viewport.offsetWidth >> 1) + parseInt(world.style.marginLeft, 10)) - 45,
					y = e.pageY - ((viewport.offsetHeight >> 1) + parseInt(world.style.marginTop, 10)) - 46,
					pos = Draw.reTransformCoords(x, y);

				if (activeElem === '$') {
					if (Level.x === pos.x >> 6 && Level.y === pos.y >> 6) {
						Level.dir = (Level.dir + 1) % 4;
					} else {
						Level.x = pos.x >> 6;
						Level.y = pos.y >> 6;
					}
				} else {
					Level.setFloor(pos.x >> 6, pos.y >> 6, activeElem);
				}
				Draw.resetLevel();
			}
		});
		addEvent(world, 'mousemove', function (e) {
			if (!hasClass(world, 'edit')) { return; }

			var x = e.pageX - ((viewport.offsetWidth >> 1) + parseInt(world.style.marginLeft, 10)) - 45,
				y = e.pageY - ((viewport.offsetHeight >> 1) + parseInt(world.style.marginTop, 10)) - 46,
				pos = Draw.reTransformCoords(x, y),
				elem;

			if (drawMode) {
				Level.setFloor(pos.x >> 6, pos.y >> 6, activeElem);
				Draw.resetLevel();
			}

			if (pos.x < 0 || pos.y < 0 || pos.x >> 6 >= Level.width || pos.y >> 6 >= Level.height) {
				removeClass(world, 'hover');
				elem = document.querySelector('.edit .hover');
				if (elem !== null) { removeClass(elem, 'hover'); }
			} else {
				addClass(world, 'hover');
				if (!hasClass(Draw.getFloorElem(pos.x >> 6, pos.y >> 6), 'hover')) {
					elem = document.querySelector('.edit .hover');
					if (elem !== null) { removeClass(elem, 'hover'); }
					addClass(Draw.getFloorElem(pos.x >> 6, pos.y >> 6), 'hover');
				}
			}
		});
		addEvent(world, 'mouseout', function (e) {
			if (!hasClass(world, 'edit')) { return; }

			removeClass(world, 'hover');
			var elem = document.querySelector('.edit .hover');
			if (elem !== null) { removeClass(elem, 'hover'); }
		});

		addEvent(viewport, 'mouseup', function (e) {
			if (e.button === 0) {
				drawMode = false;
				sizeMode = false;
			}
		});

		addEvent(window, 'keyup', function (e) {
			if (e.target.nodeName.toUpperCase() === 'INPUT') {
				return;
			}

			switch (e.keyCode) {
				case 122:	// F11
					if (hasClass(editor, 'visible')) {
						removeClass(editor, 'visible');
						removeClass(world, 'edit');
						removeClass(world, 'hover');
						drawMode = false;
						sizeMode = false;
					} else {
						addClass(editor, 'visible');
						addClass(world, 'edit');
						sizeElem.style.width = (Level.width * 10) + 'px';
						sizeElem.style.height = (Level.height * 10) + 'px';
					}
					break;
			}

			e.preventDefault();
			e.stopPropagation();
		});
	})();
	
	function resizeMap(srcMap, srcWidth, srcHeight, dstWidth, dstHeight) {
		var i, map = '';

		for (i = 0; i < Math.min(srcHeight, dstHeight); i++) {
			map += srcMap.substr(i * srcWidth, Math.min(srcWidth, dstWidth)) + (srcWidth < dstWidth ? '...........'.substr(0, dstWidth - srcWidth) : '');
		}

		for (i = 0; i < dstHeight - srcHeight; i++) {
			map += '............'.substr(0, dstWidth);
		}
		return map;
	}
})(window);
