window.addEvents({
		'domready' : function() { 

        jk.init();

				$$('#messageboard a.close').addEvent('click', function() {
						load('/message');
						$('messageboard').destroy();
						return false;
				});

        $$('#searchform').each(function(s) {
            
            var label = s.getElement('label');
            var input = s.getElement('input[type=text]');
            
            if(input.get('value').length == 0) label.show();

            label.addEvent('click', function() {
                this.hide();
                input.focus();
            });
            
            input.addEvent('focus', function() {
                label.hide();                
            });
            
            input.addEvent('blur', function() {
                if(input.get('value').length > 0) return false;
                label.show();
            });
            
            s.addEvent('submit', function(e) { 
    
                var field   = this.getElement('input[name=search]');
                var value   = field.get('value').trim();
                var pholder = field.retrieve('placeholder');
    
                if(pholder == value) {
                    field.focus();
                    return e.stop();
                }
                field.set('value', value.trim().toLowerCase());						
                
            });
                    
        });
										
		},
		'keydown' : function(event) {
				if(event.key == 'esc' && !event.target.hasClass('custom-esc')) dropdown.close();		
		}
});



Element.implement({
		getHeight : function() {
				return this.getSize().y;
		},
		getWidth : function() {
				return this.getSize().x;
		},
		hide: function() {
				return this.addClass('hide');
		},
		show: function() {
				return this.removeClass('hide');
		},
		fadeIn : function(duration, callback) {
				var self = this;
				this.setStyle('opacity', 0);
				this.set('tween',{
						'duration' : duration,
						'onComplete': function() {
								if(callback) callback.attempt(false, self);
						}
				}).tween('opacity', 1);
		},
		fadeOut : function(duration, callback) {
				var self = this;
				this.set('tween',{
						'duration' : duration,
						'onComplete': function() {
								if(callback) callback.attempt(false, self);
						}
				}).tween('opacity', 0);
		},
		slideIn : function(duration, callback) {

				if(!duration) duration = 300;
				if(!callback) callback = function() {}; 
				
				this.removeClass('hide');
				var h = this.getHeight();
				var o = this.getStyle('overflow');
				this.addClass('hide');

				this.setStyle('height', 0)
						.setStyle('overflow', 'hidden')
						.removeClass('hide')
						.set('tween', {
								duration : duration,
								onComplete : function() {
										this.setStyle('overflow', o);
										callback.attempt();
								}.bind(this)
						}).tween('height', h);
		
		},
		slideOut : function(duration, callback) {

				if(!duration) duration = 300;
				if(!callback) callback = function() {}; 

				var h = this.getHeight();
				var o = this.getStyle('overflow');
				
				this.setStyle('overflow', 'hidden')
						.set('tween', {
								duration : duration,
								onComplete : function() {
										this.setStyle('overflow', o).addClass('hide').setStyle('height', h);
										callback.attempt();
								}.bind(this)
						}).tween('height', 0);
		
		},
		isParent : function(element) {
				t = this; element = $(element);
				while(t.getParent()) { 
					if(t==element) return true;
					t=t.getParent(); 
				} return false;
		}
});



var jk = {
    
    list : false,
    active : false,

    init : function() {

        if(!$('cage')) return false;
				if($(document.body).hasClass('scroll') == false) return false;

        this.list = $('cage').getElement('ul.items');
        if(!this.list) return false;

        window.addEvent('keydown', function(event) {
            if(['input', 'textarea'].contains(event.target.get('tag'))) return true;
            if(event.key == 'j') jk.next();                
            if(event.key == 'k') jk.previous();            
        });
        
        var hash = window.location.hash;

        if(hash == '#last') this.select(this.list.getLast());

        jk.select( $( hash.replace('#', 'item-') ) );
        
        document.addEvent('click', function(e) {
            if(!$(e.target).isParent(jk.list)) {
                jk.active = false;
                jk.list.getElements('li.active').removeClass('active');
            }
        });
    
    },

    next : function() {
        if(!this.active) return this.select( this.list.getElement('li') );

        var next = this.active.getNext();
        if(next) return this.select(next);

        var link = $('pager').getElement('a.arrow.right');
        if(link) window.location = link.get('href');
    },
    
    previous : function() {
        if(!this.active) {
            var link = $('pager').getElement('a.arrow.left');
            if(link) window.location = link.get('href') + '#last';
        }
          
        var previous = this.active.getPrevious();
        if(previous) return this.select(previous); 

        var link = $('pager').getElement('a.arrow.left');
        if(link) window.location = link.get('href') + '#last';
    },
    
    select : function(element) {
    
        if(!$(element)) return false;
    
        window.location.hash = element.get('id').replace('item-', '');
        this.list.getElements('li.active').removeClass('active');
        element.addClass('active');        
        this.active = element;

        var myFx = new Fx.Scroll(window, {
            duration: 300,
            offset : {
                y : -100
            },
            wait: false
        }).toElement(element);

        return false;
        ///window.scrollTo(0, element.offsetTop );
        
    }

}; 

