var Overlayer = {
	
	overlay: null,
	loader:  null,
	
	checkJsonResult: function(json, result, func) {
		if(json==null) {
			this.showInfoBox('infoBoxError', 'Fehlermeldung', 'Bei der Daten&uuml;bertragung ist ein Fehler aufgetreten!');
		} else if(json.error) {
			this.showInfoBox('infoBoxError', 'Fehlermeldung', json.error);
		} else if(json[result]) {
			func();
			if(json.info) this.showInfoBox('', 'Hinweis', json.info);
		} else {
			this.showInfoBox('infoBoxError', 'Fehlermeldung', 'Ein unbekannter Fehler ist aufgetreten. Falls dieser Fehler nochmals auftritt, melden Sie diesen dem Administrator.');
		}
	},
	
	showInfoBox: function(className, title, text) {
		if(this.infobox) this.infobox.destroy();
		this.infobox = new Element('div', {'class':'infoBox '+className});
		this.infobox.setStyle('opacity', '0');
		var titleElm = new Element('h2');
		titleElm.set('html', title);
		var textElm = new Element('div', {'class':'text'});
		textElm.set('html', text);
		var closeTextElm = new Element('div', {'class':'closeText'});
		closeTextElm.set('html', '(Um dieses Fenster vorzeitig zu schlie&szlig;en, klicken Sie einfach drauf.)');
		this.infobox.adopt([titleElm, textElm, closeTextElm]);
		$(document.body).grab(this.infobox);
		var scroll = $(document.body).getScroll();
		this.infobox.setStyles({left:scroll.x, top:scroll.y});
		this.infobox.fade('in');
		this.destroyFunc = this.destroyInfoBox.bind(this);
		this.infobox.addEvent('click', this.destroyFunc);
		this.timeout = window.setTimeout(this.destroyFunc, 8000);
	},
	
	destroyInfoBox: function() {
		this.infobox.fade('out');
		window.clearTimeout(this.timeout);
		this.timeout = null;
	},
	
	showConfirmBox: function(titleText, text, func) {
		this.box = new Element('div', {'class':'confirmBox'});
		var boxTitle = new Element('h2');
		boxTitle.set('html', titleText);
		var boxText = new Element('div', {'class':'confirmBoxText'});
		boxText.set('html', text);
		
		var boxLeft = new Element('div', {'class':'buttonBoxLeft'});
		var buttonYes = new Element('div', {'class':'button'});
		buttonYes.set('html', 'ja');
		boxLeft.grab(buttonYes);
		boxLeft.addEvent('click', function() {
			this.closeConfirmBox();
			func();
		}.bind(this));
		
		var boxRight = new Element('div', {'class':'buttonBoxRight'});
		var buttonNo = new Element('div', {'class':'button'});
		buttonNo.set('html', 'nein');
		boxRight.grab(buttonNo);
		boxRight.addEvent('click', this.closeConfirmBox.bind(this));
		
		var clear = new Element('div', {'class':'clear'});
		this.box.adopt([boxTitle, boxText, boxLeft, boxRight, clear]);
		if(!this.overlay) this.generateOverlay('overlayHidden');
		$(document.body).grab(this.box);
		this.box.setStyle('display', 'block');
		this.setElementCenter(this.box);
	},
	
	closeConfirmBox: function() {
		this.box.destroy();
		this.closeOverlay();
	},
	
	generateOverlay: function(className) {
		var clsName = className || 'overlay';
		this.overlay = new Element('div', {'class':clsName});
		this.setOverlaySize();
		$(document.body).grab(this.overlay);
	},
	
	closeOverlay: function() {
		this.overlay.destroy();
		this.overlay = null;
		window.removeEvent('resize', this.resizeFunc);
	},
	
	setOverlaySize: function() {
		this.overlay.setStyle('display', 'none');
		var size = $(document.body).getScrollSize();
		this.overlay.setStyles({'width':size.x+'px', 'height':size.y+'px', 'display':'block'});
	},
	
	setElementCenter: function(element) {
		var sizeBrowser = getBrowserInnerSize();
		var sizeElement = element.getSize();
		var scrPos = getScrollPosition();
		var absY = Math.round((sizeBrowser.height/2 - sizeElement.y/2) + scrPos.left);
		var absX = Math.round((sizeBrowser.width/2 - sizeElement.x/2) + scrPos.top);
		if(absY<0) absY = 0;
		if(absX<0) absX = 0;
		element.setStyles({top:absY+'px', left:absX+'px'});
	},
	
	showAjaxLoader: function() {
		if(this.loader==null) this.loader = new Element('div', {'class':'ajaxLoader'});
		this.setElementCenter(this.loader);
		$(document.body).grab(this.loader);
	},
	
	closeAjaxLoader: function() {
		if(this.loader) this.loader.dispose();
	},
	
	showWarning: function(warntext, warnings) {
		this.warningBox = new Element('div', {'class':'warningBox'});
		var warningImage = new Element('img', {'class':'warningImage', 'src':'pics/overlay/warning.gif'});
		var warningText = new Element('span', {'class':'warningText'});
		warningText.set('html', warntext);
		var warningList = new Element('ul', {'class':'warningList'});
		for(var i=0; i<warnings.length; i++) {
			var li = new Element('li');
			li.set('html', warnings[i]);
			warningList.grab(li);
		}
		var closeDiv = new Element('div', {'class':'warningCloseDiv'});
		closeDiv.set('html', 'schlie&szlig;en');
		this.warningBox.adopt([warningImage, warningText, warningList, closeDiv]);
		//this.showOverlay();
		this.generateOverlay();
		this.closeFunction = this.closeWarning.bind(this);
		this.warningBox.addEvent('click', this.closeFunction);
		this.overlay.addEvent('click', this.closeFunction);
		$(document.body).grab(this.warningBox);
		this.setElementCenter(this.warningBox);
	},
	
	closeWarning: function() {
		this.warningBox.removeEvent('click', this.closeFunction);
		this.overlay.removeEvent('click', this.closeFunction);
		this.warningBox.dispose();
		this.overlay.setStyle('display', 'none');
		window.removeEvent('resize', this.resizeFunc);
	}
}

