if (! Headwork) {
	var Headwork = {};
}
/**
 * Headwork
 */
Headwork = Object.extend(Headwork, {
	DEBUG: false,
	REGISTRY: {},
	WINDOWS: $A()
});

/**
 * Headwork.Modules
 *
 * @param {Object} modulename
 */
Headwork.Modules = {
	isLoaded: function(modulename) {
		return (Headwork.REGISTRY[modulename]);
	}
}

/**
 *
 * @param {String} namespace e.g 'NetworkService'
 */
Headwork.namespace = function(namespace, callback) {
	if (Object.isUndefined(Headwork[namespace])) {
		Headwork[namespace] = {};

		var script = new Element('script', {
			type: 'text/javascript',
			src: adminThemePath + '/js/headwork/' + String(namespace).toLowerCase() + '.js'
		});

		if (Prototype.Browser.IE) {
			script.observe('readystatechange', function() {
				if (script.readyState == 'loaded' || script.readyState == 'complete') {
					(callback || Prototype.emptyFunction)();
				}
			});
		} else {
			script.observe('load', function(e) {
				(callback || Prototype.emptyFunction)();
			});
		}

		document.getElementsByTagName('head')[0].appendChild(script);
		return;
	}
	(callback || Prototype.emptyFunction)();
}
/**
 * Headwork.Module
 *
 * @param {Object} modulename
 * @param {Object} object
 */
Headwork.Module = function(modulename, object) {
	if (! object) {
		if (! Headwork.REGISTRY[modulename]) {
			throw new Error("Can't get module '" + modulename + "' from registry.");
		}
		return Headwork.REGISTRY[modulename];
	}
	object.MODULENAME = modulename;

	object.isModule = function() { return true; }

	object.isLoaded = function() { return Headwork.Modules.isLoaded(this.MODULENAME); }

	object.Option = function(key, value) {
		if (! value) { return (! Object.isUndefined(object.options[key]) ? object.options[key] : null) }
		object.options[key] = value;
	}.bind(object);

	object.lang = {};

	object.Language = function(lang, translations) { this.lang[lang] = translations; }

	if (! object.init || typeof object.init != 'function') {
		object.init = function(params) { this.options = params; }.bind(object);
	}
	if (! object.close || typeof object.close != 'function') {
		object.close = Prototype.emptyFunction;
	}

	for (property in object) {
		if (typeof object[property] == 'function') {
			object[property] = object[property].bind(object);
		}
	}

	Headwork.REGISTRY[modulename] = object;
	return object;
}

/**
 * Erzeugt neue Administratorenfenster
 *
 * @param {Object} onload
 * @param {Object} onclose
 * @param {Object} width
 * @param {Object} height
 * @param {Object} minheight
 * @param {Object} center
 * @param {Object} left
 * @param {Object} top
 * @param {Object} className
 * @param {Object} title
 */
