/**
 * @author:		tfuhlroth
 * @copyright	Maxomedia - Agentur für Crossmedia-Kommunikation BSW
 */


/**
 * Console
 */
 
if (window['console'] === undefined) window.console = { log: $empty };
if (window['opera']) window.console.log = window.opera.postError;



/**
 * Site Singleton
 */

var Site = {
	
	settings: {}
	
};
$extend(Site, new Events());

window.addEvent('domready', function () {
	/* to top */
	new Fx.SmoothScroll({
		links: '.top a',
		wheelStops: false
	});
	
	/* gallery-pics: adjust content-aside */
	if ($('profile-image-thumbs-container')) {
		var styles = {
			position: 'relative',
			left: 0,
			top: 0
		};
		var body = $(document.body);
		if (body.hasClass('r1024')) styles.top = -75;
		if (body.hasClass('r1280')) styles.top = -478;
		$('content-aside').setStyles(styles);		
	}
	
	/* emo-header flash fallback */
	if (Browser.Plugins.Flash.version == 0) {
		$('emotion-flash-container').addClass('fallback');		
		
		var mySecondElement = new Element('a', {
			'href': 'http://get.adobe.com/flashplayer/',
			'class': 'getFlash',
			'target': '_blank',			
			'styles': {
				'display': 'block'				
			}			
		});	
		
		mySecondElement.wraps($('emotion-flash-container'));

	}
	
});




/**
 * RSCRHandler
 */

Site.RSCRHandler = {
	
	initialize: function () {
		window.addEvent('resize', this.resize.bind(this));
	},
	
	resize: function () {
		new Request({
			'url': '/_service/RSCRChangeWidth.ashx',
			'method': 'get',
			'data': 'width=' + window.getSize().x,
			'link': 'cancel',
			'noCache': true
		}).send();
	}
	
};

window.addEvent('domready', function () {
	Site.RSCRHandler.initialize();
});




/**
 * Facebook
 */

Site.Facebook = {
	
	initialize: function (apiKey) {
		this.apiKey = apiKey;
		Asset.javascript('http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/de_DE', {
			onload: function () {
				FB.init(this.apiKey, 'xd_receiver.htm');
			}.bind(this)
		});
	}
	
};




/**
 * Header
 *
 * @classDescription Class for initialising EmotionFlash-Header.
 * @param {String} src
 * @param {String} key
 * @return {Object} Returns a new EmotionFlash object.
 * @constructor
 */

var EmotionFlash = new Class({
	
	initialize: function (baseURL, src, key) {
		this.baseURL = baseURL;
		this.src = src;
		this.key = key;
		this.load();
	},
	
	load: function () {
		swfobject.embedSWF(this.src, 'emotion-flash', '100%', '100%', '10', '/_assets/flash/expressInstall.swf', {
			baseURL: this.baseURL,
			flashSource: '/_assets/flash/',
			flvSource: '/_assets/videos/',
			soundSource: '/_assets/sounds/',
			key: this.key
		}, {
			wmode: 'transparent'
		});
	}
	
});




/**
 * Timetable
 */

var Timetable = new Class({
	
	options: {
		urls: {
			de: 'http://fahrplan.sbb.ch/bin/query.exe/dn?s={from}&z={to}&date={date}&time={time}&timesel=arrive&start=1',
			fr: 'http://fahrplan.sbb.ch/bin/query.exe/fn?s={from}&z={to}&date={date}&time={time}&timesel=arrive&start=1',
			it: 'http://fahrplan.sbb.ch/bin/query.exe/in?s={from}&z={to}&date={date}&time={time}&timesel=arrive&start=1',
			en: 'http://fahrplan.sbb.ch/bin/query.exe/en?s={from}&z={to}&date={date}&time={time}&timesel=arrive&start=1'
		}
	},
	
	initialize: function (fields, button) {
		this.fields = new Hash();
		new Hash(fields).forEach(function (id, key) {
			this.fields.set(key, $(id));
		}, this);
		this.button = $(button);
		if (!this.button) return false;
		this.button.addEvent('click', this.open.bind(this));
	},
	
	open: function (event) {
		event.stop();
		var values = new Hash();
		this.fields.forEach(function (field, key) {
		    var value = (field.get('value').length) ? field.get('value') : '';
		    value = escape(value);
			values.set(key, value);
		}, this);
		window.open(this.options.urls[Site.settings.lang].substitute(values));
	}
	
});





/**
 * CinemanSearch
 */

var CinemanSearch = new Class({
	
	options: {
		urls: {
			de: 'http://www.cineman.ch/kinoprogramm/process.php?city={city}&zip={zip}&lang=de',
			fr: 'http://www.cineman.ch/kinoprogramm/process.php?city={city}&zip={zip}&lang=fr',
			it: 'http://www.cineman.ch/kinoprogramm/process.php?city={city}&zip={zip}&lang=de',
			en: 'http://www.cineman.ch/kinoprogramm/process.php?city={city}&zip={zip}&lang=en'
		}
	},
	
	initialize: function (fields, button) {
		this.fields = new Hash();
		new Hash(fields).forEach(function (id, key) {
			this.fields.set(key, $(id));
		}, this);
		this.button = $(button);
		if (!this.button) return false;
		this.button.addEvent('click', this.open.bind(this));
	},
	
	open: function (event) {
		event.stop();
		var values = new Hash();
		this.fields.forEach(function (field, key) {
		    var value = (field.get('value').length) ? field.get('value') : '';
		    value = escape(value);
			values.set(key, value);
		}, this);
		window.open(this.options.urls[Site.settings.lang].substitute(values));
	}
	
});




/**
 * EventSearch
 */

