/* --------------------------------------------------------------------
VSBTU.CH Website - main.js 11-06-2009
Version: 1.0
Created by: net4visions.com
Last edited: 11-15-2009
Requirements: mootools-1.2.4-core.js, mootools-1.2.4.2-more.js
Compress online: http://www.refresh-sf.com/yui/ || http://yui.2clics.net/ 
-------------------------------------------------------------------- */

var Site = new Class({
	Implements: [Options, Events],
	
	options: {
		externalLinks: 		true,
		convertTips:		true,
		columnHeights:		false,
		smoothScroll:		true,
		setSlides:			true,
		setTableSort:		false,
		supressTitle:		false,
		setTooltips:		true,
		setInlinePDF:		true
	},	
	
	// INIT
	initialize: function(options) {		
		this.setOptions(options);	
		
		if (this.options.externalLinks)	this.setLinks();
		if (this.options.columnHeights) this.setColumnHeights();
		if (this.options.smoothScroll) 	this.setScroll();
		if (this.options.setSlides) 	this.setSlides();
		if (this.options.setTableSort) 	this.setTableSort();
		if (this.options.supressTitle) 	this.supressTitle();		
		if (this.options.setTooltips)	this.setTips();
		if (this.options.setInlinePDF)	this.setInlinePDF();	
		//this.truncateText(); Remarks: currently using CSS solution
	},
	
	// SHOW PDF FILES INLINE
	setInlinePDF: function() {
		var files = $(document.body).getElements('a[href$=pdf]', 'a[href$=ppt]');
 	   	if (files.length < 1) return false;
 	   	var size	= '600 480';
 		var path 	= 'http://docs.google.com/viewer';
 	   	var url		= 'http://vsbtu.ch';
 	   	
		files.each(function(item, index) {
			var href = item.get('href');
			var file = href.contains('http://') ? href : url + href.substring(href.indexOf('/'));
			
			var str = item.get('title');
			if (!$chk(str)) str = item.get('href');
			str = str.substring(str.lastIndexOf('/')+1, str.length-4);
			var title = str.replace(/_/g, ' ').toUpperCase();
						
			item.addEvent('click', function(e){
				e.stop();
				Mediabox.open(path + '?url=' + file + '&embedded=true', title, size);
			})
		})
	},
	
	// TRUNCATE TEXT
	truncateText: function() {
		if (!$defined($('tblDownloads'))) return false;
		new FitText('tblDownloads', 'div.col-width > a', {
			fitClass: 'truncated',
			offset: 0
		});
	},
	
	// HIGHLIGHT EXTERNAL LINKS
	setLinks: function() {
		if(!this.options.externalLinks) return false;		
		$$('a[rel=external]','a[target=_blank]').each(function(el) {
			if ($type(el.getFirst()) != 'element') el.addClass('external');
			el.set('target','_blank');
		});
	},
	
	// SUPRESS DEFAULT BROWSER TITLES ON LINKS
	supressTitle: function() {
		$(document.body).getElements('a').addEvents({
		    'mouseenter': function(){
		        this.store({title: this.title});
		        this.set('title', '');
		    },
		    'mouseleave': function(){
		        this.set('title', this.retrieve('title'));
		    }
		});
	},

	// EQUAL COLUMN HEIGHTS
	setColumnHeights: function() {
		var vals = [];
		var cols = $$('.unit div.eq');
		if (cols.length == 0) return false;
		$$('.unit div.eq').each(function(element){
			vals.push(element.getSize().y);
		});
		
		vals.sort(this._compare).reverse();
		var hsize = vals[0];
		cols.setStyle('height', hsize);
	},
	
	// SMOOTH SCROLL
	setScroll: function() {
		new Fx.SmoothScroll({
			links: $$('a[href*=#]')
		});
	},
	
	// SLIDES
	setSlides: function() { // slide for events and links
		if (!this.options.setSlides) return false;
		
		var tElements = $$('.toggle');
		var sElements = $$('.slide');
 
		sElements.each(function(el, idx) {							  	
			var fx = new Fx.Slide(el).hide();
			if (!$chk(el.get('html'))) return false; // no event content provided
			tElements[idx].isCollapsed = true;
			tElements[idx].addClass('expand');
			tElements[idx].setStyle('cursor', 'pointer'); 			
			tElements[idx].addEvent('click', function(ev) {
				ev.stop();
				fx.toggle();
				tElements[idx].isCollapsed = (tElements[idx].isCollapsed) ? false : true; 
				if (tElements[idx].isCollapsed) {
					tElements[idx].removeClass('collapse');	
					tElements[idx].addClass('expand');
				} else {
					tElements[idx].removeClass('expand');
					tElements[idx].addClass('collapse');	
				}				
			})
		})
	},
	
	
	// SET TABLE SORT
	setTableSort: function() {
		var el = $('tblDownloads');
		if (!$defined(el)) return false;
		var table = new HtmlTable(el, {
			sortIndex: 0,
			parsers: ['string', 'string', 'files', 'date'],
			classHeadSort: 'asc',
			classHeadSortRev: 'desc',
			sortable: true,
			onSort: function() {
				
			}
		});
		table.sort(2, true);
	},
	
	
	// SET TIPS (DOWNLOAD TABLE)
	setTips: function() {
		var els = $$('.ellipsis a');
		if (els.length == 0) return false;
		new Tips(els, {
			text: function(item) {
				var str = item.get('title');
				if (!$chk(str)) str = item.get('href');
				str = str.substring(str.lastIndexOf('/')+ 1, str.length -4);
				return str.replace(/_/g, ' ').toUpperCase();
			}
		});
	}
});	


