/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
const Role = require('./wb-role');
const WbTools = require('./wb-tools');
const WbZoom = require('./wb-zoom');
const APointer = require('./wb-tool-apointer');
const Player = require('./wb-player');
const TMath = require('./wb-tool-math');
const StaticTMath = require('./wb-tool-stat-math');
require('fabric'); // will produce `fabric` namespace

const BUMPER = 100
	, extraProps = ['uid', 'fileId', 'fileType', 'count', 'slide', 'omType', '_src', 'formula'];


module.exports = class Wb {
	constructor(wbo, tcid, _role) {
		this.id = wbo.wbId;
		this.title = wbo.name;
		this.width = wbo.width;
		this.height = wbo.height;
		this.slide = 0;

		const canvases = [], self = this;
		let wbEl, tools, zoomBar
			, role = null, scrollTimeout = null;

		function _removeHandler(o) {
			const __o = self._findObject(o);
			if (!!__o) {
				const cnvs = canvases[o.slide];
				if (!!cnvs) {
					if ('Video' === __o.omType) {
						$('#wb-video-' + __o.uid).remove();
					}
					cnvs.remove(__o);
				}
			}
		}
		function _modifyHandler(_o) {
			_removeHandler(_o);
			_createHandler(_o);
		}
		function _createHandler(_o) {
			switch (_o.fileType) {
				case 'VIDEO':
				case 'RECORDING':
					//no-op
					break;
				case 'PRESENTATION':
				{
					const ccount = canvases.length;
					for (let i = 0; i < _o.count; ++i) {
						if (canvases.length < i + 1) {
							addCanvas();
						}
						const canvas = canvases[i];
						if (_o.deleted) {
							ToolUtil.addDeletedItem(canvas, _o);
						} else {
							let scale = self.width / _o.width;
							scale = scale < 1 ? 1 : scale;
							canvas.setBackgroundImage(_o._src + '&slide=' + i, canvas.renderAll.bind(canvas)
									, {scaleX: scale, scaleY: scale});
						}
					}
					zoomBar.update(role, canvases.length);
					if (ccount !== canvases.length) {
						tools.reactivateBtn();
						self._showCurrentSlide();
					}
				}
					break;
				default:
				{
					const canvas = canvases[_o.slide];
					if (!!canvas) {
						_o.selectable = canvas.selection;
						_o.editable = ('text' === tools.getMode() || 'textbox' === tools.getMode());
						canvas.add(_o);
					}
				}
					break;
			}
		}
		function _createObject(arr, handler) {
			fabric.util.enlivenObjects(arr, function(objects) {
				for (let i = 0; i < objects.length; ++i) {
					const _o = objects[i];
					_o.loaded = true;
					handler(_o);
				}

				self.eachCanvas(function(canvas) {
					canvas.requestRenderAll();
				});
			});
		}

		//events
		function objCreatedHandler(o) {
			if (role === Role.NONE && o.omType !== 'pointer') {
				return;
			}
			let json;
			switch(o.omType) {
				case 'pointer':
					json = o;
					break;
				default:
					o.includeDefaultValues = false;
					json = self._toOmJson(o);
					break;
			}
			OmUtil.wbAction({action: 'createObj', data: {
				wbId: self.id
				, obj: json
			}});
		}
		function objAddedHandler(e) {
			const o = e.target;
			if (o.loaded === true) {
				return;
			}
			switch(o.omType) {
				case 'textbox':
				case 'i-text':
					o.uid = uuidv4();
					o.slide = this.slide;
					objCreatedHandler(o);
					break;
				default:
					o.selectable = this.selection;
					break;
			}
		}
		function objModifiedHandler(e) {
			const o = e.target, items = [];
			if (role === Role.NONE && o.omType !== 'pointer') {
				return;
			}
			function modifiedAction(items) {
				OmUtil.wbAction({action: 'modifyObj', data: {
					wbId: self.id
					, obj: items
				}});
			}
			o.includeDefaultValues = false;
			if ('activeSelection' === o.type) {
				o.clone(function(_o) {
					// ungrouping
					_o.includeDefaultValues = false;
					const _items = _o.destroy().getObjects();
					for (let i = 0; i < _items.length; ++i) {
						items.push(self._toOmJson(_items[i]));
					}
					modifiedAction(items);
				}, extraProps);
			} else {
				items.push(self._toOmJson(o));
				modifiedAction(items);
			}
		}
		function objSelectedHandler(e) {
			tools.updateCoordinates(e.target);
		}
		function selectionCleared(e) {
			const o = e.target;
			if (!o || '' !== o.text) {
				return;
			}
			if ('textbox' === o.omType || 'i-text' === o.omType) {
				OmUtil.wbAction({action: 'deleteObj', data: {
					wbId: self.id
					, obj: [{
						uid: o.uid
						, slide: o.slide
					}]
				}});
			}
		}
		function pathCreatedHandler(o) {
			o.path.uid = uuidv4();
			o.path.slide = this.slide;
			o.path.omType = 'freeDraw';
			objCreatedHandler(o.path);
		}
		function scrollHandler() {
			if (scrollTimeout !== null) {
				clearTimeout(scrollTimeout);
			}
			scrollTimeout = setTimeout(function() {
				const sc = wbEl.find('.scroll-container')
					, canvases = sc.find('.canvas-container');
				if (Math.round(sc.height() + sc[0].scrollTop) === sc[0].scrollHeight) {
					if (self.slide !== canvases.length - 1) {
						self._doSetSlide(canvases.length - 1);
					}
					return false;
				}
				canvases.each(function(idx) {
					const h = $(this).height(), pos = $(this).position();
					if (self.slide !== idx && pos.top > BUMPER - h && pos.top < BUMPER) {
						self._doSetSlide(idx);
						return false;
					}
				});
			}, 100);
		}
		/*TODO interactive text change
		var textEditedHandler = function (e) {
			var obj = e.target;
			OmUtil.log('Text Edit Exit', obj);
		};
		var textChangedHandler = function (e) {
			var obj = e.target;
			OmUtil.log('Text Changed', obj);
		};*/
		function setHandlers(canvas) {
			// off everything first to prevent duplicates
			canvas.off({
				'wb:object:created': objCreatedHandler
				, 'object:modified': objModifiedHandler
				, 'object:added': objAddedHandler
				, 'object:selected': objSelectedHandler
				, 'path:created': pathCreatedHandler
				//, 'text:editing:exited': textEditedHandler
				//, 'text:changed': textChangedHandler
				, 'before:selection:cleared': selectionCleared
			});
			canvas.on({
				'wb:object:created': objCreatedHandler
				, 'object:modified': objModifiedHandler
			});
			if (role !== Role.NONE) {
				canvas.on({
					'object:added': objAddedHandler
					, 'object:selected': objSelectedHandler
					, 'path:created': pathCreatedHandler
					, 'before:selection:cleared': selectionCleared
					//, 'text:editing:exited': textEditedHandler
					//, 'text:changed': textChangedHandler
				});
			}
		}
		function addCanvas() {
			const sl = canvases.length
				, cid = 'can-' + self.id + '-slide-' + sl
				, c = $('<canvas></canvas>').attr('id', cid);
			wbEl.find('.canvases').append(c);
			const canvas = new fabric.Canvas(c.attr('id'), {
				preserveObjectStacking: true
			});
			canvas.wbId = self.id;
			canvas.slide = sl;
			canvases.push(canvas);
			const cc = $('#' + cid).closest('.canvas-container');
			if (role === Role.NONE) {
				if (sl === self.slide) {
					cc.show();
				} else {
					cc.hide();
				}
			}
			__setSize(canvas);
			setHandlers(canvas);
		}
		function __setSize(_cnv) {
			_cnv.setWidth(zoomBar.getZoom() * self.width)
				.setHeight(zoomBar.getZoom() * self.height)
				.setZoom(zoomBar.getZoom());
		}
		function _setSize(skipSendWsMsg) {
			zoomBar.setSize();
			self.eachCanvas(function(canvas) {
				__setSize(canvas);
			});
			if (!skipSendWsMsg) {
				self._doSetSlide(self.slide);
			}
		}
		function _videoStatus(json) {
			const g = self._findObject(json);
			if (!!g) {
				g.videoStatus(json.status);
			}
		}

		this._toOmJson = (o) => {
			const r = o.toJSON(extraProps);
			switch (o.omType) {
				case 'Video':
					delete r.objects;
					break;
				case TMath.TYPE:
					delete r.objects;
					break;
				default:
					//no-op
			}
			return r;
		};
		this._findObject = (o) => {
			let _o = null;
			const cnvs = canvases[o.slide];
			if (!!cnvs) {
				cnvs.forEachObject(function(__o) {
					if (!!__o && o.uid === __o.uid) {
						_o = __o;
						return false;
					}
				});
			}
			return _o;
		};
		this.setRole = (_role) => {
			if (role !== _role) {
				role = _role;
				const sc = wbEl.find('.scroll-container');
				if (role === Role.NONE) {
					sc.off('scroll', scrollHandler);
				} else {
					sc.on('scroll', scrollHandler);
				}
				self._showCurrentSlide();
				this.eachCanvas(function(canvas) {
					setHandlers(canvas);
					canvas.forEachObject(function(__o) {
						if (!!__o && __o.omType === 'Video') {
							__o.setPlayable(role);
						}
					});
				});
				tools.setRole(role);
				zoomBar.setRole(role);
				zoomBar.update(role, canvases.length);
				_setSize();
			}
		};
		this.setSize = (wbo) => {
			this.width = wbo.width;
			this.height = wbo.height;
			zoomBar.init(wbo);
			_setSize();
		};
		this.doSetSize = _setSize;
		this.resize = () => {
			if (zoomBar.getMode() !== 'ZOOM') {
				_setSize(true);
			}
		};
		this._showCurrentSlide = () => {
			wbEl.find('.scroll-container .canvas-container').each(function(idx) {
				if (role === Role.PRESENTER) {
					$(this).show();
					const cclist = wbEl.find('.scroll-container .canvas-container');
					if (cclist.length > self.slide) {
						cclist[self.slide].scrollIntoView();
					}
				} else {
					if (idx === self.slide) {
						$(this).show();
					} else {
						$(this).hide();
					}
				}
			});
		};
		this._doSetSlide = (_sld) => {
			const sld = 1 * _sld;
			if (sld < 0 || sld > canvases.length - 1) {
				return;
			}
			self.slide = _sld;
			OmUtil.wbAction({action: 'setSlide', data: {
				wbId: self.id
				, slide: _sld
			}});
			zoomBar.update(role, canvases.length);
		};
		this.setSlide = (_sl) => {
			self.slide = _sl;
			self._showCurrentSlide();
		};
		this.createObj = (obj) => {
			const arr = [], del = [], _arr = Array.isArray(obj) ? obj : [obj];
			for (let i = 0; i < _arr.length; ++i) {
				const o = _arr[i];
				if (!!o.deleted && 'PRESENTATION' !== o.fileType) {
					del.push(o);
					continue;
				}
				switch(o.omType) {
					case 'pointer':
						new APointer(this).create(canvases[o.slide], o);
						break;
					case 'Video':
						Player.create(canvases[o.slide], o, self);
						break;
					case TMath.TYPE:
						StaticTMath.create(o, canvases[o.slide]);
						break;
					default:
					{
						const __o = self._findObject(o);
						if (!__o) {
							arr.push(o);
						}
					}
						break;
				}
			}
			if (arr.length > 0) {
				_createObject(arr, _createHandler);
			}
			for (let i = 0; i < del.length; ++i) {
				const o = del[i];
				ToolUtil.addDeletedItem(canvases[o.slide], o);
			}
		};
		this.load = this.createObj;
		this.modifyObj = (obj) => { //TODO need to be unified
			const arr = [], _arr = Array.isArray(obj) ? obj : [obj];
			for (let i = 0; i < _arr.length; ++i) {
				const o = _arr[i];
				switch(o.omType) {
					case 'pointer':
						_modifyHandler(new APointer(this).create(canvases[o.slide], o));
						break;
					case 'Video':
					{
						const g = self._findObject(o);
						if (!!g) {
							Player.modify(g, o);
						}
					}
						break;
					case TMath.TYPE:
					{
						_removeHandler(o);
						StaticTMath.create(o, canvases[o.slide]);
					}
						break;
					default:
						arr.push(o);
						break;
				}
			}
			if (arr.length > 0) {
				_createObject(arr, _modifyHandler);
			}
		};
		this.removeObj = (arr) => {
			for (let i = 0; i < arr.length; ++i) {
				_removeHandler(arr[i]);
			}
		};
		this.clearAll = () => {
			for (let i = 1; i < canvases.length; ++i) {
				const cc = $('#can-' + this.id + '-slide-' + i).closest('.canvas-container');
				cc.remove();
				canvases[i].dispose();
			}
			$('.room-block .wb-block .wb-video').remove();
			canvases.splice(1);
			canvases[0].clear();
			zoomBar.update(role, canvases.length);
		};
		this.clearSlide = (_sl) => {
			if (canvases.length > _sl) {
				const canvas = canvases[_sl];
				let arr = canvas.getObjects();
				while (arr.length > 0) {
					canvas.remove(arr[arr.length - 1]);
					arr = canvas.getObjects();
				}
				$('.room-block .wb-block .wb-video.slide-' + _sl).remove();
				canvas.requestRenderAll();
			}
		};
		this.getCanvas = (_slide) => {
			return canvases[typeof(_slide) === 'number' ? _slide : self.slide];
		};
		this.eachCanvas = (func) => {
			for (let i = 0; i < canvases.length; ++i) {
				func(canvases[i]);
			}
		};
		this.videoStatus = _videoStatus;
		this.getRole = () => {
			return role;
		};
		this.getFormula = () => {
			return tools.getMath();
		};
		this.getZoom = () => {
			return zoomBar.getZoom();
		};
		this.destroy = () => {
			tools.destroy();
		};

		wbEl = $('#' + tcid);
		tools = new WbTools(wbEl, this);
		zoomBar = new WbZoom(wbEl, this);
		zoomBar.init(wbo);
		addCanvas();
		this.setRole(_role);
	}

	getId() {
		return this.id;
	}
};