var EventSearch = new Class({

    options: {
        urls: {
            de: 'http://www.moonwalk.ch/search/process.php?search={city}&target=event',
            fr: 'http://www.moonwalk.ch/search/process.php?search={city}&target=event',
            it: 'http://www.moonwalk.ch/search/process.php?search={city}&target=event',
            en: 'http://www.moonwalk.ch/search/process.php?search={city}&target=event'
        }
    },

    initialize: function(fields, button) {
        this.fields = new Hash();
        new Hash(fields).forEach(function(id, key) {
            this.fields.set(key, $(id));
        }, this);
        this.button = $(button);
        if (!this.button) return false;
        this.button.addEvent('click', this.open.bind(this));
    },

    open: function(event) {
        event.stop();
        var values = new Hash();
        this.fields.forEach(function(field, key) {
            var value = (field.get('value').length) ? field.get('value') : '';
            value = escape(value);
            values.set(key, value);
        }, this);
        window.open(this.options.urls[Site.settings.lang].substitute(values));
    }

});




/**
 * Dock
 */

Site.dock = {
	
	initialize: function () {
		this.container = $('dock');
		if (!this.container) return false;
		
		this.menus = new Hash({});
		this.container.getElements('.menu').forEach(function (menuElement) {
			var key = menuElement.getElement('.label').get('text');
			var menu = new DockMenu(menuElement, {
				onBeforeOpen: this.checkMenus.bind(this)
			});
			this.menus.include(key, menu);
		}, this);
		
		window.addEvent('scroll', this.adjustToScrollWidth.bind(this));
		this.adjustToScrollWidth();
	},
	
	checkMenus: function () {
		this.menus.forEach(function (menu) {
			if (menu.isOpen) menu.close(); // close all open menus
		}, this);
	},
	
	adjustToScrollWidth: function () {
		this.container.setStyle('left', -window.getScroll().x);
	}
	
};

window.addEvent('domready', function () {
	Site.dock.initialize();
});


/**
 * DockMenu
 */

var DockMenu = new Class({
	
	Implements: [Options, Events],
	
	options: {
		closeDelay: 750,
		scrollable: true,
		viewportHeight: 300
		//onBeforeOpen: $empty
	},
	
	initialize: function (element, options) {
		this.element = $(element);
		this.setOptions(options);
		
		this.container = this.element.getElement('.menu-container');
		if (!this.container) return false;
		this.button = this.element.getElement('.button');
		this.body = this.element.getElement('.menu-body');
		this.viewport = this.element.getElement('.menu-viewport');
		this.content = this.element.getElement('.menu-content');
		
		if (this.options.scrollable && this.content.getSize().y > this.options.viewportHeight) {
			this.buildScrollbar();
		}	
		
		this.container.store('height', this.container.getSize().y - (this.container.getStyle('border-top-width').toInt() + this.container.getStyle('border-bottom-width').toInt()));
		this.fx = new Fx.Tween(this.container, {
			property: 'height',
			link: 'cancel',
			duration: 400,
			transition: 'sine:out'
		}).set(0);
		
		this.isOpen = false;
		this.timer = null;
		this.bound = {
			open: this.open.bind(this),
			close: this.close.bind(this),
			toggle: this.toggle.bindWithEvent(this),
			mouseenter: this.mouseenter.bind(this),
			mouseleave: this.mouseleave.bind(this),
			checkFocus: this.checkFocus.bindWithEvent(this),
			checkMouseWheel: this.checkMouseWheel.bindWithEvent(this)
		};
		this.button.addEvent('click', this.bound.toggle);
		
		this.modifyItemEvents();
	},
		
	attachEvents: function () {
		this.element.addEvent('mouseenter', this.bound.mouseenter);
		this.element.addEvent('mouseleave', this.bound.mouseleave);
		this.element.addEvent('mousewheel', this.bound.checkMouseWheel);
		$(document.body).addEvent('click', this.bound.checkFocus);
	},
	
	detachEvents: function () {
		this.element.removeEvent('mouseenter', this.bound.mouseenter);
		this.element.removeEvent('mouseleave', this.bound.mouseleave);
		this.element.removeEvent('mousewheel', this.bound.checkMouseWheel);
		$(document.body).removeEvent('click', this.bound.checkFocus);
	},
	
	checkMouseWheel: function (event) {
		event.stop();
		if (this.slider) {
			this.slider.set(this.slider.step - (event.wheel * 20));
		}
	},
	
	open: function () {
		this.fireEvent('onBeforeOpen');
		this.isOpen = true;
		this.attachEvents();
		this.fx.set(this.container.retrieve('height'));
		this.container.setStyle('visibility', 'visible');
	},
	
	close: function () {
		this.isOpen = false;
		this.detachEvents();
		this.fx.set(0);
		this.container.setStyle('visibility', 'hidden');
		this.reset();
	},
		
	mouseenter: function () {
		this.timer = (this.timer) ? $clear(this.timer) : null;
		this.element.addEvent('mousewheel', this.bound.checkMouseWheel);
	},
	
	mouseleave: function (event) {
		this.timer = this.hide.delay(this.options.closeDelay, this);
		this.element.removeEvent('mousewheel', this.bound.checkMouseWheel);
	},
	
	checkFocus: function (event) {
		if (!this.element.hasChild(event.target)) this.hide();
	},
	
	show: function () {
		this.fireEvent('onBeforeOpen');
		this.isOpen = true;
		this.container.setStyle('visibility', 'visible');
		this.attachEvents();
		this.fx.start(this.container.retrieve('height'));
	},
	
	hide: function () {
		this.isOpen = false;
		this.fx.start(0).chain(function () {
			this.detachEvents();
			this.container.setStyle('visibility', 'hidden');
			this.reset();
		}.bind(this));
	},
	
	toggle: function (event) {
		event.stop();
		(this.isOpen) ? this.hide() : this.show();
	},
	
	buildScrollbar: function () {
		
		this.viewport.setStyles({
			'overflow': 'hidden',
			'height': this.options.viewportHeight
		});
		this.content.setStyles({
			'position': 'absolute',
			'left': 0,
			'top': 0
		});
		
		this.scrollbar = new Element('div', {
			'class': 'menu-scrollbar'
		}).set('tween', {link: 'cancel', transition: 'sine:out', duration: 250});
		
		this.knob = new Element('div', {
			'class': 'knob'
		}).inject(this.scrollbar);
		new Element('div').inject(this.knob);
		
		this.scrollbar.inject(this.body);
				
		// knob-size
		this.ratio = (this.viewport.getSize().y / this.content.getSize().y);
		this.knob.setStyle('height', (this.ratio * 100).round() + '%');
		
		this.slider = new Slider(this.scrollbar, this.knob, {
			mode: 'vertical',
			onChange: function (step) {
				if (this.slider.options.transition == 'tween') this.content.get('tween').cancel();
				this.content[this.slider.options.transition]('top', -(((this.content.getSize().y - this.viewport.getSize().y) / 100) * step).round());
			}.bind(this),
			onComplete: function (step) {
				/*this.slider.options.transition = 'tween';
				this.slider.set(this.getNearestSnap(step));
				this.slider.options.transition = 'setStyle';*/
			}.bind(this)
		});
		this.slider.options.transition = 'setStyle';
	},
	
	reset: function () {
		if (this.slider) this.slider.set(0);
	},
	
	modifyItemEvents: function () {
		this.content.getElements('.main-anchor').forEach(function (anchor) {
			anchor.getParent('.main-anchor-target').addEvent('click', function () {
				window.location.href = anchor.get('href');
			});
		}, this);
	}

});