var JsonRequest = new Class({
	
	Extends: Request,
	
	options: {
		secure: true,
		showLoader: true
	},
	
	initialize: function(options){
		this.parent(options);
		this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'});
		this.addEvent('request', this.startRequest.bind(this));
		this.addEvent('exception', this.closeAjax.bind(this));
		this.addEvent('cancel', this.closeAjax.bind(this));
	},
	
	success: function(text){
		if(this.options.showLoader) Overlayer.closeAjaxLoader();
		this.response.json = JSON.decode(text, this.options.secure);
		this.onSuccess(this.response.json, text);
	},
	
	startRequest: function(){
		if(this.options.showLoader) Overlayer.showAjaxLoader();
	},
	
	
	failure: function(xhr) {
		if(this.options.showLoader) Overlayer.closeAjaxLoader();
	},
	
	closeAjax: function() {
		if(this.options.showLoader) Overlayer.closeAjaxLoader();
	}
});

/**
 * Generiert eine selbst erstellte Selectbox
 */
var SelectBox = new Class({
	
	initialize: function(obj) {
		this.selections = {};
		this.blur = new BlurEvent();
		this.generateSelectBox(obj);
	},
	
	initSelectBox: function() {
		this.textBox.set('text','bitte auswählen...');
		this.selected = null;
	},
	
	generateSelectBox: function(obj) {
		this.selectBox = new Element('div', {'class':'selectBox'});
		this.textBox = new Element('div', {'class':'textBox'});
		var selector = new Element('div', {'class':'selector'});
		selector.addEvent('click', this.openSelector.bind(this));
		this.selectBox.adopt([this.textBox, selector]);
		
		this.initSelectBox();
		this.selectorBox = new Element('div', {'class':'selectorBox', 'style':'display:none;'});
		for(var i=0; i<obj.selections.length; i++) {
			this.addSelection(obj.selections[i]);
		}
		$(document.body).grab(this.selectorBox);
		
		obj.parent.grab(this.selectBox);
		this.blur.setGlobals([this.selectorBox], function(){
			this.selectorBox.setStyle('display','none');
			this.blur.deactivateBlurEvent();
		}.bind(this));
	},
	
	openSelector: function() {
		var coords = this.selectBox.getCoordinates();
		if(Browser.Engine.trident && Browser.Engine.version==4) {
			this.selectorBox.setStyles({top:(coords.top + coords.height - 2)+'px', left:(coords.left-2)+'px'});
		} else {
			this.selectorBox.setStyles({top:(coords.top + coords.height)+'px', left:coords.left+'px'});
		}
		this.selectorBox.setStyle('display','block');
		this.blur.activateBlurEvent(false);
	},
	
	addSelection: function(selection) {
		var id = selection.id ? selection.id : selection.text;
		if(this.selections[id]) return false;
		var selectionBox = new Element('div', {'class':'selectionBox'});
		selectionBox.set('text', selection.text);
		this.selections[id] = {text:selection.text, element:selectionBox};
		this.selectorBox.grab(selectionBox);
		if(selection.selected) this.setSelected(selection);
		selectionBox.addEvent('click', this.setSelected.bind(this,selection));
		selectionBox.addEvent('mouseover', function(){selectionBox.addClass('selectionMouseOver');});
		selectionBox.addEvent('mouseout', function(){selectionBox.removeClass('selectionMouseOver');});
		return true;
	},
	
	setSelected: function(selection) {
		var id = selection.id ? selection.id : selection.text;
		this.textBox.set('text', selection.text);
		this.selected = id;
		this.selectorBox.setStyle('display','none');
		this.blur.deactivateBlurEvent();
	},
	
	removeSelection: function(id) {
		if(!this.selections[id]) return false;
		this.selections[id].element.destroy();
		delete this.selections[id];
		return true;
	},
	
	destroySelectBox: function() {
		this.selectBox.destroy();
		this.selectorBox.destroy();
	},
	
	getSelected: function() {
		return this.selected == null ? '' : this.selected;
	}
});