var Loader = new Class({

		Implements : [Options, Events],

		options : {
				delay : 500
		},
		initialize : function(options) {
				this.setOptions(options);
				this.loaded  = false;
				this.loading = false;
				this.timer   = false;
				this.func    = function(t) {
						if(this.loaded) return true;
						this.fireEvent('onStart', t);
				};

		},
		start : function(t) {
				this.loaded  = false;
				this.loading = true;
				this.timer   = this.func.delay(this.options.delay, this, t);
		},
		stop : function(t) {
				this.loaded  = true;
				this.loading = false;
				this.fireEvent('onStop', t);
				$clear(this.timer);
		}

});



var question = {

    sc : false,

		show : function(title, description, callback) {
				
				if($('question')) $('question').destroy();

        if(!this.sc) document.body.addEvent('keydown', function(e) {            
            if(e.key == 'esc') question.hide();
        });

				// add the blocker if it is not there
				this.blocker = new Element('div', {id : 'blocker'})
						.addClass('blocker')
						.addClass('dropdown')
						.addEvent('click', this.hide.bind(this))
						.inject(document.body);
				
				html  = '<div class="display">';
				html += '<div class="title">' + title + '</div>';
				html += '<div class="description">' + description + '</div>';
				html += '</div>';
				html += '<div class="bottom">';
				html += '<div class="buttons">';
				html += '<div class="button reset"><span>cancel</span></div>';
				html += '<div class="button ok"><span>remove</span></div>';
				html += '</div>';
				html += '</div>';

				var a = new Element('div')
						.set('id', 'question')
						.set('html', html)
						.set('tween', {duration : 300})
						.setStyle('top', -300)
						.inject(document.body)
						.tween('top', 0);
																
				$('question').getElement('.ok').addEvent('click', function() {
						question.hide();
						callback.attempt();
				});

				$('question').getElement('.reset').addEvent('click', function() {
						question.hide();
				});

		},
		
		hide : function() {
				if($(this.blocker)) this.blocker.destroy();
				if(!$('question')) return false;

        $('question').set('tween', {
            duration : 300,
            onComplete : function() {
                $('question').destroy();								
            }
        }).tween('top', -300);

		}
};


var Menu = new Class({
		
		Implements : [Options, Events],
		
		options : {
				top : 0,
				left : 0
		},

		initialize : function(menu, options) {

				this.setOptions(options);				
				this.menu   = $(menu).inject(document.body);
				this.button = false;

				window.addEvent('resize', this.close.bind(this));

		},
		
		open : function(button) {

				this.button = button;
				this.blocker = new Element('div')
						.addClass('blocker')
						.addEvent('click', this.close.bind(this))
						.inject(document.body);

				$$('.context-menu').addClass('hide');

				var pos    = this.button.getCoordinates();
				var width  = this.button.getWidth();
				var height = this.button.getHeight();
				
				var dist = {
						x : (window.getWidth() - (pos.left + width + this.options.left)),
						y : (window.getHeight() - (pos.top + height + this.options.top))
				};						

				this.menu.removeClass('hide');
				this.menu.setStyle('opacity', 0);

				var size = {
						x : this.menu.getWidth(),
						y : this.menu.getHeight()			
				};
												
				var direction = {
						x : (size.x >= dist.x) ? 'right' : 'left',
						y : (size.y >= dist.y) ? 'up' : 'down'
				};

				var offset= {
						x : this.options.left,
						y : this.options.top + height
				};

				if(direction.y == 'up')    offset.y = -(size.y) - this.options.top;						
				if(direction.x == 'right') offset.x = width-size.x;						
				
				this.menu.setStyles({
						'top' : pos.top + offset.y,
						'left' : pos.left + offset.x
				});

				this.menu.setStyle('opacity', 1);
				this.fireEvent('onOpen');
				
		},
		
		close : function() {
				this.menu.addClass('hide');
				if(this.blocker) this.blocker.destroy();
				this.fireEvent('onClose');
		},
		
		toggle : function(button) {
				(this.menu.hasClass('hide')) ? this.open(button) : this.close();		
		}

});



