/*  remmah. JavaScript framework
 *  (c) 2006 Peter Hammer Mortensen <hammer_mortensen@hotmail.com>
 *  remmah. is freely distributable under the terms of ....
 *  For details, see the remmah. web site: http://www.....
/*--------------------------------------------------------------------------*/
Function.prototype.requires = function(fn)
{
	addEvent(window, 'load', function() {
		try
		{
			var f = eval(fn);
			if (!f)
				throw "Error";
		}
		catch(e)
		{
			alert(fn + ': is required, but is not defined.\nThe script will terminate.');
			return false;
		}
	}, false);
}

String.prototype.namespace = function(separator) {
  var ns = this.split(separator || '.'), p = window, i;
  for (i = 0; i < ns.length; i++) {
    p = p[ns[i]] = p[ns[i]] || {};
  }
};

function addEvent(elm, evType, fn, useCapture)
{
	return remmah.Event.addEvent(elm, evType, fn, useCapture);
}

function getScrollOffsets()
{
	if( self.pageYOffset ) {
		getScrollOffsets = function() {
			var offset = new Object();
			offset.X = 0;
			offset.Y = 0;

			offset.X = self.pageXOffset;
			offset.Y = self.pageYOffset;

			return offset;
		}
	} else if( document.documentElement && document.documentElement.scrollTop ) {
		getScrollOffsets = function() {
			var offset = new Object();
			offset.X = 0;
			offset.Y = 0;

			offset.X = document.documentElement.scrollLeft;
			offset.Y = document.documentElement.scrollTop;

			return offset;
		}
	} else if( document.body ) {
		getScrollOffsets = function() {
			var offset = new Object();
			offset.X = 0;
			offset.Y = 0;
		
			offset.X = document.body.scrollLeft;
			offset.Y = document.body.scrollTop;
		
			return offset;
		}
	}
}

// globals
var d = window.document;

// prototype functions
Function.prototype.extend = function(Super) {
	var Self = this;
	var Func = function() {
		Super.apply(this, arguments);
		Self.apply(this, arguments);
	};

	Func.prototype = new Super();
	Func.prototype.Parent = Super.prototype;
	Func.prototype.Parameters = Self.params();
	
	Func.prototype.params = function(){};
	return Func;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
}

// base
//if( typeof( remmah ) == "undefined" ) remmah = {};
var remmah = remmah ? remmah : new Object();
remmah._getElement=	d.getElementById	? (function(id) {return d.getElementById(id);} ):
			d.all			? (function(id) {return d.all[id];} ):
			new Function; // not supported
remmah.DOM={
	name		: 'remmah.DOM',
	// Better implementation for document.getElementById( str )
	// Accepts: an object, a string, an array of objects or strings
	getElement 	: function(id)
	{
		var  t = typeof(id);
		switch(t){
      		case 'object' 	: // Flipped Loop with Optimized Reverse Count (see http://www.devwebpro.com/devwebpro-39-20030514OptimizingJavaScriptforExecutionSpeed.html)
        				n = id.length;
					var i=n-1;
					do 
					{
						var  t2 = typeof(id[i]);
						if ( t2 == 'string' )
							id[i] = remmah._getElement(id); //(d.getElementById) ? d.getElementById(id[i]) : ((d.all) ? d.all[id[i]] : null);
					}
					while (--i);
					return id;
		case 'string' 	: return remmah._getElement(id);
      		default 	: return null;
		}
	},
	getEventTarget: function(e)
	{
		return remmah.Event.getTarget(e);
	},
	getElementsByClassName : function(classname, node)
	{
		if(!node) node = document.getElementsByTagName("body")[0];
		var a = [];
		var re = new RegExp('\\b' + classname + '\\b');
		var els = node.getElementsByTagName("*");
		for(var i=0,j=els.length; i<j; i++)
			if(re.test(els[i].className))a.push(els[i]);
		return a;
	},
	hasClassName : function(id, classname)
	{
		var element = this.getElement(id);
  		var classes = element.className.split(' ');
  
  		for (var i = 0; i < classes.length; i++) {
    			if (classes[i] == classname) 
    				return true;
  		}
  		return false;
	},
	getOpacity:  function(element)
	{
		var s = element.style;

		//if (remmah.DOM.isCssSupported('opacity', element))
		if(!element.runtimeStyle)
			return parseInt(s.opacity);
		else
			return parseInt((s.filter.toString().match(/\bopacity[=](.*)\b/g)[0].split("=")[1])/100);
	},
	setOpacity:  function(opacity, element)
	{
		var s = element.style;
		s.opacity = opacity;
		var undefined;
		if (s.filter !== undefined)         {s.filter = "alpha(opacity=" + (opacity*100) + ")"};
	},
	getStyle: function(element, prop)
	{
		var val; 

		if (document.defaultView && document.defaultView.getComputedStyle) {
			val = document.defaultView.getComputedStyle(element, null)[prop];
		} else if (element.currentStyle) {
			val = element.currentStyle[prop];
		} else {
			val = element.style[prop];
		}

		if (val == '')
			val = element.style[prop];

		return val;
	}
};
remmah.Event={
	getTarget: function(e)
	{
		if (!e) var e = window.event;
		if (e.target) return e.target;
		else if (e.srcElement) return e.srcElement;
	},
	
	// addEvent and removeEvent
	// cross-browser event handling for IE5+,  NS6 and Mozilla
	// By Scott Andrew
	addEvent: function(elm, evType, fn, useCapture)
	{
		if (elm.addEventListener){
			elm.addEventListener(evType, fn, useCapture);
			return true;
		} else if (elm.attachEvent){
   			var r = elm.attachEvent("on"+evType, fn);
   			return r;
 		}
	},

	addFileLoadEvent: function(elm, fn)
	{
		if (window.opera)
		{
			elm.onload= fn
		}
		else
		{
			if (elm.onreadystatechange != 'undefined')
			{
				//elm.onreadystatechange = fn;
				elm.onreadystatechange = function(){
					var rs = this.readyState;
					if (rs == 'loaded' || rs == 'complete') {
						fn();
					}
				}
			}
			elm.onload = fn;
		}
	},

	Key: {
		"BACKSPACE"	:   8, 
		"TAB"		:   9,
		"RETURN"	:  13, 
		"SPACE"		:  32, 
		"LEFT" 		:  37,
		"UP" 		:  38,
		"RIGHT" 	:  39,
		"DOWN" 		:  40,
		"PERIOD"	:  46
	}
}