// HtmlTable.Parser for file sizes
HtmlTable.Parsers.files = {
	match: /^\d+[^\d.,]*$/,
    convert: function() {
    	var value = this.get('text').toLowerCase();
    	value = value.match(/([\d.,]+)\s*([kmgt])b/) || [0,0,''];
    	var z = {m:3, g:6, t:9}[ value[2] ] || 0;
    	return value[1].replace(/,/g,'').toFloat() * Math.pow(10, z); 
    },
    number: true
};




/*
---

script: Tips.js

description: Class for creating nice tips that follow the mouse cursor when hovering an element.

license: MIT-style license

authors:
- Valerio Proietti
- Christoph Pojer

requires:
- core:1.2.4/Options
- core:1.2.4/Events
- core:1.2.4/Element.Event
- core:1.2.4/Element.Style
- core:1.2.4/Element.Dimensions
- /MooTools.More

provides: [Tips]

...
*/

(function(){

var read = function(option, element){
	return (option) ? ($type(option) == 'function' ? option(element) : element.get(option)) : '';
};

this.Tips = new Class({

	Implements: [Events, Options],

	options: {
		/*
		onAttach: $empty(element),
		onDetach: $empty(element),
		*/
		onShow: function(){
			this.tip.setStyle('display', 'block');
		},
		onHide: function(){
			this.tip.setStyle('display', 'none');
		},
		title: 'title',
		text: function(element){
			return element.get('rel') || element.get('href');
		},
		showDelay: 100,
		hideDelay: 100,
		className: 'tip-wrap',
		offset: {x: 16, y: 16},
		fixed: false
	},

	initialize: function(){
		var params = Array.link(arguments, {options: Object.type, elements: $defined});
		this.setOptions(params.options);
		document.id(this);
		
		if (params.elements) this.attach(params.elements);
	},

	toElement: function(){
		if (this.tip) return this.tip;
		
		this.container = new Element('div', {'class': 'tip'});
		return this.tip = new Element('div', {
			'class': this.options.className,
			styles: {
				position: 'absolute',
				top: 0,
				left: 0
			}
		}).adopt(
			new Element('div', {'class': 'tip-top'}),
			this.container,
			new Element('div', {'class': 'tip-bottom'})
		).inject(document.body);
	},

	attach: function(elements){
		$$(elements).each(function(element){
			var title = read(this.options.title, element),
				text = read(this.options.text, element);
			
			element.erase('title').store('tip:native', title).retrieve('tip:title', title);
			element.retrieve('tip:text', text);
			this.fireEvent('attach', [element]);
			
			var events = ['enter', 'leave'];
			if (!this.options.fixed) events.push('move');
			
			events.each(function(value){
				var event = element.retrieve('tip:' + value);
				if (!event) event = this['element' + value.capitalize()].bindWithEvent(this, element);
				
				element.store('tip:' + value, event).addEvent('mouse' + value, event);
			}, this);
		}, this);
		
		return this;
	},

	detach: function(elements){
		$$(elements).each(function(element){
			['enter', 'leave', 'move'].each(function(value){
				element.removeEvent('mouse' + value, element.retrieve('tip:' + value)).eliminate('tip:' + value);
			});
			
			this.fireEvent('detach', [element]);
			
			if (this.options.title == 'title'){ // This is necessary to check if we can revert the title
				var original = element.retrieve('tip:native');
				if (original) element.set('title', original);
			}
		}, this);
		
		return this;
	},

	elementEnter: function(event, element){
		this.container.empty();
		
		['title', 'text'].each(function(value){
			var content = element.retrieve('tip:' + value);
			if (content) this.fill(new Element('div', {'class': 'tip-' + value}).inject(this.container), content);
		}, this);
		
		$clear(this.timer);
		this.timer = this.show.delay(this.options.showDelay, this, element);
		this.position((this.options.fixed) ? {page: element.getPosition()} : event);
	},

	elementLeave: function(event, element){
		$clear(this.timer);
		this.timer = this.hide.delay(this.options.hideDelay, this, element);
		this.fireForParent(event, element);
	},

	fireForParent: function(event, element){
		element = element.getParent();
		if (!element || element == document.body) return;
		if (element.retrieve('tip:enter')) element.fireEvent('mouseenter', event);
		else this.fireForParent(event, element);
	},

	elementMove: function(event, element){
		this.position(event);
	},

	position: function(event){
		var size = window.getSize(), scroll = window.getScroll(),
			tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight},
			props = {x: 'left', y: 'top'},
			obj = {};
		
		for (var z in props){
			obj[props[z]] = event.page[z] + this.options.offset[z];
			if ((obj[props[z]] + tip[z] - scroll[z]) > size[z]) obj[props[z]] = event.page[z] - this.options.offset[z] - tip[z];
		}
		
		this.tip.setStyles(obj);
	},

	fill: function(element, contents){
		if(typeof contents == 'string') element.set('html', contents);
		else element.adopt(contents);
	},

	show: function(element){
		this.fireEvent('show', [this.tip, element]);
	},

	hide: function(element){
		this.fireEvent('hide', [this.tip, element]);
	}

});

})();