Headwork.Window = Class.create({
	initialize: function(options) {
		this.id = 0;
		this.zIndex = 500;
		this.options = Object.extend({
			isModal: true,
			center: false,
			className: '',
			title: '',
			closeButton: true,
			name: ''
		}, options || { });

		this.render();
	},

	render: function() {
		var minheight = this.options.minheight ? this.options.minheight == 'auto' ? 'auto' : (this.options.minheight + "px") : '';
		var height = this.options.height ? this.options.height == 'auto' ? 'auto' : (this.options.height + "px") : '';
		var width = this.options.width ? this.options.width == 'auto' ? 'auto' : (this.options.width + "px") : '';

		this.wrapper = new Element('div', {
			'class': 'admin admin-window' + (!this.options.className.empty() ? ' '+this.options.className : ''),
			'id': 'admin-window-' + (this.options.id || (this.id = Headwork.WINDOWS.length + 1)),
			'style': 'visibility:hidden'+
					 (height != '' ? ";height:" + height : '') +
					 (width != '' ? ";width:" + width : '') +
					 (minheight != '' ? ";min-height:" + minheight : '')
		});

		this.wrapper.update(
			'<div class="admin-windowHeader"><span>' + this.options.title + '</span>' +
			'	<div class="admin-wait" style="display: none;"></div>' +
			(this.options.closeButton ? '<div class="admin-close" title="'+ langCommon['CLOSE'] +'"></div>' : '') +
			'</div>' +
			'<div class="admin-windowContent" id="admin-windowContent-' + this.id + '"></div>'
		);

		Element.extend(document.body).insert(this.wrapper);

		this.content = this.wrapper.down('div#admin-windowContent-' + this.id);

		this.options.onload = (this.options.onload || Prototype.emptyFunction).bind(this);
		this.options.onload();

		if(this.wrapper.down('div.admin-close')) {
			this.wrapper.down('div.admin-close').observe('click', (function(event) {
				(this.onClose || Prototype.emptyFunction)(event);
				(this._onClose)(event);
			}).bind(this));
		}

		this.handle = new Draggable(this.wrapper, {
			handle: this.wrapper.down('div.admin-windowHeader', 0),
			starteffect: function(){},
			endeffect: function(){}
		});

		// IE7: Breite der Leiste setzen, sonst zu klein. -2px wegen Border
		this.wrapper.down('.admin-windowHeader').setStyle({minWidth: this.wrapper.getWidth()-2+'px'});
		// Und mit der Toolbar hat er auch Probleme
		if(this.wrapper.down('.admin-toolbar')) {
			this.wrapper.down('.admin-toolbar').setStyle({minWidth: this.wrapper.getWidth()-2+'px'});
		}

		if(this.options.center) {
			var viewportSize = document.viewport.getDimensions();
			var elementSize = this.wrapper.getDimensions();

			this.options.left 	= (viewportSize.width - elementSize.width) / 2;
			if(!this.options.top) {
				this.options.top 	= (viewportSize.height - elementSize.height) / 2;
			}

			this.wrapper.setStyle({left: this.options.left+'px', top: this.options.top+'px'});
		}

		// Modal dialog?
		// @TODO: adminModuleShatter erzeugen falls er noch nicht vorhanden ist
		if (this.options.isModal) {
			if (Headwork.WINDOWS.size() > 0) {
				var lastWindow = Headwork.WINDOWS.last();
				this.zIndex = lastWindow.zIndex + 10;
			}
			$('adminModuleShatter').setStyle({'zIndex':this.zIndex});
			this.wrapper.setStyle({'zIndex':(this.zIndex+1)});
			$('admin_messages').setStyle({'zIndex':this.zIndex+1});

			if (Headwork.WINDOWS.size() == 0) {
				new Effect.Appear($('adminModuleShatter'), {
					from: 0,
					to: 0.3,
					duration: 0.5
				});
			}
		}

		this.wrapper.setStyle({'visibility':'visible'});
		Headwork.WINDOWS.push(this);

		if(popupForm = this.wrapper.down('form')) {
			if(popupForm.findFirstElement() && !popupForm.findFirstElement().disabled) {
				popupForm.focusFirstElement();
			}
		}
	},

	close: function() {
		this._onClose();
	},

	startWait: function() {
		this.wrapper.down('div.admin-wait').show();
		this.wrapper.addClassName('admin-progress');
	},

	stopWait: function() {
		this.wrapper.down('div.admin-wait').hide();
		this.wrapper.removeClassName('admin-progress');
	},

	destroy: function() {
		this._onClose();
	},

	_onClose: function() {
		this.options.onclose = (this.options.onclose || Prototype.emptyFunction).bind(this);
		this.options.onclose();

		var elementSize = this.wrapper.getDimensions();

		Headwork.WINDOWS = Headwork.WINDOWS.without(this);
		this.wrapper.remove();
		this.handle.destroy();

		var lastWindow = Headwork.WINDOWS.last();
		var	nextZIndex = Headwork.WINDOWS.size() > 0 ? lastWindow.zIndex : 0;

		$('admin_messages').setStyle({'zIndex':nextZIndex == 0 ? '99' : nextZIndex + 1});

		if(this.options.isModal && Headwork.WINDOWS.size() == 0) {
			new Effect.Fade($('adminModuleShatter'), {from: 0.3, to: 0, duration: 0.3, afterFinish: function(s) {
				$('adminModuleShatter').setStyle({'zIndex':nextZIndex});
			} });
		} else {
			$('adminModuleShatter').setStyle({'zIndex':nextZIndex});
		}
	}
});

Headwork.Window.close = function(name) {
	if (name.strip() == '') { return false; }
	$A(Headwork.WINDOWS).each(function(obj) {
		if (obj.options.name == name) {
			obj.close();
		}
	});
}


/**
 *
 * @param {Object} $super
 * @param {Object} options
 */
