﻿/**
 * @author tfuhlroth maxomedia - agentur für crossmedia-kommunikation bsw
 */

/* -------------------------------------------------- */
/* =Console */

if (!$defined(window['console'])) window.console = { log: $empty };


/* -------------------------------------------------- */
/* =Teaser */

var Teaser = new Class({
	
	initialize: function (element) {
		this.element = $(element);
		this.image = this.element.getElement('.image');
		this.title = this.element.getElement('h3');
		
		this.build();
		this.attach();
	},
	
	build: function () {
		this.flash = new Element('div').setStyle('opacity', 0).set('tween', {link: 'cancel', transition: 'sine:out'}).inject(this.image);
		
		new Element('div', {text: this.title.get('text')}).setStyle('padding-left', 30).inject(this.title.empty());
		this.box = new Element('span', {'class': 'box'}).inject(this.title, 'top');
		this.box.set('morph', {link: 'cancel', transition: 'sine:out', duration: 175})
		this.box.set('tween', {link: 'cancel', transition: 'sine:out'});
		this.boxColor = this.box.getStyle('background-color');
		this.arrow = new Element('span', {'class': 'arrow'}).set('tween', {link: 'cancel', transition: 'sine:out', duration: 175}).inject(this.title, 'top');
		
	},
	
	attach: function () {
		this.element.addEvent('mouseenter', this.flashImage.bind(this));
		this.element.addEvent('mouseenter', this.boxToWhite.bind(this));
		this.element.addEvent('mouseleave', this.boxToBlue.bind(this));
	},
	
	flashImage: function () {
		this.flash.setStyle('opacity', 0.6);
		this.flash.tween('opacity', 0);
	},
	
	boxToWhite: function () {
		this.box.get('morph').start({
			'left': -10
		}).chain(function () {
			this.start({
				'left': 0
			});
		});
		this.box.tween('background-color', '#fff');
		
		this.arrow.get('tween').start('left', 8).chain(function () {
			this.element.setStyle('z-index', 5);
			this.start('left', -12).chain(function () {
				this.element.setStyles({
					'z-index': 20,
					'background-image': 'url(/app_themes/grand-casino-bern/_gfx/bg_teaser-small-icon_blue.gif)'
				});
				this.start('left', 0);
			});
		});
	},
	
	boxToBlue: function () {
		this.box.get('morph').start({
			'left': 6
		}).chain(function () {
			this.start({
				'left': 0
			});
		});
		this.box.tween('background-color', this.boxColor);
		
		this.arrow.get('tween').start('left', -15).chain(function () {
			this.element.setStyle('z-index', 5);
			this.start('left', 10).chain(function () {
				this.element.setStyles({
					'z-index': 20,
					'background-image': 'url(/app_themes/grand-casino-bern/_gfx/bg_teaser-small-icon_white.gif)'
				});
				this.start('left', 0);
			});
		});
	}

});


window.addEvent('domready', function () {
	$$('.teaser-small').forEach(function (element) {
		new Teaser(element);
	});
});


/**
 * Menu
 *
 * @classDescription Class for handling expandable Menus.
 * @param {String, Element} container
 * @param {Object} data
 * @param {Object} options
 * @return {Object} Returns a new Menu object.
 * @constructor
 */

var Menu = new Class({
	
	Implements: [Options, Events],
	
	options: {
		closeDelay: 750,
		customTransition: false
	},
	
	initialize: function (options) {
		this.setOptions(options);
		
		this.timer = null;
		this.openItems = [];
		
		this.attachEvents();
	},
	
	attachEvents: function () {
		this.element.addEvents({
			'mouseenter': this.mouseenter.bind(this),
			'mouseleave': this.mouseleave.bind(this),
			'mouseover': this.mouseover.bind(this),
			'click': this.select.bind(this)
		});
	},	
		
	mouseenter: function () {
		this.timer = (this.timer) ? $clear(this.timer) : null;
	},
	
	mouseleave: function () {
		this.timer = this.clear.delay(this.options.closeDelay, this);
	},
	
	clear: function () {
		this.openItems.forEach(function (listitem) {
			this.hide(listitem.getElement('ul'));
		}, this);
		this.openItems.empty();
		this.fireEvent('clear');
	},
	
	mouseover: function (event) {
		if (event.target.get('tag') === 'a') {
			var listitem = event.target.getParent('li');
			
			if (this.openItems.length) {
				$A(this.openItems).reverse().some(function (openItem) {
					if (openItem.hasChild(listitem)) {
						return true;
					} else {
						this.hide(openItem.getElement('ul'));
						this.openItems.pop();
						return false;
					}
				}, this);
			}
			
			var item = listitem.retrieve('item');
			if (item.Nodes && item.Nodes.length) {
				this.show(listitem.getElement('ul'));
				this.openItems.push(listitem);
			}
		}
	},
		
	show: function (list) {
		if (!this.options.customTransition) list.setStyle('display', 'block');
		this.fireEvent('show', list);
	},
	
	hide: function (list) {
		if (!this.options.customTransition) list.setStyle('display', 'none');
		this.fireEvent('hide', list);
	},
	
	select: function (event) {
		if (event.target.get('tag') === 'a') {
			if (this.options.ignoreHyperlinkReference) event.stop();
			var listitem = event.target.getParent('li');
			var item = listitem.retrieve('item');
			this.fireEvent('select', item);
		}
	}
	
});

