<?php

define('IS_ADMIN', true);
require_once(dirname(__FILE__)."/../../include/init.php");
es_include("user.php");

$user = new User();
if (!($user->LoadBySession() && $user->Validate(array(INTEGRATOR, ADMINISTRATOR, MODERATOR))))
	exit;
?>
// TODO: drag & drop for menu tabs
// TODO: remove nodeProcessing, allow to do deleteMenu and deleteNode when other ajax requests are active
Ajax.droppableRequests = [];

Effect.ScrollLeft = Class.create(Effect.Base, {
	initialize: function(element)
	{
		this.element = $(element);
		if (!this.element) throw(Effect._elementDoesNotExistError);

		var options = Object.extend({
			shift: 100
		}, arguments[1] || { });
		this.start(options);
	},
	setup: function()
	{
		this.originalScrollLeft = this.element.scrollLeft;
	},
	update: function(position) {
		this.element.scrollLeft = this.originalScrollLeft + (this.options.shift * position).round();
	}
});

var DragObserver = Class.create();
DragObserver.prototype = {
	initialize: function(e)
	{
		this.e = e;
		this.x = 0;
		this.y = 0;
		this.eventStop = false;
	},
	onStart: function(name, drag, event)
	{
		this.eventStop = false;
		this.x = event.pointerX();
		this.y = event.pointerY();
	},
	onDrag: function(name, drag, event)
	{
	},
	onEnd: function(name, drag, event)
	{
		if (this.x == event.pointerX() && this.y == event.pointerY())
		{
			this.eventStop = false;
		}
		else
		{
			this.eventStop = true;
		}
	}
}

var SiteMap = Class.create();

