(function(){ 
	
	if (typeof(MooTools) == 'undefined') return;
	
	var $ = document.id;
	
	// introduce namespace
	if (typeof(S2) == 'undefined') {
		S2 = new Class({
			log: function(){
				try{
					console.log(arguments);
				} catch(e){}
			},
			error: function(){
				try{
					console.error(arguments);
				} catch(e){}
			}
		});
	};
	
	S2.MooResponse = new Class({
		Extends: S2,
		
		Implements: [Options, Events],
		
		options: {
			requestObjects: {
				xml: {
					url: 'index.php'
				},
				json: {
					url: 'index.php'
				}
			},
			requestParams: {
				'L': 0,
				'method': 'get'
			},
			rootNode: 'response'
		},
		
		initialize: function(options){
			this.setOptions(options);
			this.requests = new Hash({
				'xml': new Request(this.options.requestObjects.xml),
				'json': new Request.JSON(this.options.requestObjects.json)
			});
			this.requests.map(function(request, type){
				request.addEvent('success', function(){
					this.handleResponse.apply(this, [type].extend(arguments));
				}.bind(this));
			}.bind(this));
		},
		
		request: function(type, options){
			var type = type || 'xml';
			var request = this.requests.get(type);
			options = $merge(this.options.requestParams, {data: options});
			return request.send(options);
		},
		
		requestXML: function(){
			return this.request.apply(this, ['xml'].extend(arguments));
		},
		
		requestJSON: function(){
			return this.request.apply(this, ['json'].extend(arguments));
		},
		
		handleResponse: function(type){
			var args = $A(arguments).slice(1);
			switch (type){
				case 'json':
					return this.handleJSONResponse.apply(this, args);
				case 'xml':
				default:
					return this.handleXMLResponse.apply(this, args);
			}
		},
		
		handleXMLResponse: function(responseText, responseXML){
			var nodes = [];
			//var root = responseXML.getElementsByTagName(this.options.rootNode)[0];
			var root = responseXML.firstChild;
			
			
			for (var i = 0, k = root.childNodes.length; i < k; i++){
				if (root.childNodes[i].nodeType == 1) {
					var child = this.removeWhitespace(root.childNodes[i]);
					if (child) nodes.push(child); //this.log('eh', child, child.childNodes);
				}
			}
			
			nodes.each(function(node){
				//var nodeTag = node.get('tag');
				var nodeTag = node.nodeName;
				this.log('[s2_mootools] Handling node of type <'+nodeTag+'>');
				var handler = this['handle'+nodeTag.capitalize().camelCase()+'Node'];
				if (typeof(handler) != 'function') return this.log('No handler for '+nodeTag+'-Nodes implemented.');
				var value = node.getElementsByTagName('value').length ? node.getElementsByTagName('value')[0].firstChild.nodeValue : null;
				try {
					handler.apply(this, [node, value]);
				} catch (e){
					this.log(e);
				}
			}, this);
		},
		
		/*
		handleJsactionsNode: function(){
			console.log('im from core');
		},
		*/
		
		handleJSONResponse: function(){
			this.log('JSON-Response-Handling has not been implemented yet.');
			this.log(arguments);
		},
		
		removeWhitespace: function(node, recursion) {
			var recursion = recursion || 0;
			if (recursion > 25){
				this.log(recursion, node);
				return;
			}
			
			for (i=0; i < node.childNodes.length; i++){
				var current = node.childNodes[i];
				if (current.nodeType == 3 && /^\s+$/.test(current.nodeValue)) {
					node.removeChild(current);
					/*if (i == node.childNodes.length-1) {
						break;
					}*/
					if (i >= node.childNodes.length) {
						i--;
					}
				} else if (current.nodeType == 1 && current.childNodes.length > 0) {
					//this.log(current, current.childNodes, current.childNodes[0]);
					this.removeWhitespace(current, ++recursion); //remove whitespace on child element's children
				}
			}
			
			//this.log(node, node.childNodes);
			return node;
		}
		
	});
	
	/* static addHandler function
	S2.MooResponse.addHandler = function(name, func){
		var name = 'handle'+name.capitalize().camelCase()+'Node';
		var handler = {};
		handler[name] = func;
		return S2.MooResponse.implement(handler);
	}
	*/
	
	S2.MooResponse.addHandler = function(name, func){
		var name = 'handle'+name.capitalize().camelCase()+'Node';
		var handler = {};
		handler[name] = func;
		return Class.refactor(S2.MooResponse, handler);
	}
	
})();


