// HELPER FUNCS

function fh_hasClass( obj, str )
{
	var n = obj.className;

	if(typeof(n) == 'undefined')
		return false;

	var p = n.split(" ");

	for(var i = 0; i < p.length; i++)
	{
		if(p[i] == str)
			return true;
	}
	return false;
}


// HELPER END

function f_each( func )
{
	for(var i = 0; i < this.length; i++)
		func(this[i]);

	return this;
}

function f_findInArray( str )
{
	var nodes = new Array();
	
	for(var i = 0; i < this.length; i++)
		nodes.concat(this[i].find(str));

	return f_byArray(nodes);
}

function f_hasAttr( str )
{
	var s = str.split('=', 2);

	if(s.length == 1)
		return null;

	var nodes = new Array();
	for(var i = 0; i < this.length; i++)
	{
		if(this[i][s[0]] == s[1])
			nodes.push(this[i]);
	}
	
	return f_byArray(nodes);
}

function f_find( str )
{
	if(str.substr(0, 1) == '#')
		return f_byObj(document.getElementById(str.substr(1, str.length)));

	var s = str.split('.', 2);
	var nodes;
	if(s.length == 1)
	{
		// By TagName
		nodes = new Array();
		var o = this.getElementsByTagName(s);
		for(var i = 0; i < o.length; i++)
			nodes.push(f_byObj(o[i]));
	}
	else
	{
		// By ClassName
		var tag = s[0];
		var cls = s[1];

		nodes = new Array();
		var o = this.getElementsByTagName(tag);
		for(var i = 0; i < o.length; i++)
		{
			if(fh_hasClass(o[i], cls))
				nodes.push(f_byObj(o[i]));
		}
	}
	return f_byArray( nodes );
}

function f_css( name, value )
{
	if(typeof(value) == 'undefined')
	{
		var r = this.style[name];
		if(typeof(r) == 'undefined' || (typeof(r) == 'string') && r == '')
			return 0;

		return r;
	}
	
	if(typeof(f_fn.infos.styleWrite[name]) == 'undefined')
	{
		if(typeof(value) != 'string')
			value = value + "px";
		this.style[name] = value;
	}
	else
	{
		f_fn.infos.styleWrite[name]( this, name, value );	
	}

	return this;
}

function f_append( str )
{
	var oih = this.innerHTML;
	this.innerHTML = oih + str;
	return this;
}

function f_html( str )
{
	if(typeof(str) == 'undefined')
		return this.innerHTML;

	this.innerHTML = str;
	return this;
}

function f_addClass( str )
{
	if(typeof(this.className) == 'undefined' || this.className == '')
		this.className = str;
	else
		this.className += ' '+str;

	return this;
}

function f_removeClass( str )
{
	var s   = str.split(' ');
	var cls = '';

	for(var i = 0; i < s.length; i++)
	{
		if(s[i] != str)
			cls += ' '+str
	}

	this.className = cls.substring(1, cls.length);
	return this;
}

function f_hasClass( str )
{
	return fh_hasClass( this, str );
}

function f_id( str )
{
	if(typeof(str) == 'undefined')
		return this.id;

	this.id = str;
	return this;
}

function f_attr( name, value )
{
	if(typeof(value) == 'undefined')
		return this[name];

	this[name] = value;

	return this;
}

function f_isArray()
{
	return('undefined' == typeof(this.length));
}

function f_value( n )
{
	if(typeof(n) == 'undefined')
	{
		if(this.tagName == 'INPUT')
			return this.value;
		return this.value;
	}

	this.value = n;
	return this;
}

function f_create( tag )
{
	var a = f_fn.create(tag);
	this.appendChild(a);
	return a;
}

function f_remove( obj )
{
	this.removeChild(obj);
	return this;
}

function f_byArray( obj )
{
	obj.find    = f_findInArray;
	obj.hasAttr = f_hasAttr;
	obj.each    = f_each;
	return obj;
}

function f_getParent()
{
	return $(this.parentNode);
}