var menuData  = {
	"Nodes": [
		{"Label": "Dashboard", "Location": "/dashboard/"},
		{"Label": "News", "Location": "/news/", "Nodes": [
			{"Label": "Maxo Green", "Location": "/green/"},
			{"Label": "Trend Blog", "Location": "http://knowhowblog.tools.mxm.ch/"}
		]},
		{"Label": "Jobs", "Location": "/jobs/", "Nodes": [
			{"Label": "New", "Location": "/jobs/new/"},
			{"Label": "Wochenplaner", "Location": "/planer/"}
		]},
		{"Label": "Projekte", "Location": "/projects/", "Nodes": [
			{"Label": "Honorar-Forecast", "Location": "/projects/?list=4"},
			{"Label": "New Business", "Location": "/projects/?list=3"},
			{"Label": "Rechnungen", "Location": "/projects/?list=2"},
			{"Label": "Kennzahlen", "Location": "/projects/?list=5"},
			{"Label": "Case Studies", "Location": "/casestudies/"},
			{"Label": "POPP", "Location": "http://popp.tools.mxm.ch/"}
		]},
		{"Label": "Worker", "Location": "/worker/", "Nodes": [
			{"Label": "Abwesenheit", "Location": "/abwesenheit/"},
			{"Label": "SMS", "Location": "/sms/"}
		]},
		{"Label": "Forum", "Location": "/forum/"},
		{"Label": "Dokumente", "Location": "/dokumente/", "Nodes": [
			{"Label": "Templates", "Location": "/dokumente/templates/"},
			{"Label": "Links", "Location": "/links/"}
		]},
		{"Label": "Quiz", "Location": "/quiz/"},
		{"Label": "Misc", "Location": "/misc/", "Nodes": [
			{"Label": "Maxo Green", "Location": "/green/"},
			{"Label": "Bibliothek", "Location": "/bibliothek/"}
		]}
	]
};

Menu.JSON = new Class({
	
	Extends: Menu,
	
	options: {
		className: 'menu'
	},
	
	initialize: function (container, data, options) {
		this.container = $(container);
		this.data = new Hash(data);
		
		/*
		this.build();
		if (this.data.Nodes.length) {
			this.element.adopt(this.buildList(this.data.Nodes));
		}
		*/
		this.parent(options);
	},
	
	build: function () {
		this.element = new Element('div', {'class': this.options.className}).inject(this.container);
	},
	
	buildList: function (data) {
		var list = new Element('ul');
		data.forEach(function (item) {
			var listitem = new Element('li');
			var anchor = new Element('a', {
				'text': item.Label
			}).inject(listitem);
			if (item.Nodes && item.Nodes.length) listitem.adopt(this.buildList(item.Nodes));
			
			listitem.store('item', item);
			listitem.inject(list);
		}, this);
		return list;
	}
	
});


			
Menu.HTML = new Class({
		
	Extends: Menu,
	
	options: {
		ignoreHyperlinkReference: false
	},
	
	initialize: function (element, options) {
		this.element = $(element);
		this.setOptions(options);
		
		this.data = new Hash({'Nodes': []});
		this.getData(this.element, this.data.get('Nodes'));
		
		this.parent(options);
	},
	
	getData: function (element, node) {
		element.getChildren().forEach(function (item) {
			var obj = {};
			var pushItem = false;
			
			var anchors = item.getChildren('a');
			if (anchors.length) {
				var anchor = anchors[0];
				obj.Label = anchor.get('text');
				obj.Location = anchor.get('href');
				//if (this.options.removeHyperlinkReference) anchor.removeProperty('href');
				pushItem = true;
			}
			
			var lists = item.getChildren('ul');
			if (lists.length) {
				var list = lists[0];
				obj.Nodes = [];
				this.getData(list, obj.Nodes);
			}
			
			if (pushItem) {
				node.push(obj);
				item.store('item', obj);
			}
		}, this);
	}
	
});


/* -------------------------------------------------- */
/* =Events */

Events.implement({
	
	relayEvent: function (type, targetType, bind) {
		if (arguments.length === 2) { // type and targetType are the same
			bind = arguments[1];
			targetType = arguments[0];
		}
		this.addEvent(type, function () {
			bind.fireEvent(targetType, arguments);
		}.bind(bind));
	}
	
});


/* -------------------------------------------------- */
/* =Array */

Array.implement({
	
	shuffle: function () {
		if (this.length > 1) {
			var results = [];
			while (this.length) {
				var index = $random(0, this.length - 1);
				results.push(this[index]);
				this.splice(index, 1);
			}
			this.combine(results);
		}
		return this;
	}
	
});