/*
---

script: HtmlTable.Sort.js

description: Builds a stripy, sortable table with methods to add rows.

license: MIT-style license

authors:
- Harald Kirschner
- Aaron Newton

requires:
- core:1.2.4/Hash
- /HtmlTable
- /Class.refactor
- /Element.Delegation
- /Date

provides: [HtmlTable.Sort]

...
*/

HtmlTable = Class.refactor(HtmlTable, {

	options: {/*
		onSort: $empty, */
		sortIndex: 0,
		sortReverse: false,
		parsers: [],
		defaultParser: 'string',
		classSortable: 'table-sortable',
		classHeadSort: 'table-th-sort',
		classHeadSortRev: 'table-th-sort-rev',
		classNoSort: 'table-th-nosort',
		classGroupHead: 'table-tr-group-head',
		classGroup: 'table-tr-group',
		classCellSort: 'table-td-sort',
		classSortSpan: 'table-th-sort-span',
		sortable: false
	},

	initialize: function () {
		this.previous.apply(this, arguments);
		if (this.occluded) return this.occluded;
		this.sorted = {index: null, dir: 1};
		this.bound = {
			headClick: this.headClick.bind(this)
		};
		this.sortSpans = new Elements();
		if (this.options.sortable) {
			this.enableSort();
			if (this.options.sortIndex != null) this.sort(this.options.sortIndex, this.options.sortReverse);
		}
	},

	attachSorts: function(attach){
		this.element[$pick(attach, true) ? 'addEvent' : 'removeEvent']('click:relay(th)', this.bound.headClick);
	},

	setHeaders: function(){
		this.previous.apply(this, arguments);
		if (this.sortEnabled) this.detectParsers();
	},
	
	detectParsers: function(force){
		if (!this.head) return;
		var parsers = this.options.parsers, 
				rows = this.body.rows;

		// auto-detect
		this.parsers = $$(this.head.cells).map(function(cell, index) {
			if (!force && (cell.hasClass(this.options.classNoSort) || cell.retrieve('htmltable-sort'))) return cell.retrieve('htmltable-sort');
			var sortSpan = new Element('span', {'html': '&#160;', 'class': this.options.classSortSpan}).inject(cell, 'top');
			this.sortSpans.push(sortSpan);

			var parser = parsers[index], 
					cancel;
			switch ($type(parser)) {
				case 'function': parser = {convert: parser}; cancel = true; break;
				case 'string': parser = parser; cancel = true; break;
			}
			if (!cancel) {
				HtmlTable.Parsers.some(function(current) {
					var match = current.match;
					if (!match) return false;
					if (Browser.Engine.trident) return false;
					for (var i = 0, j = rows.length; i < j; i++) {
						var text = rows[i].cells[index].get('html').clean();
						if (text && match.test(text)) {
							parser = current;
							return true;
						}
					}
				});
			}

			if (!parser) parser = this.options.defaultParser;
			cell.store('htmltable-parser', parser);
			return parser;
		}, this);
	},

	headClick: function(event, el) {
		if (!this.head) return;
		var index = Array.indexOf(this.head.cells, el);
		this.sort(index);
		return false;
	},

	sort: function(index, reverse, pre) {
		if (!this.head) return;
		pre = !!(pre);
		var classCellSort = this.options.classCellSort;
		var classGroup = this.options.classGroup, 
				classGroupHead = this.options.classGroupHead;

		if (!pre) {
			if (index != null) {
				if (this.sorted.index == index) {
					this.sorted.reverse = !(this.sorted.reverse);
				} else {
					if (this.sorted.index != null) {
						this.sorted.reverse = false;
						this.head.cells[this.sorted.index].removeClass(this.options.classHeadSort).removeClass(this.options.classHeadSortRev);
					} else {
						this.sorted.reverse = true;
					}
					this.sorted.index = index;
				}
			} else {
				index = this.sorted.index;
			}

			if (reverse != null) this.sorted.reverse = reverse;

			var head = document.id(this.head.cells[index]);
			if (head) {
				head.addClass(this.options.classHeadSort);
				if (this.sorted.reverse) head.addClass(this.options.classHeadSortRev);
				else head.removeClass(this.options.classHeadSortRev);
			}

			this.body.getElements('td').removeClass(this.options.classCellSort);
		}

		var parser = this.parsers[index];
		if ($type(parser) == 'string') parser = HtmlTable.Parsers.get(parser);
		if (!parser) return;

		if (!Browser.Engine.trident) {
			var rel = this.body.getParent();
			this.body.dispose();
		}

		var data = Array.map(this.body.rows, function(row, i) {
			var value = parser.convert.call(document.id(row.cells[index]));

			return {
				position: i,
				value: value,
				toString:  function() {
					return value.toString();
				}
			};
		}, this);
		data.reverse(true);

		data.sort(function(a, b){
			if (a.value === b.value) return 0;
			return a.value > b.value ? 1 : -1;
		});

		if (!this.sorted.reverse) data.reverse(true);

		var i = data.length, body = this.body;
		var j, position, entry, group;

		while (i) {
			var item = data[--i];
			position = item.position;
			var row = body.rows[position];
			if (row.disabled) continue;

			if (!pre) {
				if (group === item.value) {
					row.removeClass(classGroupHead).addClass(classGroup);
				} else {
					group = item.value;
					row.removeClass(classGroup).addClass(classGroupHead);
				}
				if (this.zebra) this.zebra(row, i);

				row.cells[index].addClass(classCellSort);
			}

			body.appendChild(row);
			for (j = 0; j < i; j++) {
				if (data[j].position > position) data[j].position--;
			}
		};
		data = null;
		if (rel) rel.grab(body);

		return this.fireEvent('sort', [body, index]);
	},

	reSort: function(){
		if (this.sortEnabled) this.sort.call(this, this.sorted.index, this.sorted.reverse);
		return this;
	},

	enableSort: function(){
		this.element.addClass(this.options.classSortable);
		this.attachSorts(true);
		this.detectParsers();
		this.sortEnabled = true;
		return this;
	},

	disableSort: function(){
		this.element.remove(this.options.classSortable);
		this.attachSorts(false);
		this.sortSpans.each(function(span) { span.destroy(); });
		this.sortSpans.empty();
		this.sortEnabled = false;
		return this;
	}

});