remmah.Ajax = function()
{
	var obj;
	if (window.XMLHttpRequest) obj= new XMLHttpRequest(); 
	else if (window.ActiveXObject)
	{
		try
		{
			obj= new ActiveXObject('MSXML2.XMLHTTP.3.0');
		}
		catch(er)
		{
			try
			{
				obj= new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(er)
			{
				obj= false;
			}
		}
	}
	return obj;
}
remmah.File={
	getFileExtension: function(filename)
	{
		return filename.split('.').pop();
	},
	queueTimer: 1,
	loadQueueTimer: null,
	loadQueue: [],
	callbackQueue: [],
	addLoadQueue: function(file)
	{
		remmah.File.loadQueue.push(file);
		if (remmah.File.loadQueueTimer == null)
			remmah.File.loadQueueTimer = setTimeout(remmah.File.loadStart, remmah.File.queueTimer);
	},
	loadStart: function()
	{
		if (remmah.File.loadQueue.length != 0)
		{
			var filename = remmah.File.loadQueue[0];
			var fileRef = remmah.File.load(filename);
			remmah.Event.addFileLoadEvent(fileRef, function(){
				remmah.File.loadQueue = remmah.File.loadQueue.slice(1);
				setTimeout(remmah.File.loadStart, remmah.File.queueTimer);
			});
		}
		else
		{
			if (remmah.File.callbackQueue.length != 0)
			{
				var callbacks = remmah.File.callbackQueue;
				for (var i=0; i<callbacks.length; i++)
					callbacks[i]();
			}
		}
	},
	loadMultiple: function(filenames, callback)
	{
		//alert(filenames);
		
		for (var i=0; i<filenames.length; i++)
			remmah.File.addLoadQueue(filenames[i]);
		if (callback)
			remmah.File.callbackQueue.push(callback);
	},
	load: function(filename)
	{
		var head = document.getElementsByTagName("head")[0];
		var filetype = this.getFileExtension(filename);
		if (filetype=="js"){
			var fileref=document.createElement('script');
			fileref.setAttribute("type","text/javascript");
			fileref.setAttribute("src", filename);
			fileref.setAttribute("defer", "defer");
		}
		else if (filetype=="css"){
			var fileref=document.createElement("link");
			fileref.setAttribute("rel", "stylesheet");
			fileref.setAttribute("type", "text/css");
			fileref.setAttribute("href", filename);
		}
		if (typeof fileref!="undefined")
			head.appendChild(fileref);

		return fileref;
	},
	exist: function(url)
	{
		var req= new remmah.Ajax(); // XMLHttpRequest object
		try {
			req.open("HEAD", url, false);
			req.send(null);	
			return (req.readyState == 4 && req.status == 0) ? true : false;
		}
		catch (er)
		{
			return false;
		}
	},
	getCurrentScript: function(str)
	{
		var scripts = document.getElementsByTagName("script");
		if (str)
		{
			for (var i=0; i<scripts.length; i++)
			{
				var script = scripts[i];
				if (script.src.indexOf(str) != -1)
					return scripts[i];
			}
		}
		else
		{
			return scripts[scripts.length - 1];
		}
	},
	getQueryString: function(str)
	{
		var script = remmah.File.getCurrentScript(str);
		var queryString = script.src.replace(/^[^\?]+\??/,'');
		return remmah.File.parseQueryString(queryString);
	},
	parseQueryString: function(query)
	{
		var Params = new Object ();
		if ( ! query ) return Params; // return empty object
		var Pairs = query.split(/[;&]/);
		for ( var i = 0; i < Pairs.length; i++ ) {
			var KeyVal = Pairs[i].split('=');
			if ( ! KeyVal || KeyVal.length != 2 ) continue;
			var key = unescape( KeyVal[0] );
			var val = unescape( KeyVal[1] );
			val = val.replace(/\+/g, ' ');
			Params[key] = val;
		}
		return Params;
	}
};

remmah.getScriptRoot = function(str)
{
	if (str)
	{
		return remmah.getRoot(str);
	}
	else
	{
		var self = remmah.File.getCurrentScript();
		var root = self.src.substring(0, self.src.lastIndexOf('/'));
		return root;
	}
};

remmah.getRoot = function(str)
{
	var root;
	var scripts = document.getElementsByTagName("script");
	for (var i=0; i<scripts.length; i++)
	{
		var script = scripts[i];
		if (script.src.indexOf(str) != -1)
			return script.src.substring(0, script.src.lastIndexOf('/')+1);
	}
	return root;
};

debugConsole = null;
remmah.debug = function(text)
{
	if (remmah.Debugger)
	{
		debugConsole = new remmah.Debugger(document.getElementById('debugConsole'));
	
		if (debugConsole)
			debugConsole.writeLine(text, '#f90');
		//else
		//	window.status = text;
	}
}
