/**
 * Global JS library
 * $Id$ 
 */

var _debug = false;
var version = '$Revision$'.match('[0-9]+\.[0-9]+');

/*----------------------------------------------------------------------------------------------------------------------------
 * Timer
 */

var Timer = Class.create();
Timer.prototype = {
	initialize: function() {
		var date = new Date();
		this.startTime = date.getTime();
	},
	stop: function() {
		var date = new Date();
		this.stopTime = date.getTime();
		return this.stopTime-this.startTime;
	}		
}

/*----------------------------------------------------------------------------------------------------------------------------
 * Loader
 */
var Loader = {
	initialized: 0,
	stack: [],

	/** push function on stack */
	push: function(funct) {
		this.stack.push(funct);
	},
	
	/** execute functions stored in stack */
	start: function() {
		if (this.initialized == 0) {
			this.stack.each( function(f) { f(); f=null; });
			this.stack = [];
		}
		this.initialized += 1;
	}
}

/*----------------------------------------------------------------------------------------------------------------------------
 * body onLoad functions
 */
var _init = function() {
	Loader.start();
	if (document.addEventListener) {
		document.removeEventListener("DOMContentLoaded", _init, false);
	}
	window.onload = null;
}
if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", _init, false);
}
window.onload = _init;

/*----------------------------------------------------------------------------------------------------------------------------
 * IE onunload function
 */
if (window.attachEvent) {
    var clearElementProps = [
        'data',
        'onmouseover',
        'onmouseout',
        'onmousedown',
        'onmouseup',
        'ondblclick',
        'onclick',
        'onselectstart',
        'oncontextmenu'
    ];

    window.attachEvent("onunload", function() {
        var el;
        for(var d = document.all.length;d--;){
            el = document.all[d];
            for(var c = clearElementProps.length;c--;){
                el[clearElementProps[c]] = null;
            }
        }
   });
}            

var _js_hide = function(element) {
	var hide_list = $A(document.getElementsByClassName('js_hide', $(element)||document));
	hide_list.each(	function(h) { h.hide(); });
	var show_list = $A(document.getElementsByClassName('js_show', $(element)||document));
	show_list.each( function(h) { h.show(); });
}

var _init_hover = function(element) {
	try {
		var hover = $A(document.getElementsByClassName('hover_img', $(element)));
		hover.each(
			function(h) { Object.extend(h, new Hover); }
		);
	}
	catch (ex) { if(_debug) throw ex; return false; };
}

Loader.push(function() { 
	new EventDispenser(); 
	_js_hide(); 
	_init_hover();
});

var _dbg = function(obj, tiny) {
		var output = '';
		for(key in obj) {
			output += '------------------- '+key+' -------------------\n'; 
			if ((tiny==1) && (typeof obj[key] == 'function')) output += '('+(typeof obj[key])+') \n\n';
			else if (tiny==2) output += '('+(typeof obj[key])+') \n\n';
			else output += '('+(typeof obj[key])+') '+obj[key] + '\n\n';
			if (output.length > 1200) {
				alert(output);
				output = '';
			}
		}
		if (output)
			alert(output);
}
/*----------------------------------------------------------------------------------------------------------------------------
 * Events
 */
var EventDispenser = Class.create();
EventDispenser.prototype = {
	initialize: function() {
		Event.observe(document, 'mousemove', this.onMouseMove.bindAsEventListener(this));
		window.onunload = function() {
			Event._stopObserving(document, 'mousemove', this.onMouseMove);
		}
	},
	onMouseMove: function(event) {
		Mouse.x = Event.pointerX(event);
		Mouse.y = Event.pointerY(event);
		/*if (_debug) {
			document.title = "dbgMode: x: "+Mouse.x+", y: "+Mouse.y;
		}*/
  }
}

/*
 * Extend Prototype Event object, don't ask me why
 */
Object.extend(Event, {
	_stopObserving: function(element, name, observer) {
		Event.observers.each( function(e) {
			if ((e[0] == element) && (e[1] == name)) {
				Event.stopObserving.apply(this, e);
				e = null;
			}
		});
	}
});

/*----------------------------------------------------------------------------------------------------------------------------
 * Mouse
 */
var Mouse = {
	store: {},
  save: function() {
  	this.store = { 
  		x: Mouse.x, 
  		y: Mouse.y };
  },
  clear: function() {
  	Mouse.store = {};
  }
};