HtmlTable.Parsers = new Hash({

	'date': {
		match: /^\d{2}[-\/ ]\d{2}[-\/ ]\d{2,4}$/,
		convert: function() {
			return Date.parse(this.get('text')).format('db');
		},
		type: 'date'
	},
	'input-checked': {
		match: / type="(radio|checkbox)" /,
		convert: function() {
			return this.getElement('input').checked;
		}
	},
	'input-value': {
		match: /<input/,
		convert: function() {
			return this.getElement('input').value;
		}
	},
	'number': {
		match: /^\d+[^\d.,]*$/,
		convert: function() {
			return this.get('text').toInt();
		},
		number: true
	},
	'numberLax': {
		match: /^[^\d]+\d+$/,
		convert: function() {
			return this.get('text').replace(/[^-?^0-9]/, '').toInt();
		},
		number: true
	},
	'float': {
		match: /^[\d]+\.[\d]+/,
		convert: function() {
			return this.get('text').replace(/[^-?^\d.]/, '').toFloat();
		},
		number: true
	},
	'floatLax': {
		match: /^[^\d]+[\d]+\.[\d]+$/,
		convert: function() {
			return this.get('text').replace(/[^-?^\d.]/, '');
		},
		number: true
	},
	'string': {
		match: null,
		convert: function() {
			return this.get('text');
		}
	},
	'title': {
		match: null,
		convert: function() {
			return this.title;
		}
	}

});


// domready - init site
window.addEvent('domready', function() {
	Site = new Site();	
});