/* IE adjust */
if (Browser.Engine.trident && Browser.Engine.version == 4) {
	
	(function () {
		var container = $('dock-container');
		var adjust = function () {
			var top = (window.getSize().y + window.getScroll().y) - container.getSize().y;
			container.setStyle('top', top);
		};
		window.addEvent('resize', adjust);
		window.addEvent('scroll', adjust);
	})();
}


/**
 * Toolbox
 */

var Toolbox = new Class({
	
	Implements: Options,
	
	options: {
		activeIndex: -1
	},
	
	initialize: function (options) {
		this.setOptions(options);
		
		this.container = $('toolbox-container');
		if (!this.container) return false;
		this.togglers = this.container.getElements('h3');
		this.elements = this.container.getElements('div.content');
		
		this.activeItem = null;
		
		this.accordion = new Fx.Accordion(this.togglers, this.elements, {
			display: this.options.activeIndex,
			opacity: false,
			alwaysHide: true,
			onActive: function (toggler, element) {
				if (this.activeItem) this.activeItem.removeClass('active');
				this.activeItem = toggler.getParent('li').addClass('active');
			}.bind(this),
			onBackground: function (toggler, element) {
				if (toggler.getParent('li') == this.activeItem) {
					this.activeItem.removeClass('active');
					this.activeItem = null;
				}
			}.bind(this)
		});
	}
	
});




/**
 * Gallery
 *
 * @classDescription Class for displaying Image-Galleries.
 * @param {String, Element} image
 * @param {String, Element} container
 * @param {Object} options
 * @return {Object} Returns a new Gallery object.
 * @constructor
 */

var Gallery = new Class({
	
	Implements: [Options, Events],
	
	options: {
		slots: {y: 3}
	},
	
	settings: {},
	
	initialize: function (image, container, options) {
		this.setOptions(options);
		this.image = $(image);
		
		this.container = $(container);
		if (!this.container) return false;
		this.thumblist = this.container.getElement('.thumbs');
		this.viewport = this.container.getElement('.viewport');
		
		this.setup();
	},
	
	setup: function () {
		this.thumbs = this.thumblist.getElements('li');
		this.thumbs.forEach(function (item) {
			var anchor = item.getElement('a');
			anchor.addEvent('click', this.show.bindWithEvent(this, anchor));
		}, this);
		
		this.settings.itemSize = this.thumbs[0].getSize();
		this.settings.offset = {y: this.thumbs[0].getStyle('margin-bottom').toInt()};
		var slots = (this.thumbs.length < this.options.slots.y) ? this.thumbs.length : this.options.slots.y;
		this.settings.size = {y: (slots * (this.settings.itemSize.y + this.settings.offset.y)) - this.settings.offset.y};
		
		this.viewport.setStyle('height', this.settings.size.y);
		if (this.thumbs.length > this.options.slots.y) this.buildScrollbar();
	},
	
	buildScrollbar: function () {
		
		this.scrollbar = new Element('div', {
			'class': 'scrollbar'
		}).set('tween', {link: 'cancel', transition: 'sine:out', duration: 250});
		
		this.knob = new Element('div', {
			'class': 'knob'
		}).inject(this.scrollbar);
		new Element('div').inject(this.knob);
		
		this.scrollbar.inject(this.container);
		
		// knob-size
		this.ratio = (this.options.slots.y / this.thumbs.length);
		this.knob.setStyle('height', (this.ratio * 100).round() + '%');
		
		this.slider = new Slider(this.scrollbar, this.knob, {
			mode: 'vertical',
			onChange: function (step) {
				if (this.slider.options.transition == 'tween') this.thumblist.get('tween').cancel();
				this.thumblist[this.slider.options.transition]('top', -(((this.thumblist.getSize().y - this.viewport.getSize().y - this.settings.offset.y) / 100) * step).round());
			}.bind(this),
			onComplete: function (step) {
				//this.slider.options.transition = 'tween';
				//this.slider.set(this.getNearestStep(step));
				//this.slider.options.transition = 'setStyle';
			}.bind(this)
		});
		this.slider.options.transition = 'setStyle';
		
		// mousewheel
		this.viewport.addEvent('mousewheel', this.checkMouseWheel.bind(this));
	},
	
	getNearestStep: function (step) {
		var slotStep = 100 / (this.thumbs.length - this.options.slots.y);
		return ((step / slotStep).round()) * slotStep;
	},
	
	checkMouseWheel: function (event) {
		event.stop();
		if (this.slider) {
			this.slider.set(this.slider.step - (event.wheel * 20));
		}
	},
		
	show: function (event, anchor) {
		event.stop();
		var image = new Asset.image(anchor.get('href'), {
			onload: function (element) {
				if (this.image) element.replaces(this.image);
				this.image = element;
			}.bind(this)
		});
	}
	
});