SiteMap.prototype = {
	initialize: function(data, exp, lng, integrator)
	{
		this.sortable = new Object();
		this.nodeList = new Object();
		this.expireDate = exp;
		this.projectPath = '<?php echo PROJECT_PATH; ?>';
		this.path2Admin = '<?php echo ADMIN_PATH; ?>';
		this.path2Main = this.path2Admin+'template/';
		this.nodeProcessing = false;
		this.savingSEO = false;
		this.savingMenu = false;
		this.menuContainer = $('MenuContainer');
		this.openedMenu = null;
		this.integrator = integrator;
		this.dataLangCode = lng;

		this.menuShift = 0;
		this.menuFullWidth = 0;
		this.menuWindowWidth = 600;
		this.menuSliding = false;
		this.menuStep = 200;

		this.tabs = $('tabs-container');

		this.menuNav = $('MenuNav');

		(function(){
			// Load node list into HTML
			for (var i = 0; i < data.length; i++)
				this.addNode(data[i]);

			// Set menu wrap container width
			this.setMenuWidth();

			// If there is no menus and pages show add menu button
			if (this.openedMenu)
			{
				this.toggleMenu(this.openedMenu, false);
				var menuCount = this.menuContainer.childElements().length;
				if (this.integrator)
				{
					if (menuCount > 3)
					{
						this.menuNav.useMap = '#map-right';
						this.menuNav.className = 'tab-nav1-right';
					}
					else
					{
						this.menuNav.useMap = '#map-empty';
						this.menuNav.className = 'tab-nav1-empty';
					}
					this.setMenuPosition();
				}
				else
				{
					if (menuCount > 3)
					{
						this.menuNav.useMap = '#map-right';
						this.menuNav.className = 'tab-nav2-right';
					}
					else
					{
						this.menuNav.useMap = '';
						this.menuNav.className = '';
					}
				}
			}
			else
			{
				if (this.integrator)
				{
					this.menuNav.useMap = '#map-empty';
					this.menuNav.className = 'tab-nav1-empty';
					this.setMenuPosition();
				}
				else
				{
					this.menuNav.useMap = '';
					this.menuNav.className = '';
				}
			}

			// Scroll to current menu
			if (this.menuShift >= this.menuWindowWidth)
			{
				if (this.menuShift > this.menuFullWidth - this.menuWindowWidth)
					this.menuShift = this.menuFullWidth - this.menuWindowWidth;
				this.startScroll(this.menuShift);
			}

			// Hide loading picture & show page tree
			$('tree-loading').remove();
			$('tree-content').show();
			$('tabs').show();

			Position.includeScrollOffsets = true;
			this.sortable = $H(this.sortable);
			this.sortable.each((function(i)
			{
				if ($('child'+i[0]).childElements().length > 1)
					this.createSort(i[0]);
			}).bind(this));

			this.dragObserver = new DragObserver($('child0'));
			Draggables.addObserver(this.dragObserver);
			preventSelection($('child0'));
		}).bind(this).delay(10/1000);

		// Event observers
        Event.observe(document, 'click', this.parseClick.bindAsEventListener(this));
		Event.observe(document, 'keyup', (function(event){if (event.keyCode == 27){this.closePopups();}}).bindAsEventListener(this));

		// Observe mouse move to avoid lag of one additional click in Opera, IE & Firefox
		// TODO: Find better solution. This solution has one problem in Opera only: if we move element and then click it without mouse move we have this lag, because Opera doesn't generate drag start when click on the link
		Event.observe($('child0'), 'mousemove', (function(event){this.dragObserver.eventStop = false;}).bind(this));

		var objBody = $$('body')[0];

		// Overlay
		objBody.appendChild(Builder.node('div', {id: 'overlay'}));
		$('overlay').hide();
		this.overlay = $('overlay');

		// Preview
		objBody.appendChild(Builder.node('div', {id: 'preview', className: 'page-preview'}, [Builder.node('iframe'), Builder.node('a', {id: 'closePreview', className: 'close', href: '#'})]));
		$('preview').hide();
		this.preview = $('preview');

		Event.observe($('closePreview'), 'click', (function(event){this.closePopups();}).bind(this));

		// Menu
		objBody.appendChild(Builder.node('div', {id: 'menu', className: 'menu'}, [
			Builder.node('div', {id: 'menu-edit-loading'}, [
				Builder.node('img', {src: this.path2Main+'images/icons/loading16.gif', width: '16px', height: '16px'}),
				Builder.node('span').update(GetTranslation('loading-menu'))
			]),
			Builder.node('form', {id: 'menu-edit-form'})
		]));
		$('menu').hide();
		this.menu = $('menu');

		// SEO
		objBody.appendChild(Builder.node('div', {id: 'seo', className: 'seo'}, [
			Builder.node('div', {id: 'seo-edit-loading'}, [
				Builder.node('img', {src: this.path2Main+'images/icons/loading16.gif', width: '16px', height: '16px'}),
				Builder.node('span').update(GetTranslation('loading-seo'))
			]),
			Builder.node('form', {id: 'seo-edit-form'})
		]));
		$('seo').hide();
		this.seo = $('seo');

		// Image preloading
		this.preloadImages();
	},

	preloadImages: function()
	{
		var imageList = new Array();
		// Left arrow in the menu tabs
		imageList[imageList.length] = this.path2Main+'images/tab-left-arrows.png';
		imageList[imageList.length] = this.path2Main+'images/tab-left-arrows-hover.png';
		// Tab navigation
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-prev-inactive.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-next-inactive.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-arrows.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-arrows-prev-inactive.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-arrows-next-inactive.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-add-only.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-plus.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-p.png';
		imageList[imageList.length] = this.path2Main+'images/tab-nav-bg-n.png';
		// Hovers
		imageList[imageList.length] = this.path2Main+'images/icons/seo-close-hover.png';
		imageList[imageList.length] = this.path2Main+'images/icons/seo-hover.png';
		// Now preload it
		var imgObj = new Image();
		for (var i = 0; i < imageList.length; i++)
			imgObj.src = imageList[i];
	},

	parseClick: function(event)
	{
		var target = Event.element(event);
		switch (target.id.substr(0, 6))
		{
			case 'node-i':
				event.stop();
				if (!this.dragObserver.eventStop)
					this.toggleNode(target.id.substr(6));
				break;
			case 'node-a':
				event.stop();
				if (!this.dragObserver.eventStop)
					this.switchNode(target.id.substr(6));
				break;
			case 'node-p':
				event.stop();
				if (!this.dragObserver.eventStop)
					this.previewNode(target.id.substr(6));
				break;
			case 'node-m':
				event.stop();
				if (!this.dragObserver.eventStop)
				{
					if (!this.savingSEO)
					{
						if (this.seo.visible() && this.seo.childElements()[1].elements['PageID'] && this.seo.childElements()[1].elements['PageID'].value == target.id.substr(6))
							this.closeSEO();
						else
							this.editSEO(target.id.substr(6), event);
					}
				}
				break;
			case 'node-d':
				event.stop();
				if (!this.dragObserver.eventStop)
					this.deleteNode(target.id.substr(6));
				break;
			case 'node-t':
				event.stop();
				if (!this.dragObserver.eventStop)
					this.editNode(target.id.substr(6));
				break;
			case 'menu-l':
				event.stop();
				this.toggleMenu(target.id.substr(6), true);
				break;
			case 'menu-d':
				event.stop();
				this.deleteMenu(target.id.substr(6));
				break;
		}
		switch (target.id)
		{
			case 'SaveSEO':
				event.stop();
				this.saveSEO();
				break;
			case 'SaveMenu':
				event.stop();
				this.saveMenu();
				break;
			case 'CancelSEO':
			case 'CloseSEO':
				event.stop();
				if (!this.savingSEO) this.closeSEO();
				break;
			case 'CancelMenu':
			case 'CloseMenu':
				event.stop();
				if (!this.savingMenu) this.closeMenu();
				break;
			case 'MenuNavPrevLeft':
			case 'MenuNavPrevBoth':
			case 'prev-hover':
			case 'MenuNavNextRight':
			case 'MenuNavNextBoth':
			case 'next-hover':
			case 'MenuNavStart':
				event.stop();
				this.scrollTab(target.id);
				break;
			case 'MenuNavAdd':
			case 'MenuNavAddLeft':
			case 'MenuNavAddRight':
			case 'MenuNavAddBoth':
			case 'add-hover':
				event.stop();
				this.editMenu(0);
				break;
			case 'overlay':
				this.preview.hide();
				this.preview.down(0).src = 'about:blank';
				this.overlay.hide();
				break;
			case 'module-list-control':
				event.stop();
				this.toggleModuleList(target);
				break;
		}

		this.dragObserver.eventStop = false;
	},

	addNode: function(node)
	{
		var parent = $('child'+node.parentID);
		if (!parent)
		{
			alert("ERROR: parent '" + node.parentID + "' is not found for '" + node.id + "'");
			return;
		}

		if (node.parentID > 0)
		{
			var margin = node.level*20;

			var visibility = '';
			node.icon = node.link;
			var object = 'page';
			if (node.pageType == 1)
			{
				node.icon = 'page';
			}
			else if (node.pageType == 3)
			{
				visibility = ' style="visibility: hidden;"';
				node.icon = object = 'link';
			}

			if (node.active == 'Y')
			{
				var activeTitle = GetTranslation('page-deactivate');
				var activeClass = 'switch-on';
				var titleColor = node.colorA;
				var iconClass = 'pctgr-'+node.icon;
			}
			else
			{
				var activeTitle = GetTranslation('page-activate');
				var activeClass = 'switch-off';
				var titleColor = node.colorI;
				var iconClass = 'pctgr-'+node.icon+'-inactive';
			}

			var div = document.createElement('div');
			div.id = 'node_'+node.id;
			div.className = 'line-item';

			var nodeContent = '<div class="line">';
			nodeContent += '	<a href="#" id="node-a'+node.id+'" title="'+activeTitle+'" class="'+activeClass+'">&nbsp;</a>';
			nodeContent += '	<span class="title" style="color: '+titleColor+'; margin-left: '+margin+'px">';
			nodeContent += '		<img id="node-i'+node.id+'" src="'+this.path2Main+'images/spacer.png" width="16" height="16" title="'+node.iconTitle+'" alt="'+node.iconTitle+'" class="'+iconClass+'" />';
			nodeContent += '		<span id="node-t'+node.id+'" title="'+GetTranslation(object+'-edit').replace(/%Title%/g, node.title)+'">';
			nodeContent += '			'+node.shortTitle;
			nodeContent += '		</span>';
			nodeContent += '	</span>';
			nodeContent += '	<div class="tools" id="tools'+node.id+'">';
			nodeContent += '		<a href="#" id="node-p'+node.id+'" title="'+GetTranslation('page-preview')+'" class="preview"'+visibility+'>&nbsp;</a>';
			nodeContent += '		<a href="#" id="node-m'+node.id+'" title="'+GetTranslation('page-seo')+'" class="seo"'+visibility+'>&nbsp;</a>';
			nodeContent += '		<a href="#" id="node-d'+node.id+'" title="'+GetTranslation(object+'-delete').replace(/%Title%/g, node.title)+'" class="delete">&nbsp;</a>';
			nodeContent += '	</div>';
			nodeContent += '</div>';
			nodeContent += '<div id="child'+node.id+'" class="child"></div>';
			div.innerHTML = nodeContent;

			parent.appendChild(div);

			// define plus & minus icons
			if ($('node-i'+node.parentID))
			{
				if (!this.sortable[node.parentID])
					this.sortable[node.parentID] = node.parentID;
				if (this.nodeIsHidden(node.parentID))
				{
					$('child'+node.parentID).hide();
					$('node-i'+node.parentID).className = 'pctgr-plus';
					$('node-i'+node.parentID).title = GetTranslation('page-show');
				}
				else
				{
					$('node-i'+node.parentID).className = 'pctgr-minus';
					$('node-i'+node.parentID).title = GetTranslation('page-hide');
				}
			}
		}
		else
		{
			if (!this.sortable[node.parentID])
				this.sortable[node.id] = node.id;

			// Create node for menu content
			var div = document.createElement('div');
			div.id = 'child'+node.id;
			parent.appendChild(div);
			$('child'+node.id).hide();

			if (node.opened)
				this.openedMenu = node.id;

			if (!this.openedMenu)
				this.menuShift += this.menuStep;

			// Create top menu element
			var div = document.createElement('div');
			div.id = 'menu-t'+node.id;
			div.title = node.title;
			var nodeContent = '<label>';
			nodeContent += '	<span id="menu-l'+node.id+'">'+node.shortTitle+'</span>';
			nodeContent += '</label>';
			if (this.integrator)
				nodeContent += '<a href="#" id="menu-d'+node.id+'" class="delete">&nbsp;</a>';
			div.innerHTML = nodeContent;
			this.menuContainer.appendChild(div);
		}

		this.nodeList[node.id] = node;
	},

	setMenuPosition: function()
	{
		var menuCount = this.menuContainer.childElements().length;
		if (menuCount > 2)
		{
			$('tabs').setStyle({width: '73%'});
		}
		else
		{
			switch(menuCount)
			{
				case 2:
					$('tabs').setStyle({width: '400px'});
					break;
				case 1:
					$('tabs').setStyle({width: '200px'});
					break;
				case 0:
					$('tabs').setStyle({width: '5px'});
					break;
			}
		}
	},

	createSort: function(id)
	{
		Sortable.create('child'+id, {
			tag: 'div',
			overlap: 'vertical',
			format: /^node_([0-9]+)$/,
			scroll: window,
			onUpdate: this.saveSort.bind(this)
		});
	},

	saveSort: function(e)
	{
		var postString = 'Action=SaveSort&ParentID='+e.id.substr(5)+'&'+Sortable.serialize(e.id, {name: 'IDs'});

		// Destroy sortable while we are saving it
		Sortable.destroy(e.id);

		e.appendChild(Builder.node('div', {className: 'overlay-sort', id: 'overlay-'+e.id}, [Builder.node('img', {src: this.path2Main+'images/icons/loading32.gif', width: '32px', height: '32px'})]));
		$('overlay-'+e.id).hide();
		if (e.up(0).id == 'child0')
			$('overlay-'+e.id).setStyle({top: '0px', width: e.getWidth()+'px', height: e.getHeight()+'px'});
		else
			$('overlay-'+e.id).setStyle({top: '33px', width: e.getWidth()+'px', height: e.getHeight()+'px'});
		new Effect.Appear($('overlay-'+e.id), { from: 0.0, to: 0.9, duration: 0.25 });

		new Ajax.Request(this.path2Admin+'ajax.php?'+postString, {
			onCreate: function() { $('debug').update(''); },
			onFailure: function(tr) { $('debug').update(tr.responseText); },
			onSuccess: function(tr)
			{
				result = tr.transport.responseJS.Answer;
				if (!result)
					alert(GetTranslation('error-saving-sort'));

				// Return sortable back
				this.createSort(e.id.substr(5));
				new Effect.Fade($('overlay-'+e.id), { duration: 0.25, afterFinish: function() { $('overlay-'+e.id).remove(); } });
			}.bind(this)
		});
	},

	scrollTab: function(id)
	{
		if (this.savingMenu) return;

		this.closePopups();

		switch(id)
		{
			case 'MenuNavPrevLeft':
			case 'MenuNavPrevBoth':
			case 'prev-hover':
				if (this.tabs.scrollLeft > 0)
					this.startScroll(-this.menuStep);
				break;
			case 'MenuNavNextRight':
			case 'MenuNavNextBoth':
			case 'next-hover':
				if (this.tabs.scrollLeft <  this.menuFullWidth - this.menuWindowWidth)
					this.startScroll(this.menuStep);
				break;
			case 'MenuNavStart':
				if (this.tabs.scrollLeft > 0)
					this.startScroll(-this.menuFullWidth);
				break;
		}
	},

	stopScroll: function()
	{
		if (this.tabs.scrollLeft > 0)
			$('MenuNavStart').show();
		else
			$('MenuNavStart').hide();

		this.fixNavigation();
		this.menuSliding = false;
	},

	fixNavigation: function()
	{
		if (this.integrator)
		{
			if (this.menuContainer.childElements().length > 3)
			{
				if (this.tabs.scrollLeft == 0)
				{
					this.menuNav.useMap = '#map-right';
					this.menuNav.className = 'tab-nav1-right';
					$('prev-hover').hide();
				}
				else if (this.tabs.scrollLeft < this.menuFullWidth - this.menuWindowWidth)
				{
					this.menuNav.useMap = '#map-both';
					this.menuNav.className = 'tab-nav1-both';
				}
				else
				{
					this.menuNav.useMap = '#map-left';
					this.menuNav.className = 'tab-nav1-left';
					$('next-hover').hide();
				}
			}
			else
			{
				this.menuNav.useMap = '#map-empty';
				this.menuNav.className = 'tab-nav1-empty';
				$('next-hover').hide();
				$('prev-hover').hide();
			}
		}
		else
		{
			if (this.menuContainer.childElements().length > 3)
			{
				if (this.tabs.scrollLeft == 0)
				{
					this.menuNav.useMap = '#map-right';
					this.menuNav.className = 'tab-nav2-right';
					$('prev-hover').hide();
				}
				else if (this.tabs.scrollLeft < this.menuFullWidth - this.menuWindowWidth)
				{
					this.menuNav.useMap = '#map-both';
					this.menuNav.className = 'tab-nav2-both';
				}
				else
				{
					this.menuNav.useMap = '#map-left';
					this.menuNav.className = 'tab-nav2-left';
					$('next-hover').hide();
				}
			}
			else
			{
				this.menuNav.useMap = '';
				this.menuNav.className = '';
				$('next-hover').hide();
				$('prev-hover').hide();
			}
		}
	},

	startScroll: function(shift)
	{
		if (this.menuSliding) return;
		this.menuSliding = true;
		new Effect.ScrollLeft(this.tabs, {
			duration: 0.5,
			shift: shift,
			afterFinish: function() { this.stopScroll(); }.bind(this)
		});
	},

	toggleModuleList: function(element)
	{
		var element = $(element);

		var width = 32;
		if (element.up(0).getWidth() == width)
		{
			width = ($('module-list').getWidth() + 42);
			if (width > 370) $('main-item').hide();
			if (width > 570) width = 570;
			$('more-item').setStyle({width: (width + 10)+'px'});
		}

		new Effect.Morph(element.up(0),
		{
			duration: 0.25,
			style: { width: width+'px' },
			afterFinish: function()
			{
				if (element.className == 'close')
				{
					element.className = 'open';
					$('more-item').setStyle({width: '42px'});
					$('main-item').show();
				}
				else
				{
					element.className = 'close';
				}
			}.bind(this)
		});
	},

	editMenu: function(id)
	{
		if (this.savingMenu) return;

		if (this.menu.visible() && this.menu.childElements()[1].elements['PageID'] && this.menu.childElements()[1].elements['PageID'].value == id)
		{
			this.closeMenu();
			return;
		}

		this.closePopups();

		if (id > 0)
		{
			var k = 0;
			var menus = $('child0').childElements();
			for (var i = 0; i < menus.length; i++)
			{
				if (menus[i].id.substr(5) == id)
					break;
				k++;
			}
			if (Prototype.Browser.Opera)
				var left = this.tabs.viewportOffset().left + k*200 - this.tabs.scrollLeft;
			else
				var left = this.tabs.viewportOffset().left + k*200;
		}
		else
		{
			var shift = 550;
			switch($('tabs').getWidth())
			{
				case 400:
					shift = 350;
					break;
				case 200:
					shift = 150;
					break;
				case 5:
					shift = 0;
					break;
			}
			if (Prototype.Browser.Opera)
				var left = this.tabs.viewportOffset().left + shift;
			else
				var left = this.tabs.viewportOffset().left + this.tabs.scrollLeft + shift;
		}
		if (Prototype.Browser.Opera)
			this.menu.setStyle({top: (this.tabs.viewportOffset().top + 43)+'px'});
		else
			this.menu.setStyle({top: (this.tabs.viewportOffset().top + this.getScrollTop() + 43)+'px'});
		this.menu.setStyle({left: left+'px'});
		this.menu.show();

		var r = new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters:
			{
				'Action': 'LoadMenu',
				'PageID': id
			},
			onCreate: function() { $('debug').update(''); },
			onSuccess: function(tr)
			{
				result = tr.transport.responseJS.Answer;

				if (!result)
				{
					this.closeMenu();
					alert(GetTranslation('error-loading-menu'));
				}
				else
				{
					this.drawMenu(id, result.Title, result.Description, result.StaticPath, result.MenuImages);
				}
			}.bind(this),
			onFailure: function(tr)
			{
				this.closeMenu();
				$('debug').update(tr.responseText);
			}.bind(this)
		});

		// This is loading request, we can drop it in closePopups()
		Ajax.droppableRequests.push(r);
	},

	drawMenu: function(id, title, description, staticPath, menuImages)
	{
		var nodeContent = '<div class="edit-error" id="menu-edit-error" style="display: none;"></div>';
		nodeContent += '<div>';
		nodeContent += '	<label for="Title">'+GetTranslation('menu-title')+'</label><input name="Title" id="Title" type="text" value="'+title.replace(/\"/g,"&#34;")+'" />';
		nodeContent += '</div>';
		nodeContent += '<div>';
		nodeContent += '	<label for="Description">'+GetTranslation('menu-description')+'</label><textarea name="Description" id="Description">'+description.replace(/\"/g,"&#34;")+'</textarea>';
		nodeContent += '</div>';
		nodeContent += '<div>';
		nodeContent += '	<label for="StaticPath">'+GetTranslation('menu-static-path')+'</label><input name="StaticPath" id="StaticPath" type="text" value="'+staticPath.replace(/\"/g,"&#34;")+'" />';
		nodeContent += '</div>';
		if (menuImages)
		{
			var options = [{'title': GetTranslation('menu-image-no'), 'value': ''}, {'title': GetTranslation('menu-image-first-level'), 'value': 1}, {'title': GetTranslation('menu-image-all-levels'), 'value': 2}];
			for (var i = 0; i < menuImages.length; i++)
			{
				nodeContent += '<div>';
				nodeContent += '	<label for="'+menuImages[i].Name+'">'+menuImages[i].Title+'</label>';
				nodeContent += '	<select name="'+menuImages[i].Name+'" id="'+menuImages[i].Name+'">';
				for (var j = 0; j < 3; j++)
				{
					if (menuImages[i].Value == options[j].value)
						nodeContent += '<option value="'+options[j].value+'" selected="true">'+options[j].title+'</option>';
					else
						nodeContent += '<option value="'+options[j].value+'">'+options[j].title+'</option>';
				}
				nodeContent += '	</select>';
				nodeContent += '</div>';
			}
		}
		nodeContent += '<div id="menu-edit-buttons">';
		nodeContent += '	<input class="btn" type="submit" id="SaveMenu" value="'+GetTranslation('save')+'" /><input class="btn" type="button" id="CancelMenu" value="'+GetTranslation('cancel')+'" />';
		nodeContent += '</div>';
		nodeContent += '<div id="menu-edit-saving" style="display: none;">';
		nodeContent += '	<img src="'+this.path2Main+'images/icons/loading16.gif" width="16" height="16" alt="'+GetTranslation('saving-menu')+'" /><span>'+GetTranslation('saving-menu')+'</span>';
		nodeContent += '</div>';
		nodeContent += '<input type="hidden" name="PageID" id="PageID" value="'+id+'" />';
		nodeContent += '<input type="hidden" name="Active" id="Active" value="Y" />';
		nodeContent += '<input type="hidden" name="LanguageCode" id="LanguageCode" value="'+this.dataLangCode+'" />';
		nodeContent += '<input type="hidden" name="Action" id="Action" value="SaveMenu" />';

		this.menu.childElements()[1].update(nodeContent);
		this.menu.childElements()[0].hide();
		new Effect.Appear(this.menu.childElements()[1], {duration: 0.25});
	},

	saveMenu: function()
	{
		if (this.savingMenu) return;

		this.savingMenu = true;

		$('menu-edit-buttons').hide();
		$('menu-edit-saving').show();

		new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters: this.menu.childElements()[1].serialize(true),
			onCreate: function() { $('debug').update(''); },
			onSuccess: function(tr)
			{
				result = tr.transport.responseJS;

				this.savingMenu = false;

				if (result.Answer)
				{
					var id = result.Answer.PageID;
					var title = result.Answer.Title;
					var shortTitle = result.Answer.ShortTitle;

					this.nodeList[id] = {'id': id, 'parentID': 0, 'title': title, 'shortTitle': shortTitle, 'pageType': 0, 'active': 'Y', 'link': '', 'level': 0, 'opened': 0, 'colorA': '', 'colorI': '', 'iconTitle': ''};

					if ($('PageID').value > 0)
					{
						$('menu-l'+id).update(shortTitle);
						this.closeMenu();
					}
					else
					{
						// Create node element for menu
						var div = document.createElement('div');
						div.id = 'child'+id;
						$('child0').appendChild(div);
						$('child'+id).hide();

						var div = document.createElement('div');
						div.id = 'menu-t'+id;
						div.title = title;
						var nodeContent = '<label>';
						nodeContent += '	<span id="menu-l'+id+'">'+shortTitle+'</span>';
						nodeContent += '</label>';
						if (this.integrator)
							nodeContent += '<a href="#" id="menu-d'+id+'" class="delete">&nbsp;</a>';
						div.innerHTML = nodeContent;
						this.menuContainer.appendChild(div);

						// Scroll to newly created menu
						this.toggleMenu(id, false);
						this.setMenuWidth();
						this.setMenuPosition();
						this.startScroll(this.menuFullWidth - this.menuWindowWidth - this.tabs.scrollLeft);
					}
				}
				else
				{
					$('menu-edit-error').update(result.Error);
					new Effect.Appear($('menu-edit-error'), {duration: 0.25});
					$('menu-edit-saving').hide();
					$('menu-edit-buttons').show();
				}
			}.bind(this),
			onFailure: function(tr)
			{
				this.savingMenu = false;
				this.closeMenu();
				$('debug').update(tr.responseText);
			}.bind(this)
		});
	},

	closeMenu: function()
	{
		// Hide popup
		this.menu.hide();
		// Empty & hide form
		this.menu.childElements()[1].update('');
		this.menu.childElements()[1].hide();
		// Show loading message
		this.menu.childElements()[0].show();
	},

	toggleMenu: function(id, editMenu)
	{
		if (this.savingMenu) return;

		// Make menu selected by default on edit page
		$('link-page').href = 'page_edit.php?Parent='+id;
		$('link-hyperlink').href = 'link_edit.php?Parent='+id;
		var modules = $('module-list').childElements();
		for (var i = 0; i < modules.length; i++)
			modules[i].href = 'module_edit.php?Link='+modules[i].id.substr(5)+'&'+'Parent='+id;

		var menus = $('child0').childElements();
		for (var i = 0; i < menus.length; i++)
		{
			if (menus[i].visible())
			{
				if (editMenu && id == menus[i].id.substr(5) && this.integrator)
				{
					this.editMenu(id);
					return;
				}
				else
				{
					menus[i].hide();
				}
			}
		}

		$('child'+id).show();

		var d = new Date(this.expireDate);
		document.cookie = "expandedMenu=" + id + "; expires=" + d.toUTCString() + "; path=" + this.projectPath + ";";

		var menus = this.menuContainer.childElements();
		var prevMenuActive = false;
		var className = '';
		for (var i = 0; i < menus.length; i++)
		{
			className = '';
			if (prevMenuActive && i == menus.length - 1)
				className = 'past-active-last';
			else if (prevMenuActive)
				className = 'past-active';
			else if (menus[i].id == 'menu-t'+id && i == menus.length - 1)
				className = 'active-last';
			else if (menus[i].id == 'menu-t'+id)
				className = 'active';
			else if (i == 0)
				className = 'first';
			else if (i == menus.length - 1)
				className = 'last';

			menus[i].className = className;

			if (menus[i].id == 'menu-t'+id)
				prevMenuActive = true;
			else if (prevMenuActive)
				prevMenuActive = false;
		}
		this.closePopups();
	},

	deleteMenu: function(id)
	{
		if (this.savingMenu || this.savingSEO || this.nodeProcessing || $('menu-d'+id).className == 'delete-loading')
			return;

		// Form confirmation message
		var confirmMsg = GetTranslation('delete-menu-confirm');
		confirmMsg = confirmMsg.replace(/%Title%/g, this.nodeList[id].title);
		if (!confirm(confirmMsg))
			return;

		$('menu-d'+id).className = 'delete-loading';

		new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters:
			{
				'Action': 'Remove',
				'PageID': id
			},
			onCreate: function() { $('debug').update(''); },
			onSuccess: function(tr)
			{
				new Effect.ScrollLeft(this.tabs, {
					duration: 0.25,
					shift: -this.menuStep,
					afterFinish: function() { this.stopScroll(); }.bind(this)
				});

				new Effect.Morph($('menu-t'+id),
				{
					duration: 0.25,
					style: { width: '0px' },
					afterFinish: function()
					{
						var previous = $('menu-t'+id).previous(0);
						var next = $('menu-t'+id).next(0);
						var active = $('menu-t'+id).hasClassName('active') || $('menu-t'+id).hasClassName('active-last');

						$('menu-t'+id).remove();
						$('child'+id).remove();

						if (active)
						{
							if (previous)
								this.toggleMenu(previous.id.substr(6), false);
							else if (next)
								this.toggleMenu(next.id.substr(6), false);
						}
						else
						{
							var current = this.getOpenedMenuID();
							if (current)
								this.toggleMenu(current, false);
						}

						this.setMenuWidth();
						this.fixNavigation();
						this.setMenuPosition();
					}.bind(this)
				});
			}.bind(this),
			onFailure: function(tr)
			{
				$('menu-d'+id).className = 'delete';
				$('debug').update(tr.responseText);
			}
		});
	},

	getOpenedMenuID: function()
	{
		var menus = this.menuContainer.childElements();
		var id = null;
		for (var i = 0; i < menus.length; i++)
		{
			if (menus[i].hasClassName('active') || menus[i].hasClassName('active-last'))
			{
				id = menus[i].id.substr(6);
				break;
			}
		}
		return id;
	},

	setMenuWidth: function()
	{
		this.menuFullWidth = this.menuContainer.childElements().length*this.menuStep;
		this.menuContainer.setStyle({width: parseInt(this.menuFullWidth+20)+'px'});
		// Fix scrolling (remove 20px)
		if (this.tabs.scrollLeft > this.menuFullWidth - this.menuWindowWidth)
			this.tabs.scrollLeft = this.menuFullWidth - this.menuWindowWidth;
	},

	toggleNode: function(id)
	{
		if ($('child'+id).childElements().length > 0)
		{
			if ($('child'+id).visible())
			{
				this.hideNode(id);
				$('node-i'+id).className = 'pctgr-plus';
				$('node-i'+id).title = GetTranslation('page-show');
				$('child'+id).hide();
			}
			else
			{
				this.showNode(id);
				$('node-i'+id).className = 'pctgr-minus';
				$('node-i'+id).title = GetTranslation('page-hide');
				$('child'+id).show();
			}
		}
	},

	nodeIsHidden: function(id)
	{
		var re = /expandedNodes=\['\d+'(,'\d+')*\]/;
		if (arr = re.exec(unescape(document.cookie)))
		{
			eval("var " + arr[0]);
			for (var i = 0; i < expandedNodes.length; i++)
			{
				if (id == unescape(expandedNodes[i]))
					return false;
			}
		}
		return true;
	},

	showNode: function(id)
	{
		var re = /expandedNodes=\['\d+'(,'\d+')*\]/;
		if (arr = re.exec(unescape(document.cookie)))
		{
			eval("var " + arr[0]);
		}
		else
			var expandedNodes = [];

		var cookieValue = "expandedNodes=[";
		var alreadyShown = false;
		for (i = 0; i < expandedNodes.length; i++)
		{
			cookieValue += "'"+expandedNodes[i]+"',";
			if (id == unescape(expandedNodes[i]))
				alreadyShown = true;
		}

		if (alreadyShown == false)
			cookieValue += "'"+escape(id)+"',";

		cookieValue = cookieValue.substr(0, cookieValue.length - 1) + "]";
		var d = new Date(this.expireDate);
		document.cookie = cookieValue + "; expires=" + d.toUTCString() + "; path=" + this.projectPath + ";";
	},

	hideNode: function(id)
	{
		var re = /expandedNodes=\['\d+'(,'\d+')*\]/;
		if (arr = re.exec(unescape(document.cookie)))
		{
			eval("var " + arr[0]);
			var cookieValue = "expandedNodes=[";
			for (i = 0; i < expandedNodes.length; i++)
			{
				if (id != unescape(expandedNodes[i]))
				{
					cookieValue += "'"+expandedNodes[i]+"',";
				}
			}
			var d = new Date(this.expireDate);
			if (cookieValue == "expandedNodes=[")
			{
				document.cookie = "expandedNodes=; expires=" + d.toUTCString() + "; path=" + this.projectPath + ";";
			}
			else
			{
				cookieValue = cookieValue.substr(0, cookieValue.length - 1) + "]";
				document.cookie = cookieValue + "; expires=" + d.toUTCString() + "; path=" + this.projectPath + ";";
			}
		}
	},

	switchNode: function(id)
	{
		if (this.nodeProcessing || $('node-a'+id).className == 'switch-loading')
			return;

		var active = 'N';
		if ($('node-a'+id).className == 'switch-off')
			active = 'Y';

		$('node-a'+id).className = 'switch-loading';

		this.nodeProcessing = true;

		new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters:
			{
				'Action': 'SwitchActive',
				'PageID': id,
				'Active': active
			},
			onCreate: function() { $('debug').update(''); },
			onSuccess: function(tr)
			{
				if (active == 'Y')
				{
					$('node-a'+id).title = GetTranslation('page-deactivate');
					$('node-a'+id).className = 'switch-on';
					$('node-t'+id).setStyle({color: this.nodeList[id].colorA});
					if ($('node-i'+id).className != 'pctgr-minus' && $('node-i'+id).className != 'pctgr-plus')
						$('node-i'+id).className = 'pctgr-'+this.nodeList[id].icon;
				}
				else
				{
					$('node-a'+id).title = GetTranslation('page-activate');
					$('node-a'+id).className = 'switch-off';
					$('node-t'+id).setStyle({color: this.nodeList[id].colorI});
					if ($('node-i'+id).className != 'pctgr-minus' && $('node-i'+id).className != 'pctgr-plus')
						$('node-i'+id).className = 'pctgr-'+this.nodeList[id].icon+'-inactive';
				}
			}.bind(this),
			onFailure: function(tr)
			{
				if (active == 'Y')
					$('node-a'+id).className = 'switch-off';
				else
					$('node-a'+id).className = 'switch-on';
				$('debug').update(tr.responseText);
			},
			onComplete: function(tr)
			{
				this.nodeProcessing = false;
			}.bind(this)
		});
	},

	previewNode: function(id)
	{
		if (this.nodeList[id].pageType == 3)
			return;

		var arrayPageSize = this.getPageSize();
		this.overlay.setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });

		new Effect.Appear(this.overlay, { duration: 0.25, from: 0.0, to: 0.75, afterFinish: (function()
		{
			this.preview.down(0).src = this.path2Admin+'page_preview.php?PageID='+id;
			this.preview.setStyle({top: parseInt(this.getScrollTop()+30)+'px'});
			this.preview.show();
		}).bind(this)});
	},

	editSEO: function(id, event)
	{
		if (this.nodeList[id].pageType == 3 || this.savingSEO)
			return;

		this.closePopups();

		// Show loading message
		var pos = $('tools'+id).viewportOffset();
		if (Prototype.Browser.Opera)
			this.seo.setStyle({top: (pos.top + 15)+'px'});
		else
			this.seo.setStyle({top: (pos.top + this.getScrollTop() + 15)+'px'});
		this.seo.show();
		this.seo.setStyle({left: (Event.pointerX(event) - this.seo.offsetWidth - 30)+'px'});
	
		var r = new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters:
			{
				'Action': 'LoadSEO',
				'PageID': id
			},
			onCreate: function() { $('debug').update(''); },
			onSuccess: function(tr)
			{
			 	result = tr.transport.responseJS.Answer;

				if (!result)
				{
					this.closeSEO();
					alert(GetTranslation('error-loading-seo'));
				}
				else
				{
					var nodeContent = '<div>';
					nodeContent += '	<label for="MetaTitle">'+GetTranslation('meta-title')+'</label><br /><input name="MetaTitle" id="MetaTitle" type="text" value="'+result.MetaTitle.replace(/\"/g,"&#34;")+'" />';
					nodeContent += '</div>';
					nodeContent += '<div>';
					nodeContent += '	<label for="MetaKeywords">'+GetTranslation('meta-keywords')+'</label><br /><textarea name="MetaKeywords" id="MetaKeywords">'+result.MetaKeywords.replace(/\"/g,"&#34;")+'</textarea>';
					nodeContent += '</div>';
					nodeContent += '<div>';
					nodeContent += '	<label for="MetaDescription">'+GetTranslation('meta-description')+'</label><br /><textarea name="MetaDescription" id="MetaDescription">'+result.MetaDescription.replace(/\"/g,"&#34;")+'</textarea>';
					nodeContent += '</div>';
					nodeContent += '<div id="seo-edit-buttons">';
					nodeContent += '	<input class="btn" type="button" id="SaveSEO" value="'+GetTranslation('save')+'" /><input class="btn" type="button" id="CancelSEO" value="'+GetTranslation('cancel')+'" />';
					nodeContent += '</div>';
					nodeContent += '<div id="seo-edit-saving" style="display: none;">';
					nodeContent += '	<img src="'+this.path2Main+'images/icons/loading16.gif" width="16" height="16" alt="'+GetTranslation('saving-seo')+'" /><span>'+GetTranslation('saving-seo')+'</span>';
					nodeContent += '</div>';
					nodeContent += '<a href="#" class="close" id="CloseSEO">&nbsp;</a>';
					nodeContent += '<input type="hidden" name="PageID" id="PageID" value="'+id+'" />';
					nodeContent += '<input type="hidden" name="Action" id="Action" value="SaveSEO" />';

					this.seo.childElements()[1].update(nodeContent);
					this.seo.childElements()[0].hide();
					new Effect.Appear(this.seo.childElements()[1], {duration: 0.25});
				}
			}.bind(this),
			onFailure: function(tr)
			{
				this.closeSEO();
				$('debug').update(tr.responseText);
			}.bind(this)
		});

		// This is loading request, we can drop it in closePopups()
		Ajax.droppableRequests.push(r);
	},

	saveSEO: function()
	{
		if (this.savingSEO) return;

		this.savingSEO = true;

		$('seo-edit-buttons').hide();
		$('seo-edit-saving').show();

		new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters: this.seo.childElements()[1].serialize(true),
			onCreate: function() { $('debug').update(''); },
			onFailure: function(tr) { $('debug').update(tr.responseText); },
			onSuccess: function(tr)
			{
				var node = $('node-t'+$('PageID').value).up(1);
				new Effect.Highlight(node, {startcolor: '#fff9d9', endcolor: '#ffffff', keepBackgroundImage: true, restorecolor: true});
			}.bind(this),
			onComplete: function(tr)
			{
				this.savingSEO = false;
				this.closeSEO();
			}.bind(this)
		});
	},

	closeSEO: function()
	{
		// Hide popup
		this.seo.hide();
		// Empty & hide form
		this.seo.childElements()[1].update('');
		this.seo.childElements()[1].hide();
		// Show loading message
		this.seo.childElements()[0].show();
	},

	deleteNode: function(id)
	{
		if (this.nodeProcessing) return;

		// Form confirmation message
		if (this.nodeList[id].pageType == 3)
			var confirmMsg = GetTranslation('delete-link-confirm');
		else
			var confirmMsg = GetTranslation('delete-page-confirm');
		confirmMsg = confirmMsg.replace(/%Title%/g, this.nodeList[id].title);
		if ($('child'+id).childElements().length > 0)
		{
			confirmMsg += "\n"+GetTranslation("has-subpages");
		}
		if (!confirm(confirmMsg))
			return;

		this.nodeProcessing = true;
		$('node-d'+id).className = 'delete-loading';

		new Ajax.Request(this.path2Admin+'ajax.php', {
			parameters:
			{
				'Action': 'Remove',
				'PageID': id
			},
			onCreate: function() { $('debug').update(''); },
			onSuccess: function(tr)
			{
				new Effect.Fade($('node_'+id),
				{
					duration: 0.75,
					afterFinish: function()
					{
						if ($('node_'+id).up(1).id != 'child0' && $('node_'+id).up(0).childElements().length == 1)
						{
							var parentID = this.nodeList[id].parentID;
							var iconClass = 'pctgr-'+this.nodeList[parentID].icon+'-inactive';
							if (this.nodeList[parentID].active == 'Y')
								iconClass = 'pctgr-'+this.nodeList[parentID].icon;

							$('node-i'+parentID).className = iconClass;
							$('node-i'+parentID).title = this.nodeList[parentID].iconTitle;
							this.hideNode(parentID);
						}

						$('node_'+id).remove();
					}.bind(this)
				});
			}.bind(this),
			onFailure: function(tr)
			{
				$('node-d'+id).className = 'delete';
				$('debug').update(tr.responseText);
			},
			onComplete: function(tr)
			{
				this.nodeProcessing = false;
			}.bind(this)
		});
	},

	editNode: function(id)
	{
		switch (this.nodeList[id].pageType)
		{
			case 1:
				document.location.href = 'page_edit.php?PageID='+id;
				break;
			case 2:
				document.location.href = 'module_edit.php?PageID='+id;
				break;
			case 3:
				document.location.href = 'link_edit.php?PageID='+id;
				break;
		}
	},

	closePopups: function()
	{
		this.preview.hide();
		this.preview.down(0).src = "about:blank";
		new Effect.Fade(this.overlay, { duration: 0.35});

		if (this.seo.visible() && !this.savingSEO)
			this.closeSEO();

		if (this.menu.visible() && !this.savingMenu)
			this.closeMenu();

		// Drop active ajax requests
		for (var i = 0; i < Ajax.droppableRequests.length; i++)
		{
			Ajax.droppableRequests[i].options['onSuccess'] = null;
			Ajax.droppableRequests[i].options['onFailure'] = null;
			Ajax.droppableRequests[i].options['onComplete'] = null;
		}
		Ajax.droppableRequests = [];
	},

	getScrollTop: function()
	{
		var scrollTop = 0;
		if (window.pageYOffset)
			scrollTop = window.pageYOffset;
		else if (document.documentElement.scrollTop)
			scrollTop = document.documentElement.scrollTop;
		else if (document.body.scrollTop)
			scrollTop = document.body.scrollTop;
		return scrollTop;
	},

	getPageSize: function()
	{
		var xScroll, yScroll;

		if (window.innerHeight && window.scrollMaxY)
		{
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		}
		else if (document.body.scrollHeight > document.body.offsetHeight)
		{
			// all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		}
		else if (document.documentElement && document.documentElement.scrollHeight > document.documentElement.offsetHeight)
		{
			// Explorer 6 strict mode
			xScroll = document.documentElement.scrollWidth;
			yScroll = document.documentElement.scrollHeight;
		}
		else
		{
			// Explorer Mac...would also work in Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}

		var windowWidth, windowHeight;
		if (self.innerHeight)
		{
			// all except Explorer
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight)
		{
			// Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		}
		else if (document.body)
		{
			// other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}

		// for small pages with total height less then height of the viewport
		if	(yScroll < windowHeight)
		{
			pageHeight = windowHeight;
		}
		else
		{
			pageHeight = yScroll;
		}

		// for small pages with total width less then width of the viewport
		if (xScroll < windowWidth)
		{
			pageWidth = windowWidth;
		}
		else
		{
			pageWidth = xScroll;
		}

		return [pageWidth, pageHeight, windowWidth, windowHeight];
	}
}