/*----------------------------------------------------------------------------------------------------------------------------
 * Standart Response Handler
 */
var Response = {

	toggle: function(element, closeElements) {
		if (!$(element)) return false;
		if ($(element).visible()) {
			$(element).hide();
			return false;
		}
		return function() {
			if (closeElements) {
				$$(closeElements).each(	function(e) { e.hide() });
			}
			$(element).show();
		}
	}
};

/*----------------------------------------------------------------------------------------------------------------------------
 * Template
 */
Template.Pattern = /(^|.|\r|\n)(\[\$+(\w+)\])/;
Object.extend(Template.prototype, {
	assign: function() {
		args = $A(arguments);
		
		if (typeof this._vars == 'undefined')
			this._vars = {};
		
		if (typeof args[0] == 'string') {
			var arg={}, key=args[0];
			arg[key] = args[1];
			Object.extend(this._vars, arg);
		} else {
			Object.extend(this._vars, args[0]);
		}
	},
	
	fetch: function(clear) {
		var output = this.evaluate(this._vars);
		if (typeof clear != 'undefined')
			this.clear();
		return output;
	},
	
	clear: function() {
		this._vars = {};
	}
});

/*----------------------------------------------------------------------------------------------------------------------------
 * Message
 */
var Message = Class.create();
Message.prototype = {

	/** init message */
	initialize: function(text, options) {
		this._options = {
			text: text,
			timer: null,
			className: '',
			position: 'top left',
			ieHack: false,
			x: Mouse.x, y: Mouse.y
		}
		Object.extend(this._options, options || {});
		
		if (typeof this._options.x == 'undefined') {
			var b = Element.getDimensions(document.body);
			this._options.x = (b.width/2)-20;
			this._options.y = 300;
		}
		
		this.obj = null;
		this.display();
		return this;
	},
	
	/** display message */
	display: function() {
		this.obj = document.createElement('div');
		this.obj.messageObj = this;
		
		$(this.obj).addClassName('js_message');
		$(this.obj).addClassName(this._options.className);
		$(this.obj).setStyle({'top':'-1000px', 'left':'-1000px'});
		
		this.obj.innerHTML = this._options.text;
		document.body.appendChild(this.obj);
		this.calibratePosition();
		
		if (this._options.ieHack) {
			this.ieHack();
		}
		
		// automatic hide
		if (this._options.timer) {
			window.setTimeout(this.hide.bind(this), this._options.timer);
		}
		return this;
	},
	
	/** window overflow issue */
	calibratePosition: function() {
		var cl = Element.getDimensions(document.body);
		var msg = Element.getDimensions(this.obj);
		var left = (this._options.x+msg.width > cl.width) ? cl.width-msg.width-10 : this._options.x;
		var top = (this._options.y+msg.height > cl.height) ? cl.height-msg.height-10 : this._options.y;
		if (this._options.position.match('bottom')) top = top-msg.height-3;
		if (this._options.position.match('right')) left = left-msg.width-3;
		var pos = { 'top':top+'px', 'left':left+'px' }
		Element.setStyle(this.obj, pos);
		return pos;
	},
	
	ieHack: function() {
		if (document.all) {
			var hack = document.createElement('iframe');
			hack.src = "empty_page.html";
			Element.addClassName(hack, 'nonie_hide');
			var dm = $(this.obj).getDimensions();
			Element.setStyle(hack, {
				'position': 'absolute',
				'top': this.obj.style.top, 'left': this.obj.style.left,
				'width': dm.width+'px', 'height': dm.height+'px'
			});
			new Insertion.Bottom(document.body, hack.outerHTML);
			this.iehack = document.body.lastChild;
		}
	},
	
	/** hide message */
	hide: function() {
		try {
			if (this.obj) {
				document.body.removeChild(this.obj);
				this.obj = null;
				delete this.obj;

				if (this._options.ieHack && this.iehack) {
					document.body.removeChild(this.iehack);
					this.iehack = null;
					delete this.iehack;
				}
				return true;
			}
		} catch (ex) { if(_debug) throw ex; return false; };
	}
}

/*----------------------------------------------------------------------------------------------------------------------------
 * Hover
 */