var valid = {
				
		minLength : function(string, length) {
				return (string.clean().length < length) ? false : true;		
		},
		
		maxLength : function(string, length) {
				return (string.clean().length > length) ? false : true;				
		},		
		
		password : function(string) {
				return this.minLength(string, 4);
		},

		passwords : function(password1, password2) {
				if(!this.minLength(password1, 4)) return false;
				if(password1.clean() != password2.clean()) return false;
				return true;
		},
		
		username : function(string) {
				if(!string.clean().test(/^[a-z0-9][a-z0-9_-]+[a-z0-9]$/i)) return false;
				if(!this.minLength(string, 3)) return false;
				if(!this.maxLength(string, 20)) return false;
				return true;			
		},		

		email : function(string) {
				return string.clean().test(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
		},

		url : function(string) {
				return string.clean().test(/^(https?|ftp|rmtp|mms):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i);
		}

};


var Navigator = new Class({
  
    Implements : [Options, Events],
    
    container : document.body,

    options : {
        adjust : 0,
        className : 'active',
        element : 'li',
        onSelect : $empty
    },
    
    initialize : function(element, options) {
        this.setOptions(options);
        this.container = $(element);
    },

    active : function() {
		    return this.container.getElement(this.options.element + '.' + this.options.className);    
    },
    
    next : function() {
		    var active = this.active();
        if(!active) return this.fireEvent('onSelect', this.container.getElement(this.options.element) );		    
          
        var next = active.getNext();
        if(next) {
            this.fireEvent('onSelect', next);
    				this.scroll(next);
        }
    
    },
    
    previous : function() {

		    var active = this.active();
        if(!active) return false;
          
        var previous = active.getPrevious();
        if(previous) {
            this.fireEvent('onSelect', previous);
    				this.scroll(previous); 
        }
    
    },

    scroll : function(item) {

				var lim = 
						this.container.offsetHeight + 
						this.container.offsetTop + 
						this.container.scrollTop;

				if((item.offsetTop-this.options.adjust) < this.container.scrollTop) {
						// if item is above visible area				
						var offset = item.offsetTop-this.options.adjust;
						this.container.scrollTo(0,offset);								
				} else if((item.offsetTop+item.getHeight()) > lim) {
						// if item is below visible area				
						var offset = item.offsetTop-(this.container.offsetHeight-item.getHeight());
						this.container.scrollTo(0,offset-1);								
				}
    
    }
    
});


var screencast = {
    show : function(id) {
        $('screencast').show();
        $('video').getElements('.video').addClass('hide');        
        $('v-' + id).removeClass('hide');
    },
    hide : function() {
        $('screencast').hide();
    }
};


/*
Class: String
		adds some basic string functions
*/
String.implement({
		
		short : function(chars) {
				var dots = (this.length > chars) ? '…' : '';
				var short = this.substring(0,chars);
				return short + dots;
		},
		shorturl : function(chars) {
				return this.clean().replace("http://", "")
						.replace("https://", "")
						.replace("www.", "")
						.replace(/\/$/, "")
						.short(chars);
		}
});


Array.implement({

		nsort : function() {

				return this.sort(function(a, b) {

						var r = function (str) {

								if(str === undefined || str === null || $type(str) !== 'string') return false;
								
								str = str.toString();
								str = str.toLowerCase();
								str = str.replace('','a');
								str = str.replace('',"o");
								str = str.replace('',"u");
								str = str.replace('',"s");
																
								return str;
						};
						
						a = r(a.name);
						b = r(b.name);

						if(a == b) return 0;
						return (a < b) ? -1 : 1;				
				});
		
		}

});

var r = false;
var load = function(url, data, onComplete, onError) {

		if(r && typeof r.cancel == 'function') r.cancel();
		
		r = new Request.JSON({
				url: url,
				link : 'cancel',
				onFailure : function() {
						if(onError) onError.attempt();
						return false;
				},
				onComplete: function(json) {
						if(!json) return this.fireEvent('onFailure');
						if(onComplete) onComplete.attempt([json]);		
				}
		}).get(data);

};


Window.implement({	
	openedWindows: {},
	popup: function(location,name,params){
		options = '';
		$H({
			width: 800,
			height: 600,
			left: (screen.width ? (screen.width - (params && params.width ? params.width : 800)) / 2 : 0),
			top: (screen.height ? (screen.height - (params && params.height ? params.height : 600)) / 4 : 0),
			dependent: true,
			directories: false,
			fullscreen: false,
			location: false,
			menubar: false,
			resizable: true,
			scrollbars: true,
			status: false,
			toolbar: false
		}).extend(params || {}).each(function(value, key) {
			if(value === true)
				value = 'yes';
			else if(value === false)
				value = 'no';
				options += key + '=' + value + ',';		
		});
				
		this.openedWindows[name] = window.open(location,name,	options.replace(/\,$/,''));
		this.openedWindows[name].focus();
		return this.openedWindows[name];
	}
});

// bugfix for mootools html loader
Request.HTML.implement({
    processHTML: function(text){
        var match = text.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
        text = (match) ? match[1] : text;          
        var container = new Element('div');          
        return container.set('html', text);
    }
});