Headwork.Dialog = Class.create(Headwork.Window, {
	initialize: function($super, options) {
		var self = this, options = Object.extend({
			title: '',
			message: '',
			text: '',
			className: 'admin-dialog confirm',
			actions: [],
			appendCancel: true,
			autoFocus: false,
			autoSubmit: true,
			onload: Prototype.emptyFunction
		}, options || { });

		// Abbrechen-Button hinzufuegen
		if (options.appendCancel) {
			options.actions.push(new Headwork.Dialog.Button({
				text: langCommon['CANCEL'],
				className: 'admin-linkCancel'
			}));
		}

		function _onLoad() {
			var dialog = this;

			// Inhalt einfuegen
			this.content.update(
				'<div class="innerSanctum"><h3>' + options.message + '</h3>'
				+ options.text
				+'</div><div class="admin-toolbar"><div class="admin-dialog-buttons"></div></div>'
			);

			$A(options.actions).each(function(button) {
				var buttonElement = button.getElement();
				if (Object.isFunction(button.options.callback)) {
					buttonElement.observe('click', function(e){
						if ((button.options.callback.bind(button))(e, dialog) !== false) {
							(dialog._onClose.bind(dialog))();
						}
					});
				} else {
					buttonElement.observe('click', dialog._onClose.bind(dialog));
				}
				dialog.content.down('div.admin-dialog-buttons').insert(buttonElement);
			});

			if (options.autoFocus) {
				//this.content.down('input[type="text"]', 0).focus();
				console.log('load');
				this.content.observe('dom:loaded', function() {
					console.log('dom:loaded');
				});
			}

			if (options.autoSubmit && this.content.down('input[type="text"]', 0)) {
				this.content.down('input[type="text"]', 0).listen(function(e) {
					$A(options.actions).each(function(button) {
						if (button.options.autoSubmit && Object.isFunction(button.options.callback)) {
							if ((button.options.callback.bind(button))(e, dialog) !== false) {
								(dialog._onClose.bind(dialog))();
							}
						}
					});
				});
			}

			// Callback ausfuehren
			return (options.onload.bind(this))();
		}

		$super({
			isModal: true,
			center: true,
			closeButton: true,
			width:400,
			title: options.title,
			className: options.className,
			onload: _onLoad.bind(this)
		});
	}
});

Headwork.Dialog.Button = Class.create({
	initialize: function(options) {
		this.options = Object.extend({
			'className': '',
			'text': '',
			'returnValue': false,
			'autoSubmit': false,
			'callback': null
		}, options || {});
	},
	getElement: function() {
		var button = new Element('a', {'class': 'admin-link ' + this.options.className });
		return button.update(this.options.text);
	}
});


Headwork.Groups = Class.create({
	tmpl: new Template('<tr id="admin_accessTr_#{groupId}" class="#{evenOdd}">'+
							'<td class="admin_accessTableGroupName">#{groupName}</td>'+
							'<td class="admin_accessTableCheckbox"><input type="checkbox" class="admin_contentRights checkbox" value="#{groupId}" onclick="Content.checkRightsRead(#{groupId})" id="contentRightsRead_#{groupId}" name="contentRightsRead[]" checked /></td>'+
							'<td class="admin_accessTableCheckbox"><input type="checkbox" class="checkbox" value="#{groupId}" onclick="Content.checkRightsWrite(#{groupId})" id="contentRightsWrite_#{groupId}" name="contentRightsWrite[]" checked /></td>'+
							'<td class="admin_accessTableCheckbox"><input type="checkbox" class="checkbox" value="#{groupId}" onclick="Content.checkNotification(#{groupId})" id="contentNotification_#{groupId}" name="contentNotification[]" /></td>'+
							'<td><img onclick="groupLookup.removeGroup(#{groupId})" src="' + adminThemePath + '/pics/icons/delete.png" class="delete" /></td>'+
						'</tr>'),
	groups: $A(),

	initialize: function(options) {
		this.options = Object.extend({
			dummy: true
		}, options || { });
	},

	lookupGroups: function(suppressWarning) {
		new Ajax.Request(rootPath + '/modules/user/ajax/getGroups.php', {
			method: 'get',
			parameters: {'text': $F('admin_accessAddGroup'), 'showAll': 1, 'perPage': 5000, 'notIn': $$('input.admin_contentRights').pluck('value').join(',')},
			onSuccess: function(transport) {
				if(message = Ajax.isXMLError(transport, true)) {
					$('admin_accessGroups').hide();
					if(!suppressWarning) {
						showMessage(this.lang[message], true);
					}
					return;
				}
				var list = transport.responseXML.getElementsByTagName('groups').item(0);

				if(list.childNodes.length > 0) {
					$('admin_accessGroups').select('select')[0].innerHTML = '';

					$A(list.childNodes).each(function(s) {
						$('admin_accessGroups').select('select')[0].insert('<option value="' + s.getAttribute('id') + '">' + s.getElementsByTagName('title')[0].firstChild.nodeValue + '</option>');
					});

					$('admin_accessGroups').show();
				} else {
					$('admin_accessGroups').hide();
				}
			}
		});
	},

	checkKey: function(event) {
		if(event.keyCode == Event.KEY_RETURN) {
			this.lookupGroups();
		}
	},

	addGroup: function() {
		selectedGroup = $('admin_accessGroups').select('select')[0];
		if (! this.groups.member(selectedGroup.value)) {
			$('admin-accessTableBody').insert(this.tmpl.evaluate({
				groupId: selectedGroup.value,
				groupName: selectedGroup.options[selectedGroup.selectedIndex].innerHTML,
				evenOdd: $('admin-accessTableBody').select('tr:last-child')[0].hasClassName('even') ? 'odd' : 'even'
			}));
			this.lookupGroups();
			this.groups.push(selectedGroup.value);
		}
	},

	removeGroup: function(id) {
		$('admin_accessTr_' + id).remove();
		this.groups = this.groups.without(id);
		this.lookupGroups(true);
	}
});