function f_byObj( obj )
{
	obj.find        = f_find;
	obj.css         = f_css;
	obj.append      = f_append;
	obj.html        = f_html;
	obj.hasClass    = f_hasClass;
	obj.addClass    = f_addClass;
	obj.removeClass = f_removeClass;
	obj.ID          = f_id;
	obj.isArray     = f_isArray;
	obj.create      = f_create;
	obj.remove      = f_remove;
	obj.attr        = f_attr;
	obj.fadeIn      = e_fadeIn;
	obj.fadeOut     = e_fadeOut;
	obj.transform   = e_transform;
	obj.stop        = e_stop;
	obj.focus       = h_focus;
	obj.blur        = h_blur;
	obj.mouseover   = h_mouseover;
	obj.mouseout    = h_mouseout;
	obj.hover       = h_hover;
	obj.addEvent    = h_addEvent;
	obj.click       = h_click;
	obj.val         = f_value;
	obj.getParent   = f_getParent;
	obj.singleChar  = e_singleChar;
	return obj;
}

function f_fn( obj )
{
	var pos;

	if(typeof(obj) == 'object')
		return f_byObj( obj );
	else if((pos = obj.indexOf('#')) > -1)
	{
		var e = document.getElementById(obj.substr(pos + 1 , obj.length));
		if(e == null)
			return null;
		else if(pos == 0 || e.tagName == obj.substr(0, pos).toUpperCase())
		{
			return f_byObj(e);
		}
		else
		{
			return null;
		}
	}
	else
		return f_byObj( document ).find( obj );
}

f_fn.create = function( tagname )
{
	return f_byObj(document.createElement(tagname.toUpperCase()));
}

f_fn.ready = function( callback )
{
	if(window.addEventListener)
	{
   	// good Browsers
		window.addEventListener('load', callback, false);
	}
	else
	{
   	// IE
		this.attachEvent("onload", callback);
	}
}

f_fn.supported = function( opt )
{
	if(this.infos.detected == false)
		this.autodetect();

	return this.infos.supportlist[opt];
}

f_fn.autodetect = function()
{
	var bodyObj = $('body')[0];
	

	// Detect Rounded Corners
	this.infos.supportlist.roundedCorners = ('undefined' != typeof(bodyObj.style.borderRadius)
	                                      || 'undefined' != typeof(bodyObj.style.WebkitBorderRadius)
	                                      || 'undefined' != typeof(bodyObj.style.MozBorderRadius));
	// Detect Shadows
	this.infos.supportlist.boxShadow    = ('undefined' != typeof(bodyObj.style.boxShadow)
	                                    || 'undefined' != typeof(bodyObj.style.WebkitBoxShadow)
	                                    || 'undefined' != typeof(bodyObj.style.MozBoxShadow));

	this.infos.detected = true;
}

f_fn.browserInfos = function()
{
	if('undefined' == typeof(window.innerWidth))
	{
		return {
			width   : document.body.offsetWidth,
			height  : document.body.offsetHeight,
			yOffset : document.body.scrollTop,
			xOffset : document.body.scrollLeft
		};
	}
	else
	{
		return {
			width   : window.innerWidth,
			height  : window.innerHeight,
			yOffset : window.pageYOffset, 
			xOffset : window.pageXOffset
		};
	}
}

f_fn.infos = {
	'styleWrite'  : {
		'opacity'            : c_setOpacity,
		'zIndex'             : c_setZIndex,
		'borderRadius'       : c_setBorderRadius,
		'borderLeftRadius'   : c_setBorderRadius,
		'borderRightRadius'  : c_setBorderRadius,
		'borderBottomRadius' : c_setBorderRadius,
		'borderTopRadius'    : c_setBorderRadius
	},
	'supportlist' : {},
	'detected'    : false,
	'animfps'     : 25
};


// Style Stuff

function c_setOpacity(t, name, value)
{
	t.style.opacity = value;
	t.style.filter  = "alpha(opacity="+parseInt(value*100)+")";
}

function c_setZIndex(t, name, value)
{
	t.style.zIndex = value;
}

function c_setBorderRadius(t, name, value)
{
	if($.supported('roundedCorners'))
		t.style.borderRadius = t.style.MozBorderRadius = t.style.WebkitBorderRadius = value;
	else
	{
   
	}
}

// Effect Stuff