/**
 * ContextMenu
 *
 * @classDescription Class for initialising a contextual Menu.
 * @param {String or Object} target
 * @param {Object} data
 * @param {Object} options
 * @return {Object} Returns a new ContextMenu object.
 * @constructor
 */
 
 var ContextMenu = new Class({
	
	Implements: [Options, Events],
	
	options: {
		offset: {x: -5, y: -5},
		closeDelay: 750
	},
	
	initialize: function (target, data, options) {
		this.target = $(target);
		this.data = new Hash(data);
		
		if (!this.target || this.data.getLength() == 0) return false; // check if required arguments are given
		this.setOptions(options);
		
		this.bound = {
			mouseenter: this.mouseenter.bind(this),
			mouseleave: this.mouseleave.bind(this),
			checkFocus: this.checkFocus.bind(this),
			open: this.open.bindWithEvent(this)
		};
		
		this.timer = null;
		this.items = new Hash();
		this.build();
		this.target.addEvent('click', this.bound.open);
	},
	
	build: function () {
		if (this.container) { // check if there is already a contextmenu injected ...
			this.container = $('contextmenu-container');
			this.spike = this.container.getElement('.spike');
			this.element = $('contextmenu');
			this.list = this.container.getElement('ul');
			
		} else { // ... if not, build one.
			this.container = new Element('div', {'id': 'contextmenu-container'});
			this.spike = new Element('div', {'class': 'spike'}).inject(this.container);
			this.element = new Element('div', {'id': 'contextmenu'}).inject(this.container);
			this.list = new Element('ul').inject(this.element);
			this.container.inject($(document.body));
		}
	},
	
	attachEvents: function () {
		this.container.addEvent('mouseenter', this.bound.mouseenter);
		this.container.addEvent('mouseleave', this.bound.mouseleave);
		$(document.body).addEvent('click', this.bound.checkFocus);
	},
	
	detachEvents: function () {
		this.container.removeEvent('mouseenter', this.bound.mouseenter);
		this.container.removeEvent('mouseleave', this.bound.mouseleave);
		$(document.body).removeEvent('click', this.bound.checkFocus);
	},
	
	mouseenter: function () {
		this.timer = (this.timer) ? $clear(this.timer) : null;
	},
	
	mouseleave: function () {
		this.timer = this.close.delay(this.options.closeDelay, this);
	},
	
	checkFocus: function (event) {
		if (!this.container.hasChild(event.target) && event.target != this.target && !this.target.hasChild(event.target)) this.close();
	},
	
	addItem: function (item, key) {
		if (!this.items.has(key) && item) {
			var listitem = new Element('li');
			var anchor = new Element('a', {
				'text': item.label,
				'href': item.href.substitute(item)
			}).inject(listitem);
			if (item.target) anchor.set('target', item.target);
			if (item.styles) anchor.setStyles(item.styles);
			this.items.set(key, listitem);
			listitem.inject(this.list);
		}
	},
	
	addItems: function (items) {
		new Hash(items).forEach(this.addItem, this);
	},
	
	removeItem: function (key) {
		if (this.items.has(key)) {
			this.items.get(key).destroy();
			this.items.erase(key);
		}
	},
	
	removeItems: function () {
		$A(arguments).flatten().forEach(this.removeItem, this);
	},
	
	clearItems: function () {
		this.list.empty();
		this.items = new Hash();
	},
	
	open: function (event) {
		this.attachEvents();
		if (event) this.adjustPosition(event);
		this.clearItems();
		this.addItems(this.data);
		this.container.setStyle('display', 'block');
	},
	
	close: function () {
		this.detachEvents();
		this.container.setStyle('display', 'none');
	},
	
	adjustPosition: function (event) {
		this.container.setStyles({
			'left': event.page.x + this.options.offset.x,
			'top': event.page.y + this.options.offset.y
		});
	}
	
 });
 
 
 

 /**
 * MassContextMenu
 *
 * @classDescription Class for initialising a MassContextMenu.
 * @param {String or Object} element
 * @param {Object} data
 * @param {Object} menuOptions
 * @return {Object} Returns a new MessageList object.
 * @constructor
 */
 
 var MassContextMenu = new Class({
	
	initialize: function (element, data, menuOptions, options) {
		this.element = $(element);
		this.data = data;
		this.menuOptions = menuOptions;
		this.options = options || {};
		
		this.data.forEach(this.setupListItem, this);		
	},
	
	setupListItem: function (item) {
		var element = $(item.id);
		if (element && (item.menuOptions || this.menuOptions)) {
			var menuOptions = new Hash();
			if (item.menuOptions) menuOptions.combine(item.menuOptions);
			if (this.menuOptions) menuOptions.combine(this.menuOptions);
			menuOptions = menuOptions.map(function (option, key) {
				delete item.menuOptions;
				return (option) ? $merge(option, item) : option;
			}, this);
			new ContextMenu(element, menuOptions, this.options);
		}
	}
	
 });
 
 // example implementation
 /*window.addEvent('domready', function () {
	if ($('messaging-inbox')) {
		new MassContextMenu($('messaging-inbox'), [
			{'id': 'message-100', 'userid': 666, 'menuOptions': {'check': {'label': 'Check User online', 'href': '/user/check/{userid}/'}}},
			{'id': 'message-200', 'userid': 777, 'menuOptions': {'read': false}}
		], {
			'read': {'label': 'Lesen', 'href': '/settings/messages/{id}/'},
			'reply': {'label': 'Antworten', 'href': '/settings/messages/{id}/reply/'},
			'viewprofile': {'label': 'Zum Profil', 'href': '/user/{userid}/'},
			'delete': {'label': 'Loeschen', 'href': '/settings/messages/{id}/delete/', 'styles': {'color': '#f00'}}
		});	
	}
 });*/
 
 
 
 
 /**
 * StatusMessage
 */
 
 var StatusMessage = new Class({
	
	Implements: [Options],
	
	options: {
		'className': 'successful', // successful, failure
		'where': 'top', // top, bottom, after, before
		'displayTime': 3000 // -1 for permanent
	},
	
	initialize: function (target, message, options) {
		this.target = $(target);
		this.message = message;
		this.setOptions(options);
		
		this.build();
		this.show();
		if (this.options.displayTime > 0) this.hide.delay(this.options.displayTime, this);
	},
	
	build: function () {
		this.element = new Element('div', {
			'class': 'statusmessage ' + this.options.className,
			'html': this.message
		}).set('tween', {transition: 'sine:out'});
	},
		
	show: function () {
		this.element.inject(this.target, this.options.where);
	},
	
	hide: function () {
		this.element.get('tween').start('opacity', 0).chain(function () {
			this.element.destroy();
		}.bind(this));
	}
	
 });
 
 
 /**
 * StatusMessage
 */
 
 var StatusMessageTweaked = new Class({
	
	Implements: [Options],
	
	options: {
		'text' : 'x Credits added / substracted',
		'className': 'successfull', // successful, failure
		'where': 'bottom', // top, bottom, after, before
		'displayTime': 3000 // -1 for permanent
	},
	
	initialize: function (options) {
		this.target = $('dock-credits');
		this.setOptions(options);
		this.build();
		this.show();
		if (this.options.displayTime > 0) this.hide.delay(this.options.displayTime, this);
	},
	
	build: function () {
		this.element = new Element('div', {
			'id' : 'statusmessageBox',
			'class': this.options.className,
			'style' : 'display:none;height:0px;',
			'html': this.options.text
		});
	},
		
	show: function () {
		this.element.inject(this.target, this.options.where);
		$('statusmessageBox').setStyle('display','block');
		$('statusmessageBox').morph({height:25});
	},
	
	hide: function () {
		var myEffect = new Fx.Morph($('statusmessageBox'));
		myEffect.start({
			height:0
		}).chain(function (){
			$('statusmessageBox').destroy();
		});
	}	
 });
 
 
 
 /**
 * InputStatus
 */
 
 var InputStatus = new Class({
	
	Implements: [Options],
	
	options: {
		'className': 'successful', // successful, failure
		'displayTime': 1500, // -1 for permanent
		'hideOnFocus': false 
	},
	
	styles: {
		current: {},
		successful: {'background-color': '#cfc', 'border-color' : '#6d6'},
		failure: {'background-color': '#ffc8c8', 'border-color' : '#ff5a5a'}
	},
	
	initialize: function (input, options) {
		this.input = $(input);
		this.input.set('morph', {link: 'cancel', transition: 'sine:out'});
		this.setOptions(options);
		this.getCurrentStyles();
		
		this.bound = {
			onFocus: this.onFocus.bind(this)
		};
		
		this.show();
		if (this.options.displayTime > 0) this.hide.delay(this.options.displayTime, this);
	},
	
	getCurrentStyles: function () {
		this.styles.current['background-color'] = this.input.getStyle('background-color');
		this.styles.current['border-color'] = this.input.getStyle('border-top-color');
	},
	
	show: function () {
		if (this.options.hideOnFocus) this.input.addEvent('focus', this.bound.onFocus);
		this.input.morph(this.styles[this.options.className]);
	},
	
	hide: function () {
		this.input.morph(this.styles.current);
	},
	
	onFocus: function () {
		this.hide();
		this.input.removeEvent('focus', this.bound.onFocus);
	}
	
 });




 /**
 * ImageCropper v0.1 (not bulletproof at all, but enough for this specific case)
 *
 * @classDescription Class for initialising an ImageCrop-Tool.
 * @param {String or Object} element
 * @param {Object} options
 * @return {Object} Returns a new ImageCropper object.
 * @constructor
 */
 
 var ImageCropper = new Class({
	
	Implements: [Options, Events],
	
	options: {
		className: 'imagecropper',
		maskColor: '#000',
		maskOpacity: .5,
		selectionBorder: '1px dashed #fff',
		selectionSize: {x: 100, y: 100},
		selectionOffset: {x: 0, y: 0},
		fixedRatio: false,
		rawImageSize: null,
		outputMinSize: null
	},
	
	settings: {},
	
	initialize: function (image, options) {
		this.image = $(image);
		this.setOptions(options);
		
		this.settings.workingImageSize = this.image.getSize();
		
		// crap code, but we aint going for the beauty contest anyway...
		if (this.options.rawImageSize) {
			if (this.options.outputMinSize) {
				var factor = this.options.rawImageSize.x / this.settings.workingImageSize.x;
				
				var selectionSize = this.options.selectionSize;
				selectionSize.x = (selectionSize.x * factor).toInt();
				selectionSize.y = (selectionSize.y * factor).toInt();
				
				factor = this.settings.workingImageSize.x / this.options.rawImageSize.x;
				if (selectionSize.x >= this.options.outputMinSize.x && selectionSize.y >= this.options.outputMinSize.y) {
					
					this.options.selectionSize.x = (this.options.outputMinSize.x * factor).toInt();
					this.options.selectionSize.y = (this.options.outputMinSize.y * factor).toInt();
				}
				
				if (this.options.selectionSize.x < this.options.outputMinSize.x || this.options.selectionSize.y < this.options.outputMinSize.y) {
					this.options.selectionSize.x = (this.options.outputMinSize.x * factor).toInt();
					this.options.selectionSize.y = (this.options.outputMinSize.y * factor).toInt();
				}		
			}
		}
		
		// check selectionOffset
		if (this.options.selectionSize.x + this.options.selectionOffset.x > this.settings.workingImageSize.x) this.options.selectionOffset.x = this.settings.workingImageSize.x - this.options.selectionSize.x;
		if (this.options.selectionSize.y + this.options.selectionOffset.y > this.settings.workingImageSize.y) this.options.selectionOffset.y = this.settings.workingImageSize.y - this.options.selectionSize.y;
		
		this.build();
		this.settings.borderSize = new Hash({
			'top': this.selection.getStyle('border-top-width').toInt(),
			'right': this.selection.getStyle('border-right-width').toInt(),
			'bottom': this.selection.getStyle('border-bottom-width').toInt(),
			'left': this.selection.getStyle('border-left-width').toInt()
		});
		this.settings.borderSize.forEach(function (size, key) {
			if (!size) this.settings.borderSize.set(key, 0);
		}, this);
		
		this.options.selectionSize.x -= (this.settings.borderSize.left + this.settings.borderSize.right);
		this.options.selectionSize.y -= (this.settings.borderSize.top + this.settings.borderSize.bottom);
		this.selection.setStyles({
			width: this.options.selectionSize.x,
			height: this.options.selectionSize.y
		});
		this.settings.currentSize = this.options.selectionSize;
		
		this.drag = new Drag.Move(this.selection, {
			handle: this.dragHandle,
			onDrag: function () {
				this.adjustSelectionBackground();
				this.adjustResizeLimits();
			}.bind(this),
			container: this.container
		});
		this.resize = new Drag(this.selection, {
			handle: this.resizeHandle,
			modifiers: {x: 'width', y: 'height'},
			onDrag: this.keepFixedRatio.bind(this)
		});
		this.adjustSelectionBackground();
		this.adjustResizeLimits();
	},
	
	build: function () {
		this.container = new Element('div', {
			'class': this.options.className,
			styles: {
				'position': 'relative',
				'left': 0,
				'top': 0,
				'width': this.settings.workingImageSize.x,
				'height': this.settings.workingImageSize.y
			}
		});
		
		this.mask = new Element('div', {
			'class': this.options.className + '-mask',
			styles: {
				'position': 'absolute',
				'left': 0,
				'top': 0,
				'z-index': 100,
				'width': '100%',
				'height': '100%',
				'background-color': this.options.maskColor,
				'opacity': this.options.maskOpacity
			}
		}).inject(this.container);
		
		this.selection = new Element('div', {
			'class': this.options.className + '-selection',
			styles: {
				'position': 'absolute',
				'left': this.options.selectionOffset.x,
				'top': this.options.selectionOffset.y,
				'z-index': 200,
				'width': this.options.selectionSize.x,
				'height': this.options.selectionSize.y,
				'background': 'url({src}) no-repeat 0px 0px'.substitute({src: this.image.get('src')}),
				'border': this.options.selectionBorder
			}
		}).inject(this.container);
		this.dragHandle = new Element('div', {
			'class': this.options.className + '-draghandle',
			styles: {
				'position': 'absolute',
				'left': 0,
				'top': 0,
				'width': '100%',
				'height': '100%',
				'cursor': 'move'
			}
		}).inject(this.selection);
		this.resizeHandle = new Element('div', {
			'class': this.options.className + '-resizehandle',
			styles: {
				'position': 'absolute',
				'right': -6,
				'bottom': -6,
				'width': 10,
				'height': 10,
				'border': '1px solid #000',
				'cursor': 'se-resize'
			}
		}).inject(this.selection);
		
		this.container.wraps(this.image);
	},
	
	adjustSelectionBackground: function () {
		var pos = this.selection.getPosition(this.container);
		pos.x += this.settings.borderSize.get('left');
		pos.y += this.settings.borderSize.get('top');
		this.selection.setStyle('background-position', '-{x}px -{y}px'.substitute(pos));
	},
	
	adjustResizeLimits: function () {
		var selectionPosition = this.selection.getPosition(this.container);
		this.resize.options.limit = {'x': [this.options.selectionSize.x - (this.settings.borderSize.get('left') + this.settings.borderSize.get('right')), this.settings.workingImageSize.x - selectionPosition.x - (this.settings.borderSize.get('left') + this.settings.borderSize.get('right'))], 'y': [this.options.selectionSize.y - (this.settings.borderSize.get('top') + this.settings.borderSize.get('bottom')), this.settings.workingImageSize.y - selectionPosition.y - (this.settings.borderSize.get('top') + this.settings.borderSize.get('bottom'))]};
	},
	
	keepFixedRatio: function (element, event) {
		if (this.options.fixedRatio || event.shift) { // only apply if a fixed ratio is set or shift is pressed while scaling
			
			var selectionRatio = (!this.options.fixedRatio && event.shift) ? {x: 1, y: 1} : this.options.selectionSize;
			
			var pos = element.getPosition();
			var mouse = { // get mouse position relative to the top-left corner of the element
				x: this.resize.mouse.now.x - pos.x,
				y: this.resize.mouse.now.y - pos.y
			};
			var size = element.getSize();
			var calculatedSize = size;
			var alphaElement = Math.atan(this.settings.currentSize.y / this.settings.currentSize.x) * (180 / Math.PI);
			var alphaMouse = Math.atan(mouse.y / mouse.x) * (180 / Math.PI);
			
			if (alphaMouse > alphaElement) { // use x-axis...
				var ratio = selectionRatio.y / selectionRatio.x;
				calculatedSize.y = Math.floor(calculatedSize.x * ratio);
				if (calculatedSize.y >= this.resize.options.limit.y[1]) {
					calculatedSize.y = this.resize.options.limit.y[1];
					calculatedSize.x = calculatedSize.y / ratio;
				}
				if (calculatedSize.x >= this.resize.options.limit.x[1]) {
					calculatedSize.x = this.resize.options.limit.x[1];
					calculatedSize.y = calculatedSize.x * ratio;
				}
				
			} else if (alphaElement > alphaMouse) { // ...or y-axis to scale selection
				var ratio = selectionRatio.x / selectionRatio.y;
				calculatedSize.x = Math.floor(calculatedSize.y * ratio);
				if (calculatedSize.x >= this.resize.options.limit.x[1]) {
					calculatedSize.x = this.resize.options.limit.x[1];
					calculatedSize.y = calculatedSize.x / ratio;
				}
				if (calculatedSize.y >= this.resize.options.limit.y[1]) {
					calculatedSize.y = this.resize.options.limit.y[1];
					calculatedSize.x = calculatedSize.y * ratio;
				}
			}
			
			element.setStyles({
				'width': calculatedSize.x,
				'height': calculatedSize.y
			});
			
			this.settings.currentSize = calculatedSize;
			
		}
	},
	
	crop: function () {
		var pos = this.selection.getPosition(this.container);
		var size = this.selection.getSize();
		var values = new Hash({
			x: pos.x,
			y: pos.y,
			width: size.x,
			height: size.y
		});
		
		if (this.options.rawImageSize) {
			var factor = this.options.rawImageSize.x / this.settings.workingImageSize.x;
			values.forEach(function (value, key) {
				values.set(key, Math.ceil(value * factor));
			}, this);
		}
		this.fireEvent('crop', values);
	}
	
 });

 
 