// Namespace: Headwork.Widget
Headwork.Widget = {};

/**
 * Widget zur Suche von Gruppen.
 *
 * @param {Object} options
 */
Headwork.Widget.GroupSearch = Class.create({
	initialize: function() {
		var self = this;
			self.groups = $A();

		self.options = Object.extend({
			'input': '.admin-groupSearch input[type="text"]',
			'select': '.admin-groupSearch select',
			'container': '.admin-groupSearchContainer',
			'search': '.admin-groupSearch a.admin-linkSearch',
			'add': '.admin-groupSearch a.admin-linkAddGroup',
			'elRemove': '.delete',
			'elName': '.groupname',
			'elId': 'input.groupid',
			'elRead': 'input.read',
			'elWrite': 'input.write',
			'onAdd': undefined,
			'onRemove': undefined,
			'showWebGroup': false,
			'addEvenOdd': true
		}, arguments[0] || { });

		// Elemente initialisieren
		$A(['input', 'container', 'select', 'search', 'add']).each(function(property) {
			if (! Object.isElement(self.options[property]) && ! (self.options[property] = $$(self.options[property])[0])) {
				console.error('Invalid parameter "' + property + '".');
				throw new Error('Invalid parameter "' + property + '".');
			}
			self[property] = self.options[property];
		});

		var onSearch = Prototype.emptyFunction;
		self.select.hide().up(0).hide();
		self.input.listen(onSearch = function(event) {
			var element = self.input;
				element.value = element.value.strip().replace(/([^\d\w-_\s])+/g, '');
				self.lookup(element.value || '');
			Event.stop(event);
		});

		self.search.stopObserving('click');
		self.search.observe('click', onSearch);

		self.add.stopObserving('click');
		self.add.observe('click', function(event) {
			var option = Element.extend(self.select[self.select.selectedIndex]);
			if (option && option.value && option.innerHTML != '') {
				self.addGroup({id: option.value, title: option.innerHTML, read: false, write: false, allContents: false});
				option.remove();
			}
			if (self.select.childElements().length == 0) {
				self.select.hide().up(0).hide();
			}
		});

		self.groups = self.container.select(self.options.elId).pluck('value')
						  .invoke('toInt').findAll(isFinite);
		self.groups = self.groups.uniq();
		self.container.childElements().slice(1).each(function(entry) {
			var node = null;
			if (node = entry.down(self.options.elRemove, 0)) {
				node.observe('click', self.removeGroup.bind(self));
			}
		});
	},

	lookup: function(groupName, options) {
		var self = this, groupName = String(groupName).strip();
			self.select.hide().up(0).hide();
		var options = Object.extend({
			'text': groupName,
			'showAll': 1,
			'showWarnings': true,
			'perPage': 500,
			'notIn': self.groups.join(','),
			'showWebGroup': (self.options.showWebGroup ? 1 : 0)
		}, (options || {}));

		new Ajax.Request(rootPath + '/modules/user/ajax/getGroups.php', {
			method: 'get',
			parameters: options,
			onSuccess: (function(transport) {
				if(message = Ajax.isXMLError(transport, true)) {
					if (options['showWarnings']) {
						showMessage((lang[message] || message), true);
						return;
					}
				}
				var groups = $A(), list = transport.responseXML.getElementsByTagName('groups').item(0);

				if(list && list.childNodes.length > 0) {
					$A(list.childNodes).each(function(group) {
						var titles = {};
						$A(group.getElementsByTagName('title')).each(function(title) {
							titles[title.getAttribute('lang')] = title.firstChild.nodeValue;
						});
						groups.push({
							'id': group.getAttribute('id'),
							'members': group.getAttribute('members'),
							'titles': titles
						})
					});
				}
				(self.fillSelect.bind(this))(groups);
			}).bind(self)
		});
	},

	fillSelect: function(groups) {
		var self = this;
		self.select.update();
		groups.each(function(group) {
			self.select.insert(new Element('option', {
				'value': group.id
			}).update(group.titles[currentLanguage]));
		});
		self.select.show().up(0).show();
	},

	addGroup: function(group) {
		var self = this, template = self.container.down(0).template(), node;

		template.down(self.options.elName, 0).update(group.title);
		template.down(self.options.elId, 0).value = group.id;

		templateRead = template.down(self.options.elRead, 0);
		templateWrite = template.down(self.options.elWrite, 0);

		if(templateRead) {
			templateRead.checked = group.read;
			templateWrite.checked = group.write;
			templateRead.value = group.id;
			templateWrite.value = group.id;

			if(group.allContents) {
				templateRead.disable();
				templateWrite.disable();
				template.down(self.options.elRemove, 0).hide();
			} else {
				templateRead.enable();
				if(group.id == 0) {// Gruppe Web
					templateWrite.hide();
				} else {
					templateWrite.enable()
								 .show()
								 .observe('click', function(e) { if(this.checked)  { templateRead.checked = true; } });

					templateRead.observe('click', function(e) { if(!this.checked)  { templateWrite.checked = false; } });

				}
				template.down(self.options.elRemove, 0).show();
			}
		}
		if (node = template.select(self.options.elRemove)[0]) {
			node.observe('click', self.removeGroup.bind(this));
		}

		self.container.insert(template.show());
		self.groups.push(parseInt(group.id));

		if (self.options['addEvenOdd']) {
			template.addClassName(template.previous(0).hasClassName('even') ? 'odd' : 'even');
		}

		((self.options['onAdd'] || Prototype.emptyFunction).bind(self))(group, template);
	},

	removeGroup: function(e) {
		var self = this; entry = (Object.isElement(e) ? e : e.element()), node = null;
		var ancestors = entry.ancestors(), index = ancestors.indexOf(self.container);
		if (index !== -1 && Object.isElement(ancestors[index - 1])) {
			if (ancestors[index - 1].hasClassName('not-deleteable')) {
				return;
			}
			self.groups = self.groups.without(ancestors[index - 1].down(self.options.elId, 0).value);
			ancestors[index - 1].remove();
		}

		((self.options['onRemove'] || Prototype.emptyFunction).bind(self))(entry);
	}
});

