/*global Base64 */

/* Browser detection addon */

if (Browser.Engine.gecko19 && window.hasJSON) {
	/* requires:
	 * <script>var hasJSON = (typeof window.JSON != 'undefined');</script>
	 * in html before inclusion of mootools-core
	 */
	Browser.Engine.version = 191;	/* gecko 1.9.1 == FF 3.5 */
	Browser.Engine.gecko19 = false;
	Browser.Engine.gecko191 = true;	
}
if (Browser.Engine.trident && document.querySelectorAll) {
	Browser.Engine.trident5 = false;
	Browser.Engine.trident6 = true;
	Browser.Engine.version = 6;
}


/*
 * Additional Element methods:
 * 
 * 	.display(['show'|'hide'|'toggle'])
 *    shortcuts:
 *    .show()
 *    .hide()
 *  .visibility(['show'|'hide'|'toggle'])
 *  .findParent('tagName')
 *  .jumpTo()
 *  .setSelected(options, only)
 *  .highlight()  
 */

(function(funcs) {
	var methods = {};
	funcs.each(function(f) {
		methods[f.name] = function(how) {    		
			how = how || 'toggle';
			var original = this.retrieve(f.name + ':original', this.getStyle(f.name) || f.onValue);
			if (!this.retrieve(f.name + ':initialized', false)) {
				original = (original === f.offValue ? f.onValue : original);
				this.store(f.name + ':original', original);
				this.store(f.name + ':initialized', true);
			}
			switch (how) {
				case 'show': 
					this.setStyle(f.name, original);
					break;
				case 'hide':
					this.setStyle(f.name, f.offValue);
					break;
				case 'toggle':
					this[f.name]((this.getStyle(f.name) === f.offValue) ? 'show' : 'hide');
					break;
			}
			return this;
		};
	});
	Element.implement(methods);
})([{name: 'display', onValue: '', offValue: 'none'}, 
    {name: 'visibility', onValue: '', offValue: 'hidden'}]);

Element.implement({
	findParent: function(tag) {
		tag = tag.toLowerCase();
		var p = this;
		while($defined(p)) {
			if (p.get('tag') === tag) {
				return p;
			}
			p = p.getParent();
		}
		return null;
	},

	// Shortcut Functions
	show: function() {
		this.display('show');
	},
	hide: function() {
		this.display('hide');
	},
	toggle: function() {
		this.display('toggle');
	},
	
	jumpTo: function() {
		var pos = this.getPosition();
		window.scrollTo(pos.x, pos.y);
	},
	
	setSelected: function(options, only) {
		only = only || false;
		
		var that = this;
		if (only) {
			this.options.each(function(o) {
				o.selected = false;
			});
		}
		options.each(function(o) {
			if (o.getParent() === that) {
				o.selected = true;
			}
		});
	},
	
	// Highlight override
	highlight: function(start, end){
		if (!end){
			end = this.retrieve('highlight:original', this.getStyle('background-color'));
			var p = this.getParent();
			while (end === 'transparent' && p) {
				end = p.getStyle('background-color');
				p = p.getParent();
			}
			end = (end === 'transparent') ? '#fff' : end;
		}
		var tween = this.get('tween');
		tween.start('background-color', start || '#ffff88', end).chain(function(){
			this.setStyle('background-color', this.retrieve('highlight:original'));
			tween.callChain();
		}.bind(this));
		return this;
	}
});

if (!Browser.Engine.trident) {
	Element.implement({
		// Add .click() method to elements which don't have it
		click: function(evt) {
			if (!$defined(evt)) {
				evt = this.ownerDocument.createEvent('MouseEvents');  
				evt.initMouseEvent('click', true, true, this.ownerDocument.defaultView, 1, 1, 1, 1, 1, false, false, false, false, 0, null);
			}
			var ret = this.dispatchEvent(evt);
			// Workaround für https://bugzilla.mozilla.org/show_bug.cgi?id=331087
			if (Browser.Engine.gecko && !evt.isTrusted && ret) {
				location.href = this.get('href');
			}
		}
	});
}


/*
 * Additional String methods:
 * 
 *  .startswith('string')
 *  .endswith('string')
 *  .toBase64()
 *  .fromBase64()
 */
String.implement({
	startswith: function(what) {
		if (!what) { return false; }
		if (this.substr(0, what.length) === what) {
			return true;
		} else {
			return false;
		}
	},
	endswith: function(what) {
		if (!what) { return false; }
		if (this.substr(this.length - what.length) === what) {
			return true;
		} else {
			return false;
		}
	},
	
	toBase64: function() {
		if (!window.Base64) {
			if (window.console) {
				console.error("base64.js missing!");
			}
			return "";
		}
		return Base64.encode(this);
	},
	
	fromBase64: function() {
		if (!window.Base64) {
			if (window.console) {
				console.error("base64.js missing!");
			}
			return "";
		}
		return Base64.decode(this);
	}
});

/*
 * Additional Array methods:
 *
 *  .eraseAll()
 *  .first()
 *  .head()
 *  .tail()
 */
Array.implement({
	eraseAll: function() {
		for (var i = 0; i < arguments.length; i++) {
			if ($type(arguments[i]) === 'array') {
				arguments[i].each(function(e) {
					this.erase(e);
				}.bind(this));
			} else {
				this.erase(arguments[i]);
			}
		}
		return this;
	},

	first: function() {
		if (this.length > 0) {
			return this[0];
		} else {
			return null;
		}
	},
	
	head: function() {
		return this.first();
	},
	
	tail: function() {
		return this.filter(function(item, idx) {return idx > 0;});
	}
});