/* -------------------------------------------------- */
/* =String */

(function () {
	
	var charTable = {
		'-': [' '],
		'': ['.'],
		'a': ['á', 'à', 'â', 'ã'],
		'ae': ['ä'],
		'c': ['ç'],
		'e': ['ë', 'é', 'è', 'ê'],
		'i': ['ï', 'í', 'ì', 'î'],
		'o': ['ó', 'ò', 'ô', 'õ'],
		'oe': ['ö'],
		'u': ['ú', 'ù', 'û'],
		'ue': ['ü'],
		'ss': ['ß']
	};
	
	var newCharTable = new Hash({});
	new Hash(charTable).forEach(function (value, key) {
		value.forEach(function (char) {
			newCharTable.include(char, key);
		});
	}, this);
	charTable = newCharTable;
	
	
	String.implement({
		
		getSlug: function () {
			return this.replace(new RegExp('[' + charTable.getKeys().join('') + ']', 'g'), function (str) {
				return charTable[str];
			});
		}
		
	});
	
	
})();


/* -------------------------------------------------- */
/* =Dictionary */

var Dict = new Class({
	
	Implements: Events,
	
	initialize: function (dictJSON) {
		this.items = new Hash(dictJSON);
		this.fireEvent('complete');
	},
	
	get: function (key) {
		return (this.items.has(key)) ? this.items.get(key) : '[' + key + ']';
	}
	
});


Dict.Remote = new Class({
	
	Extends: Dict,
	
	initialize: function (serviceurl) {
		new Request({
			url: serviceurl,
			async: false,
			onSuccess: this.parse.bind(this)
		}).send();
	},
	
	parse: function (responseText, responseXML) {
		this.items = new Hash();
		var items = responseXML.getElementsByTagName('item');
		for (var i = 0, len = items.length; i < len; i++) {
			this.items.include(items[i].getAttribute('key'), this.getNodeValue(items[i]));
		}
	},
	
	getNodeValue: function (node) {
		if (node.textContent) return node.textContent;
		else if (node.nodeValue) return node.nodeValue;
		else if (node.text) return node.text;
	}
	
});


/* -------------------------------------------------- */
/* =Math.Vector */

Math.Vector = {
	add: function (vector1, vector2) {
		return new Vector(vector1.x + vector2.x, vector1.y + vector2.y, vector1.z + vector2.z);
	},
	subtract: function (vector1, vector2) {
		return new Vector(vector1.x - vector2.x, vector1.y - vector2.y, vector1.z - vector2.z);
	},
	scale: function (vector, scalar) {
		return new Vector(vector.x * scalar, vector.y * scalar, vector.z * scalar);
	},
	normalize: function (vector) {
		return (new Vector(vector.x, vector.y, vector.z)).normalize();
	},
	dotProduct: function (vector1, vector2) {
		return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
	},
	crossProduct: function (vector1, vector2) {
		return new Vector(vector1.y * vector2.z - vector2.y * vector1.z, vector2.x * vector1.z - vector1.x * vector2.z, vector1.x * vector2.y - vector2.x * vector1.y);
	},
	project: function (vector1, vector2) {
		var scalar = Math.Vector.dotProduct(vector2, vector2);
		if (scalar) return Math.Vector.scale(vector2, Math.Vector.dotProduct(vector1, vector2) / scalar);
		return new Math.Vector();
	},
	component: function (vector1, vector2) {
		return Math.Vector.dotProduct(vector1, Math.Vector.normalize(vector2));
	},
	perpendicular: function (vector1, vector2) {
		return Math.Vector.subract(vector1, Math.Vector.project(vector1, vector2));
	}
};


var Vector = new Class({
	initialize: function (x, y, z) {
		this.x = isNaN(x) ? 0 : x;
		this.y = isNaN(y) ? 0 : y;
		this.z = isNaN(z) ? 0 : z;
	},
	clone: function () {
		return new Vector(this.x, this.y, this.z);
	},
	add: function (vector) {
		this.x += vector.x;
		this.y += vector.y;
		this.z += vector.z;
		return this;
	},
	subtract: function (vector) {
		this.x -= vector.x;
		this.y -= vector.y;
		this.z -= vector.z;
		return this;
	},
	scale: function (scalar) {
		this.x *= scalar;
		this.y *= scalar;
		this.z *= scalar;
		return this;
	},
	length: function () {
		return Math.sqrt(this.x * this.x + this.y * this.y + this.z + this.z);
	},
	isZero: function () {
		return (this.x || this.y || this.z) ? false : true;
	},
	normalize: function () {
		var length = this.x * this.x + this.y * this.y + this.z * this.z;
		if (length && Math.abs(length - 1) > 0.01) {
			length = Math.sqrt(length);
			this.x /= length;
			this.y /= length;
			this.z /= length;
		}
		return this;
	}
});