/**
 * Diese Klasse simuliert einen Blur Event für Elemente die keine Eingabefelder sind.
 *
 * @author Peter Hartwig
 */
var BlurEvent = new Class({
	
	/**
	 * Setzt alle Globalen Variablen zurück
	 */
	initialize: function() {
		this.notFocusFunc = function(){}
		this.parents = new Array();
		this.bodyFunc = null;
		this.body = $(document.body);
	},
	
	/**
	 * Setzt die beiden globalen Variablen parents und notFocusFunc
	 *
	 * @param array parents Array mit Element-Objekten
	 * @param function notFocusFunc Diese Funktion wird aufgerufen, wenn der Blur ausserhalb des Elements geklickt wurde
	 */
	setGlobals: function(parents, notFocusFunc) {
		this.parents = parents;
		this.notFocusFunc = notFocusFunc;
	},
	
	/**
	 * Aktiviert den Blur Event
	 *
	 * @param bool withDeactivation Zeigt ob die Deaktivierungsfunktions bei einem Blur aufgerufen werden soll
	 */
	activateBlurEvent: function(withDeactivation) {
		this.firstClick = true;
		this.bodyFunc = function(ev) {
			if(this.firstClick) {
				this.firstClick = false;
				return;
			}
			var elm = (ev.target) ? ev.target : ev.srcElement;
			var fuck = this.checkIfElmIsInParent(elm);
			if(!fuck) {
				this.notFocusFunc();
				if(withDeactivation) this.deactivateBlurEvent();
			}
		}.bind(this);
		this.body.addEvent('click', this.bodyFunc);
	},
	
	/**
	 * Prüft, ob das übergebene Element elm, ein Kind oder das Element ist. Bei Erfolg wird ein true zurückgegeben.
	 *
	 * @param Element elm Das zu prüfende Element
	 * @param Element parent Das Elternelement
	 *
	 * @return bool
	 */
	checkIfElmIsInParent: function(elm) {
		var i = 5000;
		while(elm!=undefined) {
			for(var p=0; p < this.parents.length; p++) {
				if(elm==this.parents[p]) return true;
			}
			elm = elm.parentNode;
			if(i==0) return false;
			i--;
		}
		return false;
	},
	
	/**
	 * Deaktiviert den Blur Event
	 */
	deactivateBlurEvent: function() {
		if(this.bodyFunc!=null) { 
			this.body.removeEvent('click', this.bodyFunc);
		}
	}
});