var Hover = Class.create();
Hover.prototype = {

	/** init hover */
	initialize: function(options) {
		this._options = {
			position: 'bottom',
			className: 'hover_message',
			on: 'onmouseover',
			off: 'onmouseout',
			text: ''
		}
		Object.extend(this._options, options || {});
		this[this._options.on] = function() { this.showTitle(); }
		this[this._options.off] = function() { this.hideTitle(); }
		this.hoverObj = null;
	},
	
	/** show hover title */
	showTitle: function() {
		try {
			if(this.hoverObj == null) {
				var pos = Position.cumulativeOffset(this);
				var text = (this._options.text || this.title);
				this.hoverObj = new Message(text, { x:pos[0]+3,	y:pos[1], className:this._options.className, position: this._options.position});
				this.title_back = this.title;
				this.title='';
			} 
		}
		catch (ex) { if(_debug) throw ex; return false; };
	},

	/** hide hover */
	hideTitle: function() {
		try {
			if(this.hoverObj) {
				this.hoverObj.hide();
				this.title = this.title_back;
			}
			this.hoverObj = null;
		}
		catch (ex) { if(_debug) throw ex; return false; };
	}
}

/*----------------------------------------------------------------------------------------------------------------------------
 * extend prototype Element object
 */
Object.extend(Element, {
	/** toggle elements by class name */
	toggleByClassName: function(className, parent) {
		var list = $A(document.getElementsByClassName(className, parent));
		list.each( function(e) { Element.toggle(e); } );
		return true;
	},
	
	/** find parent tag */
	findParentByTagName: function(element, tagName) {
		var e = $(element);
		while (e.parentNode) {
			if (e.parentNode.tagName
				&& (e.parentNode.tagName.toLowerCase() == tagName.toLowerCase())) {
				return e.parentNode;
			} else {
				e = e.parentNode;
			}
		}
		return false;
	},

	/** find next sibling [with tagname]	 */
	findNextSibling: function(element, tagName) {
		var e = $(element);
		if (!tagName) tagName = e.tagName;
		while (e.nextSibling) {
			if (e.nextSibling.tagName
				&& (e.nextSibling.tagName.toLowerCase() == tagName.toLowerCase())) {
				return e.nextSibling;
			} else {
				e = e.nextSibling;
			}
		}
		return false;
	},
	
	/** find previous sibling [with tagname] */
	findPrevSibling: function(element, tagName) {
		var e = $(element);
		if (!tagName) tagName = e.tagName;
		while (e.previousSibling) {
			if (e.previousSibling.tagName 
				&& (e.previousSibling.tagName.toLowerCase() == tagName.toLowerCase())) {
				return e.previousSibling;
			} else {
				e = e.previousSibling;
			}
		}
		return false;
	},
	
	/** replace element class name */
	replaceClassName: function(element, from, to) {
		Element.removeClassName(element, from);
		Element.addClassName(element, to);
	}
	
});

String.prototype.trim=function(){
	return this.replace(/^\s*|\s*$/g,'');
}

/*----------------------------------------------------------------------------------------------------------------------------
 * Popup
 */
var Popup = {
	open: function(url, options) {
		this._options = {
			width: 645,
			height: 500,
			centred: true,
			name: 'popup',      
			params: 'menubar=no,location=no,resizable=yes,scrollbars=yes,status=no'
		}
		Object.extend(this._options, options || {});
		this._options.left = (screen.width-this._options.width) / 2;
		this._options.top = (screen.height-this._options.height) / 2;
		if (this._options.centred) {
			this._options.params += ',left='+this._options.left+',top='+this._options.top;
		}
		var p = window.open(url, this._options.name, 'width='+this._options.width+',height='+this._options.height+','+this._options.params);
		if (p) p.focus();
		return true;
  }
}


/*----------------------------------------------------------------------------------------------------------------------------
 * Cookie
 */
var Cookie = {
	/** set cookie */
	set: function(name,value,days) {
		var expires = '';
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days*24*60*60*1000));
			expires='; expires=' + date.toGMTString();
		}
		document.cookie = name+'='+value+expires+'; path=/';
	},
	
	/** get cookie */
	get: function(name) {
		var nameEQ = name + '=';
		var ca = document.cookie.split(';');
		for(var i=0; i < ca.length; i++) {
			var c = ca[i];
			while (c.charAt(0) == ' ') c=c.substring(1,c.length);
			if (c.indexOf(nameEQ)==0) 
				return c.substring(nameEQ.length,c.length);
		}
		return null
	},
	
	/** remove cookie */
	remove: function(name) {
		Cookie.set(name,'',-1);
	}
}