/**
* CompatibilityBar
*/

var CompatibilityBar = new Class({
	
	Implements: [Options, Events],
	
	options: {
		className: 'compatibilitybar',
		message: 'We\'re sorry, but this web site contains enhanced features not supported by the browser version you are currently using. Please update to a recent Version. <a href="http://browser-update.org/en/update.html" target="_blank">Learn how to update your browser</a>',
		browsers: [
			{alias: 'IE6', name: 'trident', version: 4}
		]
	},
	
	initialize: function (options) {
		var showBar = this.options.browsers.some(function (browser) {
			return (Browser.Engine.name == browser.name && Browser.Engine.version <= browser.version);
		}, this);
		if (!showBar) return false;
		if (Cookie.read('compatibilitybar') != 'closed') {
			this.setOptions(options);
			this.build();
			this.show();
		}
	},
	
	build: function () {
		this.container = new Element('div', {
			'class': this.options.className
		}).set('tween', {transition: 'sine:out'});
		
		this.message = new Element('div', {
			'class': this.options.className + '-message',
			'html': this.options.message
		}).inject(this.container);
		
		this.closeButton = new Element('a', {
			'class': this.options.className + '-close',
			'events': {
				'click': this.close.bind(this)
			}
		}).inject(this.container);
		
		this.container.inject(document.body, 'top');
	},
	
	show: function () {
		this.container.tween('height', this.message.getSize().y);
	},
	
	hide: function () {
		this.container.tween('height', 0);
	},
	
	close: function () {
		Cookie.write('compatibilitybar', 'closed', {path: '/'});
		this.hide();
	}
	
});