var DatePicker = new Class({

	Implements: Events,
	
	months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
	
	//initialize: function(clickedElement, day, month, year) {
	initialize: function(clickedElement, input, parent) {
		this.elements = {
			body: parent || $(document.body),
			calendarDiv: null,
			content: null,
			clickedElement: clickedElement || null,
			yearTitle: null,
			monthTitle: null,
			yearDec: null,
			yearInc: null,
			monthDec: null,
			monthInc: null,
			input: input
		}
		this.blurEvent = new BlurEvent();
		this.generateCalendar();
		this.blurEvent.setGlobals([this.elements.calendarDiv],this.close.bind(this));
		this.elements.clickedElement.addEvent('click', this.show.bind(this, false));
	},
	
	setClickedElement: function(element) {
		this.elements.clickedElement = element;
		this.elements.clickedElement.addEvent('click', this.show.bind(this, false));
	},
	
	generateCalendar: function() {
		this.elements.calendarDiv = new Element('div',{'class':'calendar'});
		
		var yearDiv = new Element('div',{'class':'calendarYear'});
		yearDiv.addEvent('mouseover',this.changeHeadsClass.bind(this,[yearDiv, true, 'calendarYearHover']));
		yearDiv.addEvent('mouseout',this.changeHeadsClass.bind(this,[yearDiv, false, 'calendarYearHover']));
		this.elements.yearDec = new Element('div',{'class':'calendarYearDec'});
		this.elements.yearTitle = new Element('div',{'class':'calendarYearTitle'})
		this.elements.yearInc = new Element('div',{'class':'calendarYearInc'});
		yearDiv.adopt([this.elements.yearDec, this.elements.yearTitle, this.elements.yearInc]);
		
		var monthDiv = new Element('div',{'class':'calendarMonth'});
		monthDiv.addEvent('mouseover',this.changeHeadsClass.bind(this,[monthDiv, true, 'calendarMonthHover']));
		monthDiv.addEvent('mouseout',this.changeHeadsClass.bind(this,[monthDiv, false, 'calendarMonthHover']));
		this.elements.monthDec = new Element('div',{'class':'calendarMonthDec'});
		this.elements.monthTitle = new Element('div',{'class':'calendarMonthTitle'})
		this.elements.monthInc = new Element('div',{'class':'calendarMonthInc'});
		monthDiv.adopt([this.elements.monthDec, this.elements.monthTitle, this.elements.monthInc]);
		
		var calendarHead = new Element('div',{'class':'calendarHead'});
		calendarHead.adopt([this.generateCalendarDiv('Wo','week'),this.generateCalendarDiv('Mo'),this.generateCalendarDiv('Di'),this.generateCalendarDiv('Mi'),this.generateCalendarDiv('Do'),this.generateCalendarDiv('Fr'),this.generateCalendarDiv('Sa'),this.generateCalendarDiv('So')]);
		
		this.elements.content = new Element('div',{'class':'calendarContent'});
		
		this.elements.calendarDiv.adopt([yearDiv, monthDiv, calendarHead, this.elements.content]);
		this.elements.calendarDiv.setStyle('display','none');
		this.elements.body.grab(this.elements.calendarDiv);
	},
	
	setSelectEvents: function(date) {
		this.date = date.clone();
		var dateYearDec = this.date.clone().decrement('year',1);
		var dateYearInc = this.date.clone().increment('year',1);
		var dateMonthDec = this.date.clone().decrement('month',1);
		var dateMonthInc = this.date.clone().increment('month',1);
		
		this.elements.yearDec.onclick = this.updateCalendar.bind(this, dateYearDec);
		this.elements.yearInc.onclick = this.updateCalendar.bind(this, dateYearInc);
		this.elements.monthDec.onclick = this.updateCalendar.bind(this, dateMonthDec);
		this.elements.monthInc.onclick = this.updateCalendar.bind(this, dateMonthInc);
	},
	
	changeHeadsClass: function(element, hover, className) {
		if(hover) element.addClass(className);
		else element.removeClass(className);
	},
	
	generateCalendarDiv: function(txt, className) {
		var div = new Element('div');
		if(className) div.set('class', className);
		div.set('text',txt);
		return div;
	},
	
	updateCalendar: function(date) {
		if(date) this.date = date.clone();
		else this.date = new Date();
		this.setSelectEvents(this.date);
		this.elements.yearTitle.set('text', this.date.get('year'));
		this.elements.monthTitle.set('text', this.months[this.date.get('month')]);
		this.elements.content.empty();
		this.generateDates(this.date);
	},
	
	generateDates: function(date) {
		var startDate = this.getStartDate(this.date);
		var thisMonth = this.date.get('month');
		
		for(var i=0; i<5; i++) {
			var weekDay = startDate.get('week') + 1;
			var weekDayDiv = this.generateDateDiv({'className':'week','txt':weekDay});
			this.elements.content.grab(weekDayDiv);
			for(var j=0; j<7; j++) {
				var className = '';
				if(thisMonth!=startDate.get('month')) className = 'gray';
				var dayDiv = this.generateDateDiv({'className':className,'txt':startDate.get('date'),'date':startDate.clone()});
				startDate.increment('day',1);
				this.elements.content.grab(dayDiv);
			}
		}
	},
	
	generateDateDiv: function(obj) {
		var div = new Element('div');
		div.set('class', obj.className);
		div.set('html', obj.txt);
		if(obj.date) {
			div.addEvent('mouseover',this.changeDateClass.bind(this,[div, true]));
			div.addEvent('mouseout',this.changeDateClass.bind(this,[div, false]));
			div.addEvent('click',this.setDateToValue.bind(this,[obj.date]));
		}
		return div;
	},
	
	setDateToValue: function(date) {
		this.close(date);
	},
	
	changeDateClass: function(element, hover) {
		if(hover) element.addClass('hover');
		else element.removeClass('hover');
	},
	
	getStartDate: function(date) {
		var startDate = new Date(date.get('year'),date.get('month'),1);
		var weekDay = startDate.get('day');
		if(weekDay==0) startDate.decrement('day',6);
		else if(weekDay!=1) startDate.decrement('day',(weekDay-1));
		return startDate;
	},
	
	/*getEndDate: function(date) {
		var startDate = date.increment('month', 1);
		var endDate = startDate.decrement('day', 1);
		var weekDay = endDate.get('day');
		if(weekDay!=0) endDate.increment('day', (7-weekDay));
		return endDate;
	},*/
	
	getCalendarElement: function() {
		return this.elements.calendarDiv;
	},
	
	show: function(date) {
		this.updateCalendar(date);
		var pos = this.elements.clickedElement.getPosition(this.elements.body);
		this.elements.calendarDiv.setStyles({'left':pos.x, 'top':pos.y});
		this.elements.calendarDiv.setStyle('display','block');
		this.blurEvent.activateBlurEvent(true);
	},
	
	close: function(date) {
		this.blurEvent.deactivateBlurEvent();
		this.elements.calendarDiv.setStyle('display','none');
		if(date) {
			this.elements.input.value = date.format('%d.%m.%Y');
			this.fireEvent('selected');
		}
	},
	
	remove: function() {
		this.elements.calendarDiv.destroy();
	}
	
});