// Namespace: Headwork.Effect
Headwork.Effect = {};

Headwork.Effect.LoadingScreen = Class.create({
	initialize: function(element, options) {
		this.element = $(element);
		this.options = Object.extend({
			'className': '',
			'img': adminThemePath + '/account/pics/load_white.gif',
			'text': 'Loading ...'
		}, options || { });

		var inner = new Template(
			'<img src="#{IMG}" alt="#{TEXT}" />' +
			'<p>#{TEXT}</p>'
		);
		this.loader  = new Element('div', {'class':'admin admin-loading ' + this.options.className}).insert(inner.evaluate({
			'IMG':  this.options.img,
			'TEXT': this.options.text
		}));
		this.wrapper = new Element('div', {
			'style': 'visibility:hidden'
		});

		Element.wrap(this.element, this.wrapper);
		this.wrapper.insert({before: this.loader});
	},
	stop: function() {
		this.loader.remove();
		this.wrapper.setStyle({'visibility':'visible'});
	}
});

Headwork.Effect.Loading = Class.create({
	initialize: function(element, options) {
		this.element = $(element);
		this.wrapper = new Element('div', {'class':'admin-loadingscreen'});
		this.options = Object.extend({
			'className': '',
			'img': adminThemePath + '/account/pics/load_white.gif',
			'text': 'Loading ...'
		}, options || { });

		var inner = new Template(
			'<img src="#{IMG}" alt="#{TEXT}" />' +
			'<p>#{TEXT}</p>'
		);

		var position = this.wrapper.positionedOffset();

		this.wrapper.setStyle({
			'position': this.element.getStyle('position'),
			'left': position.left + 'px',
			'top': position.top + 'px'
		});
		this.wrapper.insert(new Element('div', {
			'class': 'inner'
		}).insert(inner.evaluate({
			'IMG':  this.options.img,
			'TEXT': this.options.text
		})));

		Element.wrap(this.element, this.wrapper);
		this.element.setStyle({'visibility':'hidden'});
	}
});