/**
* SettingsAbo
*/

var SettingsAbo = new Class({
	
	initialize: function (container) {
		this.container = $(container);
		this.inputs = this.container.getElements('.input_text');
		this.inputs.forEach(function (input) {
			new OverText(input);
		}, this);
	}
	
});




/**
* SettingsID
*/

var SettingsID = new Class({
	
	initialize: function (container) {
		this.container = $(container);
		this.inputs = this.container.getElements('.input_text');
		this.inputs.forEach(function (input) {
			new OverText(input);
		}, this);
	}
	
});




/**
* FriendsChart
*/

var FriendsChart = new Class({
	
	initialize: function (id) {
		
	}
	
});




/**
* UserStories
*/

var UserStories = new Class({
	
	Implements: Options,
	
	options: {
		duration: 7500
	},
	
	initialize: function (container, options) {
		this.container = $(container);
		if (!this.container) return false;
		this.setOptions(options);
		
		this.items = this.container.getElements('li');
		if (!this.items.length) return false;
		//this.setHeight();
		this.items.dispose();
		this.items.setStyle('visibility', 'visible');
		
		this.ubound = this.items.length - 1;
		this.activeIndex = -1;
		this.cycle();
		this.cycle.periodical(this.options.duration, this);
	},
	
	setHeight: function () {
		var containerHeight = 0;
		this.items.forEach(function (item) {
			var itemHeight = item.getSize().y;
			if (itemHeight > containerHeight) containerHeight = itemHeight;
		}, this);
		this.container.setStyle('min-height', containerHeight);
	},
	
	cycle: function () {
		if (this.activeIndex >= 0) this.hide(this.activeIndex);
		this.activeIndex = (this.activeIndex < this.ubound) ? ++this.activeIndex : 0;
		this.show(this.activeIndex);
	},
	
	show: function (index) {
		this.items[index].inject(this.container);
	},
	
	hide: function (index) {
		this.items[index].dispose();
	}
	
});