function eh_fader( obj )
{
	obj.animinfos.step += obj.animinfos.dir;
	if(obj.animinfos.step > obj.animinfos.steps || obj.animinfos.step < 0 )
	{
		var callback = obj.animinfos.callback;
		obj.stop();
		if(callback != null)
			callback();
	}
	else
	{
		obj.css('opacity', ''+(1.0/obj.animinfos.steps)*obj.animinfos.step);
		//alert('opacity = ' +(1.0/obj.animinfos.steps)*obj.animinfos.step + ' step = ' + obj.animinfos.step + ' steps = ' + obj.animinfos.steps);
	}
}

function e_fadeIn( duration , callback )
{
	if(typeof(callback) == 'undefined')
		callback = null;

	this.css('opacity', '0.0');
	if(this.css('display') == 'none' || this.css('display') == 0)
		this.css('display', 'block');
	this.animinfos = { "timer" : null, "step" : 0, "dir" : +1, "steps" : Math.ceil(duration/1000*$.infos.animfps), "callback" : callback};
	var obj = this;
	this.animinfos.timer = window.setInterval(function(){ eh_fader(obj); }, 1000/$.infos.animfps, this);
	return this;
}

function e_fadeOut( duration , callback )
{
	if(typeof(callback) == 'undefined')
		callback = null;
	
	this.css('opacity', '1.0');
	this.animinfos = { "timer" : null, "step" : Math.ceil(duration/1000*$.infos.animfps), "dir" : -1, "steps" : Math.ceil(duration/1000*$.infos.animfps), "callback" : callback};
	var obj = this;
	this.animinfos.timer = window.setInterval(function(){ eh_fader(obj); }, 1000/$.infos.animfps, this);
	return this;
}

function eh_transformer( obj )
{
	obj.animinfos.step += 1;
	if(obj.animinfos.step > obj.animinfos.steps)
	{
   	obj.css(obj.animinfos.value, obj.animinfos.to);
		var callback = obj.animinfos.callback;
		obj.stop();
		if(callback != null)
			callback();
	}
	else
	{
   	obj.css(obj.animinfos.value, Math.round(obj.animinfos.from + (obj.animinfos.step * obj.animinfos.stepsize)));
	}
}

function e_transform( value, from, to, duration, callback)
{
	if(typeof(callback) == 'undefined')
		callback = null;

	this.css(value, from);
	var steps = Math.ceil(duration/1000*$.infos.animfps);
	var stepsize = (to - from) / steps;
	this.animinfos = {
		"timer"    : null,
		"step"     : 0,
		"steps"    : steps,
		"value"    : value,
		"from"     : from,
		"to"       : to,
		"stepsize" : stepsize,
		"callback" : callback
	};
	var obj = this;
	this.animinfos.timer = window.setInterval(function(){ eh_transformer(obj); }, 1000/$.infos.animfps, this);
	return this;
}

function eh_singleChar( obj )
{
	obj.append(obj.animinfos.text.charAt(obj.animinfos.step++));
	if(obj.animinfos.step >= obj.animinfos.text.length)
		obj.stop();
}

function e_singleChar( txt, speed )
{
	this.animinfos = {"timer" : null, "step" : 0, "text" : txt};
   this.animinfos.timer = window.setInterval(eh_singleChar, speed, this);

	return this;
}

function e_stop()
{
	if(this.animinfos && this.animinfos.timer)
		window.clearInterval(this.animinfos.timer);
	return this;
}

// Handler Stuff

function h_focus( callback )
{
	this.addEvent('focus', callback);
	return this;
}

function h_blur( callback )
{
	this.addEvent('blur', callback);
	return this;
}

function h_mouseover( callback )
{
	this.addEvent('mouseover', callback);
	return this;
}

function h_mouseout( callback )
{
	this.addEvent('mouseout', callback);
	return this;
}

function h_hover( callbackOver, callbackOut )
{
	this.mouseover( callbackOver );
	this.mouseout( callbackOut );
	return this;
}

function h_click( callback )
{
	this.addEvent('click', callback);
	return this;
}

function h_addEvent(evName, callback)
{
	if(this.addEventListener)
	{
   	// good Browsers
		this.addEventListener(evName, callback, false);
	}
	else
	{
   	// IE
		this.attachEvent("on"+evName, callback);
	}
}

window.$ = window.FN = f_fn;