/*
	<root>
	
		<jsactions>
			<action>console.log('hallo welt');</action>
			<action>console.log('hallo welt');</action>
			<action>console.log('hallo welt');</action>
		</jsactions>
		
		<injectHTML>
			Hallo
		</asdas>
	
		<delete>
			myDiv
		</delete>
		
		<Fx.Fade mode="in" duration="50" transition="Ease.InOut" delay="50">myElement</Fx.Fade>
		
		<Fx.Morph selector="#myElement" duration="500" delay="1000">
			<height>100</height>
			<opacity>0.5</opacity>
			.
			..
			...
		</Fx.Morph>
	
	</root>
*/


S2.MooResponse.addHandler('replace', function(node){
	var elements = $$(node.getAttribute('selector'));
	var content = node.getElementsByTagName('value')[0].firstChild.nodeValue;
	
	elements.each(function(el){
		el.set('html', content);
	});
});

S2.MooResponse.addHandler('jsactions', function(node){
	//this.previous();
	var scripts = node.getElementsByTagName('script');
	for (var i = 0; i < scripts.length; i++) {
		$exec(scripts[i].firstChild.nodeValue);
	}
});

S2.MooResponse.addHandler('messages', function(node){
	console.log('hhello world');
});

S2.MooResponse.addHandler('Fx.Morph', function(node){
	var options = getProperties();
});

function fadeIn(containerid){
	container = $(containerid);
	
	var containerMorph = new Fx.Morph(container, {duration: 500, transition: Fx.Transitions.Sine.easeIn});
	
	containerMorph.set({'opacity': 0});
	containerMorph.start({'opacity': [0,1]});

}

S2.MooResponse.addHandler('Fx.Fade.In', function(node){
	var id = node.get('text');
	if (!$(id)) {
		return this.log('Error: Element with id '+id+' not found.');
	}
	var element = $(id);
	var options = node.getProperties('duration', 'transition', 'delay');
	element.morph(options);
});

var tx_s2mootools_mooresponse = new S2.MooResponse();
//myMooResponse.requestXML({'eID': 'tx_s2mooresponse', 'do': 'changeProduct', 'idItem': 1});