/**
* TargetModifier by Angelo Dini
*/
var TargetModifier = new Class({

    Implements: Options,

    options: {
        target: '_blank',
        className: 'target:blank'
    },

    initialize: function(options) {
        this.setOptions(options);
        $$('a').each(function(item) {
            if (item.hasClass(this.options.className)) {
                item.set('target', this.options.target);
            }
        }, this);
    }

});

window.addEvent('domready', function() {
    new TargetModifier();
});


 
/* -------------------------------------------------- */
/* =roundCorners */

Element.implement({
	
	roundCorners: function () {
		var base = '{prefix}border-{y}{x}radius';
		var prefix = '';
		var top = 'top';
		var right = '-right-';
		var bottom = 'bottom';
		var left = '-left-';
					
		switch (Browser.Engine.name) {
			case 'webkit':
				prefix = '-webkit-';
				break;
			case 'gecko':
				base = '{prefix}border-radius{y}{x}'
				prefix = '-moz-';
				top = '-top';
				right = 'right';
				bottom = '-bottom';
				left = 'left';
				break;
		}
		
		switch (arguments.length) {
			case 1:
				this.setStyle(base.substitute({prefix: prefix}), arguments[0]);
				break;
			case 2:
				this.setStyle(base.substitute({prefix: prefix, y: top, x: left}), arguments[0]);
				this.setStyle(base.substitute({prefix: prefix, y: top, x: right}), arguments[0]);
				this.setStyle(base.substitute({prefix: prefix, y: bottom, x: right}), arguments[1]);
				this.setStyle(base.substitute({prefix: prefix, y: bottom, x: left}), arguments[1]);
				break;
			case 4:
				this.setStyle(base.substitute({prefix: prefix, y: top, x: left}), arguments[0]);
				this.setStyle(base.substitute({prefix: prefix, y: top, x: right}), arguments[1]);
				this.setStyle(base.substitute({prefix: prefix, y: bottom, x: right}), arguments[2]);
				this.setStyle(base.substitute({prefix: prefix, y: bottom, x: left}), arguments[3]);
				break;
		}
		
	}
	
});