var ImagePicker = new Class({
	
	Implements: Events,
	
	initialize: function(marker, input, button, name) {
		this.iFrameFunction = null;
		this.shownInput = input;
		this.name = name;
		this.generateHiddenForm(marker, name);
	},
	
	generateHiddenForm: function(marker, name) {
		this.formDiv = new Element('fieldset', {'class':'imagePickerFieldset'});
		this.form = new Element('form', {'class':'imagePickerForm', action:'ajax/work.php', enctype:'multipart/form-data', encoding:'multipart/form-data', method:'post', target:'uploadIFrame' + name, onsubmit:'return false;'});
		var inputFileDiv = new Element('div', {'class':'inputFileDiv'});
		this.input = new Element('input', {type:'file', name:name, accept:'image/jpeg'});
		inputFileDiv.grab(this.input);
		this.iFrame = new Element('iframe', {src:'about:blank', name:'uploadIFrame' + name, id:'uploadIFrame' + name , style:'display:none;', 'class':'uploadIFrame', scrolling:'no'});
		this.form.adopt([inputFileDiv, this.iFrame]);
		this.formDiv.grab(this.form);
		marker.grab(this.formDiv);
		this.input.addEvent('change', this.inputChanged.bind(this));
	},
	
	inputChanged: function() {
		this.iFrameFunction = this.pictureUploaded.bind(this);
		this.iFrame.addEvent('load', this.iFrameFunction);
		this.form.submit();
	},
	
	pictureUploaded: function(ev) {
		this.iFrame.removeEvent('load', this.iFrameFunction);
		var iFrameName = 'uploadIFrame' + this.name;
		var frame = null;
		for(var i=0; i<window.frames.length; i++) {
			if(window.frames[i].name==iFrameName) {
				frame=window.frames[i];
				break;
			}
		}
		if(frame==null) {
			alert('Es existiert kein iFrame ' + iFrameName + ' !');
		} else if(frame.window.error) {
			alert(frame.window.error);
		} else if(!frame.window.pictureCopy) {
			alert('Ein unbekannter Fehler ist aufgetreten!');
		} else {
			this.shownInput.value = this.input.value;
			this.fireEvent('selected');
		}
	}
});

var ImageBouncer = new Class({
	
	initialize: function(img, start, end) {
		var fxTween = new Fx.Tween(img, {
			duration: 300
		});
		fxTween.start('margin-top', start + 'px').chain(function(){
			var fxChain = new Fx.Tween(img, {
				duration: 1000,
				transition: Fx.Transitions.Bounce.easeOut
			});
			fxChain.start('margin-top', end + 'px');
		});
	}
});