/*
function ajaxReq(eID, action, idItem, optValue){
	if(L == null) {
		var L=0;
	}
	
	var resp = new Request({
		url: 'index.php',
		onRequest: function(){
			setCursor('progress');
		},
		onSuccess: function(txt, xml){
			handleMoResponse(xml);
			setCursor('auto');
		},
		onFailure: function(){
			injectMessage('Connection error', 'error');
			setCursor('auto');
		}
	}).get({
		'eID': eID,
		'do': action,
		'idItem': idItem,
		'optValue': optValue,
		'L': L
	}).send();
};

function ajaxPostReq(eID, action, valuesArr){
	dataStr='';
	for( i=0; i<valuesArr.length; i++ ){
		dataStr += valuesArr[i]['name'] +'='+ valuesArr[i]['value']+'&';
	}
	var resp = new Request({
		url: 'index.php?eID='+eID+'&action='+action+'&L='+L,
		onRequest: function(){
			setCursor('progress');
		},
		onSuccess: function(txt, xml){
			handleMoResponse(xml);
			setCursor('auto');
		},
		onFailure: function(){
			injectMessage('Connection error', 'error');
			setCursor('auto');
		},
		method: 'post', 
		data: dataStr 
	}).send();
};

function handleMoResponse(node){
	for (m = 0; m < node.childNodes.length; m++) {
		if (node.childNodes[m].nodeType == 1) {
			for (i = 0; i < node.childNodes[m].childNodes.length; i++) {
				if (node.childNodes[m].childNodes[i].nodeType == 1) {
					switch (node.childNodes[m].childNodes[i].nodeName) {
						case 'messages':
							//alert(node.childNodes[m].childNodes[i].childNodes.length);
							for (j = 0; j < node.childNodes[m].childNodes[i].childNodes.length; j++) {
								if (node.childNodes[m].childNodes[i].childNodes[j].nodeType == 1) {
									html = node.childNodes[m].childNodes[i].childNodes[j].childNodes[0].nodeValue;
									type = node.childNodes[m].childNodes[i].childNodes[j].getAttribute('type');
									markelementid = node.childNodes[m].childNodes[i].childNodes[j].getAttribute('markelementid');
									if (markelementid != '') {
										markupElement(markelementid, type);
									}
									injectMessage(html, type);
								}
							}
							break;
							
						case 'jsactions':
							for (j = 0; j < node.childNodes[m].childNodes[i].childNodes.length; j++) {
								if (node.childNodes[m].childNodes[i].childNodes[j].nodeType == 1) {
									subject = node.childNodes[m].childNodes[i].childNodes[j].childNodes[0].nodeValue;
									type = node.childNodes[m].childNodes[i].childNodes[j].getAttribute('type');
									effect = node.childNodes[m].childNodes[i].childNodes[j].getAttribute('effect');
									switch (type) {
										case 'inject':
											into = node.childNodes[m].childNodes[i].childNodes[j].getAttribute('into');
											injectHTML(subject, into, effect);
										break;
										case 'delete':
											deleteHTML(subject, effect);
										break;
										case 'replace':
											into = node.childNodes[m].childNodes[i].childNodes[j].getAttribute('into');
											replaceHTML(subject, into, effect);
										break;
										case 'fadeOut':
											fadeOut( node.childNodes[m].childNodes[i].childNodes[j].getAttribute('into') );
										break;
										case 'fadeIn':
											fadeIn( node.childNodes[m].childNodes[i].childNodes[j].getAttribute('into') );
										break;
										case 'script':
											eval(subject);
										break;
									}
								}
							}
							break;
					}
				}
			}
		}
	}
}

window.addEvent('domready', function(){
	// Blur all links and .button elements
	blurItems = $$('a');
	blurItems = blurItems.concat($$('.button'));
	blurItems.each(function(link, i){
		link.addEvent('focus', function(e){
			link.blur();
		});
	});
	
	var highlightItems = $$('input[type=text]').combine($$('input[type=password]')).combine($$('textarea'));
	
	highlightItems.each(function(el){
		el.addEvent('focus', function(e){
			el.addClass('active');
			if(el.getAttribute('readonly') == 'readonly'){
				el.blur();
			}
		});
		el.addEvent('blur', function(e){
			el.removeClass('active');
		});
	});
	
});

function scroll(element){
	if($(element)){
		new Fx.Scroll(window, {
			wait: false,
			duration: 700,
			offset: {
				'x': 0,
				'y': -50
			},
			transition: Fx.Transitions.Sine.easeOut
		}).toElement(element);
	}
}

function fadeIn(containerid){
	container = $(containerid);
	
	var containerMorph = new Fx.Morph(container, {duration: 500, transition: Fx.Transitions.Sine.easeIn});
	
	containerMorph.set({'opacity': 0});
	containerMorph.start({'opacity': [0,1]});

}


function fadeOut(containerid){
	container = $(containerid);
	
	var containerMorph = new Fx.Morph(container, {duration: 500, transition: Fx.Transitions.Sine.easeIn});
	
	containerMorph.start({'opacity': 0});
}


function injectHTML(html, containerid, effect){
	if(!containerid){
		container = $('content-wrap');
	} else {
		container = $(containerid);
	}
	
	var containerMorph = new Fx.Morph(container, {duration: 500, transition: Fx.Transitions.Sine.easeIn});
	
	if(effect == 'fade') {
		containerMorph.set({'opacity': 0});
		containerMorph.start({'opacity': [0,1]});
	}
	
	container.set('html', container.get('html'), html);
}

function replaceHTML(html, containerid, effect){
	if(!containerid){
		container = $('content-wrap');
	} else {
		container = $(containerid);
	}
	
	var containerMorph = new Fx.Morph(container, {duration: 500, transition: Fx.Transitions.Sine.easeIn});
	
	if(effect == 'fade') {
		containerMorph.set({'opacity': 0});
		containerMorph.start({'opacity': [0,1]});
	}
	
	container.set('html', html);
}

function deleteHTML(id, effect){
	var element = $(id);
	if(!element) return;

	switch(effect) {
		case "fade":
			element.setStyle('overflow', 'hidden');
			var deleteMorph = new Fx.Morph(element, {duration: 500, transition: Fx.Transitions.Sine.easeOut});
			deleteMorph.start({
				'opacity': '0',
				'height': '0px'
			}).chain(function(){
				element.destroy();
			});
		break;
		
		default:
			element.destroy();
		break;
	}
}

function markupElement(id, type){
	element = $(id);
	if (element) {
		element.addClass(type);
		if (element.getParent('span') && element.getParent('span').hasChild(id + '-' + type)) {
			return;
		}
		else {
			switch (type) {
				case 'error':
					var errorsign = '<a href="javascript:scroll(\'error\');" class="error-markup" id="' + id + '-' + type + '"><img src="typo3conf/ext/s2_template/base/gfx/invalid.gif" /></a>';
					if(element.getNext('img') && element.getNext('img').hasClass('date2cal-trigger')){
						var date2caltrigger = element.getNext('img');
						//wrapper.wraps(element);
						//wrapper.wraps(date2caltrigger);
						var errorLink = new Element('a',{
							'href' : 'javascript:scroll(\'error\')',
							'id' : id+'-'+type,
							'html' : '<img src="typo3conf/ext/s2_template/base/gfx/invalid.gif" />'
						}).inject(date2caltrigger, 'after');
					} else{
						var wrapper = new Element('span');
						wrapper.wraps(element);
						wrapper.set('html', wrapper.get('html'), errorsign);
					}
					break;
			}
		}
	}
}

function setCursor(type){
	document.getElementsByTagName('body')[0].style.cursor=type;
}

function slideEffect(id, styles){
	this.id = id;	
	this.styles = styles;
	this.element = $(this.id);
	
	this.wrapper = new Element('div');
	this.wrapper.wraps(this.element);
	this.wrapper.addClass('clearfix');
	
	this.wrapper.setStyle('overflow', 'hidden');
	
	this.slider = new Fx.Morph(this.element, {duration: 250, transition: 'sine:inOut', link: 'cancel'});
	this.wrapperSlider = new Fx.Morph(this.wrapper, {duration: 250, transition: 'sine:inOut', link: 'cancel'});


	this.element.setStyle('display', 'block');

	// Get height of Element. Fix for Mootools.
	//this.element.setStyle('height', this.element.offsetHeight);
	this.wrapper.setStyle('height', this.element.offsetHeight);
	this.wrapper.setStyle('padding', 0);
	this.wrapper.setStyle('margin', 0);
	this.wrapper.setStyle('border', 'none');
	this.wrapper.setStyle('background-color', 'transparent');
	this.wrapper.setStyle('background-image', 'none');
	// Overwrite Startsettings
	for (var key in this.styles) {
	  this.element.setStyle(key, this.styles[key]);
	}
	
	// Define Startsettings
	//this.initHeight = this.element.getStyle('height');
	this.initHeight = this.element.offsetHeight;
	this.initWrapperHeight = this.wrapper.getStyle('height');
	this.initPaddingBottom = this.element.getStyle('padding-bottom');
	this.initPaddingLeft = this.element.getStyle('padding-left');
	this.initPaddingRight = this.element.getStyle('padding-right');
	this.initPaddingTop = this.element.getStyle('padding-top');
	this.initMarginTop = this.element.getStyle('margin-top');
	this.initMarginLeft = this.element.getStyle('margin-left');
	this.initMarginRight = this.element.getStyle('margin-right');
	this.initMarginBottom = this.element.getStyle('margin-bottom');
	
	this.slideIn = function(){
		this.slider.start({
			'margin-top' : this.initMarginTop
		});
		this.wrapperSlider.start({
			'height' : this.initWrapperHeight
		});
		//this.wrapper.setStyle('display', 'block');
	}
	this.slideOut = function(){
		var parentRef = this;
		this.slider.start({
			'margin-top' : -1*this.initHeight
		});
		this.wrapperSlider.start({
			'height' : '0px'
		}).chain(function(parentRef){
			//parentRef.wrapper.setStyle('display', 'none');
		});
	}
	this.slide = function(){
		if(this.wrapper.getStyle('height') == '0px'){
			this.slideIn();
		} else{
			this.slideOut();
		}
	}
	this.hide = function(){
		//this.wrapper.setStyle('display', 'none');
		this.slider.set({
			'margin-top' : -1*this.initHeight
		});
		this.wrapperSlider.set({
			'height' : '0px'
		});
	}
	this.show = function(){
		this.slider.cancel();
		this.wrapperSlider.cancel();
		//this.wrapper.setStyle('display', 'block');
		this.slider.set({
			'margin-top' : this.initMarginTop
		});
		this.wrapperSlider.set({
			'height' : this.initWrapperHeight
		});
	}
}



function spawnCloseButton(){
	var container = $('messagecenter');
	new Element('a', {
					'href': 'javascript:void(0);',
					'class': 'close',
					'id': 'closebutton',
					'events': {
						'click': function(){
							var messageCenter = new Fx.Morph(container, {duration: 200, transition: Fx.Transitions.Sine.easeOut})
							
							messageCenter.start({
								'opacity': 0
							}).chain(function(){
								this.start({
									'height': 0,
									'margin': 0,
									'padding': 0
								})
							}).chain(function(){
								$('messagecenter').destroy();
							});
							$('closebutton').removeEvents();
							$('closebutton').destroy();
						},
						'focus': function(){
							this.blur();
						}
					}
				}).inject($('messagecenter'), 'top');
}

function injectMessage(message, type){
	if($('content-wrap')) container = $('content-wrap');
	else if($('popup'))  container = $('popup');
	
	// Get Messagecenter div
	if(!container.hasChild('messagecenter')){
		new Element('div', {'id': 'messagecenter'}).inject(container, 'top');
		spawnCloseButton();
	}
	
	// Spawn Type-specific Container if not exists and inject Message
	if(!$('messagecenter').hasChild(type)){
		var typeContainer  = new Element('div', {
			'id': type
		});
		typeContainer.inject($('messagecenter'), 'top');
	}
	
	var message  = new Element('div', {
			'class': 'message-item',
			'html': message
		});
	message.inject(type, 'top');
	
	new Fx.Morph(message, {duration: 500, transition: Fx.Transitions.Sine.easeIn}).start({'opacity': 1});
}
*/