// FIX OPERA

/**
 * Project Name:	jActivating
 * Project URI:	http://jactivating.sourceforge.net
 * Description:	Allows website users to interact with embedded content without 'activating' it first
 * Author:		David Muñoz <donraspu AT gmail DOT com>
 * Version:		1.1.2 - May 16, 2007
 * License:		This software is Public Domain (no rights reserved)
 *
 * Installation: 
 * 1) Upload embeddedcontent.js into some directory on your web server.
 * 2) Include the JavaScript file in the <head> of your document like this:
 * 		<script type="text/javascript" src="embeddedcontent.js" defer="defer"></script>
 */
var jActivating = 
{

	// Checks for Internet Explorer
	isMSIE : (document.all && !window.opera) ? true : false,
	
	
	/**
	 * Activates embedded content reinserting it
	 * @return void
	 */
	reinsertContent : function()
	{	
	var totalNodes = new Array(3);
		totalNodes['object'] = document.getElementsByTagName('object').length;
		totalNodes['embed'] = document.getElementsByTagName('embed').length;
		totalNodes['applet'] = document.getElementsByTagName('applet').length;
		for(var tagName in totalNodes)
		{
			var counter = totalNodes[tagName] - 1;
			for(var node; node = document.getElementsByTagName(tagName)[counter]; counter--)
			{
				sourceCode = jActivating.getSourceCode(node);
				if(sourceCode)
				{
					node.outerHTML = sourceCode;
				}
			}
		}
		jActivating.isMSIE = null;
	},
	
	
	/**
	 * Retrieves the object and its content in HTML.
	 * @param object - The analyzed node
	 * @return string - The HTML received, NULL for malformed syntax (end tag)
	 */
	getSourceCode : function(node)
	{
		var sourceCode = node.outerHTML;
		switch(node.nodeName.toLowerCase())
		{
			case 'embed':
				return sourceCode;
			break;
			case 'object':
			case 'applet':
				var openTag = sourceCode.substr(0, sourceCode.indexOf('>') + 1);
				var closeTag = sourceCode.substr(sourceCode.length - 9).toLowerCase();
				if(closeTag != '</object>' && closeTag != '</applet>')
				{
					// Filters malformed syntax for avoid unexpected results in Internet Explorer
					return null;
				}
				if(jActivating.isMSIE)
				{
					var innerCode = jActivating.getInnerCode(node);
					sourceCode = openTag + innerCode + closeTag;
				}
				return sourceCode;
			break;
		}
	},
	
	
	/**
	 * Retrieves the HTML between start and end tags of the object.
	 * @param object - The analyzed node
	 * @return string - The HTML received
	 *
	 * NOTE: the innerHTML property isn't used because Internet Explorer
	 * sometimes returns a empty result.
	 */
	getInnerCode : function(node)
	{
		var innerCode = '';
		var totalChilds = node.childNodes.length - 1;
		for(var counter = totalChilds, child; child = node.childNodes[counter]; counter--)
		{
			innerCode += child.outerHTML;
		}
		return innerCode;
	}
	
}


// Execute script only for Internet Explorer and Opera (9+)
if(document.attachEvent)
{
	if(window.opera)
	{
		document.attachEvent("DOMContentLoaded", jActivating.reinsertContent);
	}
	else
	{
		jActivating.reinsertContent();
	}
}