var $ = jQuery.noConflict();
// uses jquery.contextMenu - http://swisnl.github.io/jQuery-contextMenu/

function MenuEdit() {

	var _this = this;
	var source, template, activeMenu;
	var copyHelper;

	function displayMenus(data) {
		var $target = $('#menusource');
		if (typeof data.source != 'undefined') {
			_populateMenu(data.source, '#menusource');
			$target.sortable({
				grid: [10,10],
				zIndex: 200,
				appendTo: '.menuedit-container',
				helper: 'clone',
				items: '> span.me-item',
				forcePlaceholderSize: false,
				helper: function(e,li) {
					copyHelper= li.clone().insertAfter(li);
					return li.clone();
				},
				stop: function(e, ui) {
					copyHelper && copyHelper.remove();
				}
			}).disableSelection();
		}
		$.each(data, function(key, value) {
			if (typeof value.caption != 'undefined') {
				_loadTab(key, value);
			}
		});
		var $tablist = $('#menuedit_tabs');
		$tablist.tabs('refresh');
		$tablist.tabs('option', 'active', 0);
	}

	function _loadMenus() {
		$.ajax({
			dataType: 'json',
			async: true,
			url: '/admin/menus/load',
			type: 'GET'
		}).done(function(data) {
			displayMenus(data);
		});
	}

	function htmlToElement(html) {
		var t = document.createElement('template');
		t.innerHTML = html;
		return t.content.firstChild;
	}
	
	function _populateMenu(source, target) {
	// create new fragment from source items
		var fragment = document.createDocumentFragment();
		$.each(source, function(key, value) {
			value.margin = (typeof value.i == 'undefined') ? 10 : 10 + parseInt(value.i);
			var element = htmlToElement(template(value));
			fragment.appendChild(element);
		});
		var $target = $(target);
		$('span.me-item', $target).remove();
		$target[0].appendChild(fragment);
	}
	
	function _setActiveTab($panel) {
		var id = $panel.attr('id');
		var $target = $('#menusource');
		activeMenu = id;
		$target.sortable('option', 'connectWith', '#_' + id);
	}

	function _removeItem($item) {
		$item.remove();
	}
	
	function _editItem($item, source) {
		var indent, active, id;
		var idx = $item.index();
		if (source) {
			indent = 0;
			active = source;
			id = $item.data('id');
		} else {
			indent = parseInt($item.css('margin-left').replace('px', '')) - 10;
			active = activeMenu;
			id = -1;
		}
		var href = $item.data('href');
		var flags = $item.data('s');
		var caption = $item.find('span.me-caption').text();
		var mask = $item.data('mask');
		if (mask !== false) caption = mask;
		var data = {active: active,
					idx: idx,
					id: id,
					indent: indent,
					href: href,
					flags: flags,
					caption: caption
					};
		main.loadURL('/admin/menus/edit', data);
	}
	
	function _option_new() {
		var data = {active: 'source',
					idx: -1,
					id: 0,
					flags: 10,
					caption: ''
					};
		main.loadURL('/admin/menus/edit', data);
	}

	function _slideItem($item, delta) {
		var $sib = $item.prev();
		var max = ($sib.length) ? parseInt($sib.css('margin-left').replace('px', '')) : 0;
		var indent = parseInt($item.css('margin-left').replace('px', '')) - 10;
		var newpos = indent + delta;
		if (newpos < 0) {
			newpos = 0;
		} else if (newpos > max) {
			newpos = max;
		}
		var m = newpos % 10;
		if (m > 5) {
			newpos += (10 - m);	// round up
		} else {
			newpos -= m;		// round down
		}
		$item.css('margin-left', (newpos + 10) + 'px');
	}
	
	// assemble all menus, write to file, reload page
	function _saveMenus(auth) {
		var output = {};
		var $tablist = $('#menuedit_tabs div.ui-tabs-panel div.menuedit-grid');
		$tablist.each(function() {
			var $menu = $(this);
			var id = $menu.closest('div.ui-tabs-panel').attr('id');
			output[id] = _retrieveMenu($menu);
		});
		output.auth = auth;
		$.ajax({
			dataType: 'json',
			async: true,
			data: output,
			url: '/admin/menus/save',
			type: 'POST'
		}).done(function(data) {
			window.location.reload(true);
		});
	}
	
	function _retrieveMenu($menu) {
		var output = [];
		$('span.me-item', $menu).each(function() {
			var $item = $(this);
			var indent = parseInt($item.css('margin-left').replace('px', '')) - 10;
			var caption = $item.find('span.me-caption').text();
			var s = parseInt(this.dataset.s);
//			if (typeof this.dataset.mask != 'undefined' && !(s & 8)) caption = this.dataset.mask;
			if (s & 8) caption = this.dataset.mask;
			output.push({c: caption,
						 s: this.dataset.s,
						 i: indent,
						 id: this.dataset.id,
						 l: this.dataset.href});
		});
		return output;
	}
	
	function _loadTab(key, value) {
		var $tablist = $('#menuedit_tabs ul.ui-tabs-nav');
		$tablist.append('<li><a href="#' + key + '">' + value.caption + '</a></li>');
		$tablist = $('#menuedit_tabs');
		$tablist.append('<div class="menuedit-tab" id="' + key + '"><div class="menuedit-grid" id="_' + key + '"></div></div>');
		_populateMenu(value.items, '#' + key + ' div.menuedit-grid');
		
		var $target = $('#' + key + ' div.menuedit-grid');
		$target.sortable({
			grid: [10,10],
			appendTo: '.menuedit-container',
			zIndex: 200,
			items: '> span.me-item',
			receive: function(e,ui) {
				copyHelper= null;
			},
			stop: function(event, ui) {
				var delta = ui.position.left - ui.originalPosition.left;
				if (Math.abs(delta) > 5) {
					_slideItem(ui.item, delta);
				}
			}
		}).disableSelection();
	}
	
	function _disableCaption(disabled) {
		var $cap = $('#caption');
		$cap.prop('disabled', disabled );
		disabled ? $cap.addClass('disabled') : $cap.removeClass('disabled');
	}

	function _getitem(formdata, entry) {
		for(var i = 0; i < formdata.length; i++) {
			if (formdata[i].name == entry) return formdata[i].value;
		}
		return false;
	}
	
	function _getSelectedItem(tab, idx) {
		var $item;
		if (tab == 'source') {
			$item = $('#menusource span.me-item').eq(idx);
		} else {
			$item = $('#_' + tab + ' span.me-item').eq(idx);
		}
		return $item;
	}
	
	function _createEditMenu($item, id, caption) {
		var data = {id: id, caption: caption};
		$.ajax({
			dataType: 'json',
			async: true,
			data: data,
			url: '/admin/menus/custom',
			type: 'GET'
		}).done(function(data) {
			if (data.id) {
				$item.attr('data-id', data.id);
// TO FIX: data.v
			}
		});
	}
	
	// create a placeholder entry
	function _createNewItem() {
		var value = { s: 10, margin: 10 };
		var element = htmlToElement(template(value));
		var $target = $('#menusource');
		$target[0].appendChild(element);
		return $(element);
	}
	
	function _updateMenuItem($form) {
		var $item;
		var data = $form.serializeArray();
		var tab = _getitem(data, 'active');
		var idx = _getitem(data, 'idx');
		if (idx !== '-1') {
			$item = _getSelectedItem(tab, idx);
		} else {
//			var id = parseInt(_getitem(data, 'id'));
			$item = _createNewItem();
		}
		
		var flags = parseInt($item.data('s')) & ~2;
		var def = _getitem(data, 'default');
		var txt = _getitem(data, 'caption');
		if (flags & 8) {
			flags |= 2;		// override
			$item.find('span.me-caption').text(txt);
			$item.attr('data-mask', txt);	// update mask
		} else if (def !== '1') {
			flags |= 2;		// override
			$item.find('span.me-caption').text(txt);
		} else {
			$item.find('span.me-caption').text(_getitem(data, 'initial'));
		}

		$item.attr('data-s', flags);
		$item.attr('data-href', _getitem(data, 'link'));

		if (tab == 'source') {
			_createEditMenu($item, _getitem(data, 'id'),txt);
		}
		
		// close popup
		try {
			var $dialog = $('div.popup-dialog').first();
			$dialog.dialog('close');
		} catch(e) {
		}
	}
	
	function _attachContext() {
		$.contextMenu({
			selector: '.context-1', 
			build: function($trigger, e) {
				var $item = null, $target, items, flags;
				$target = $(e.target);
				items = {
					edit: {name: "Edit", icon: "edit"},
					'delete': {name: "Delete", icon: "delete"},
					sep1: "---------",
					newitem: {name: "New Menu Item", icon: "add"}
				};
				if (!$target.hasClass('me-caption')) {
					items.edit.disabled = true;
					items['delete'].disabled = true;
				} else {
					$item = $target.closest('.me-item');
					flags = parseInt($item.data('s'));
					if (!(flags & 8)) {
						items.edit.disabled = true;
						items['delete'].disabled = true;
					}
				}
				return {
					items: items,
					callback: function(key, options) {
						switch(key) {
							case 'edit':
								_editItem($item, 'source');
								return;
							case 'delete':
								return _option_delete($item);
							case 'newitem':
								return _option_new();
						}
					}
				};
			}
		});
	}

	this.disableCaption = function(data) {
		var $checkbox = $('#default');
		_disableCaption($checkbox.is(':checked'));
	};
	
	$(document).on('loaded.template', function(event) {
		var $tabs = $('#menuedit_tabs');
		if ($tabs.length) {
			$tabs.tabs({
				activate: function( event, ui ) {
					_setActiveTab(ui.newPanel);
				}
			});
			_loadMenus();
			_attachContext();
		}
	}).on('click', '.me-item .me-trash', function(event) {
		event.preventDefault();
		var $item = $(this).closest('.me-item');
		_removeItem($item);

	}).on('click', '.me-item .me-edit', function(event) {
		event.preventDefault();
		var $item = $(this).closest('.me-item');
		_editItem($item);

	}).on('click', 'button.menuedit-save', function(event) {
		event.preventDefault();
		_saveMenus(this.dataset.auth);

	}).on('click', 'button.menuedit-change', function(event) {
		event.preventDefault();
		var $form = $(this).closest('form');
		_updateMenuItem($form);
		
	}).on('click', 'input.menuedit-togglecap', function(event) {
		_disableCaption(this.checked);
	});
	
	$(function() {
		source   = $('#menu_item').html();
		template = Handlebars.compile(source);
	});
}

menuedit = new MenuEdit();