/*
* Binary Solo Productions
* bSolo Library
* Copyright (c) 2009 by Binary Solo Productions
*
* Many thanks to the makers of the prototype and jQuery libraries for
* inspiration and ideas. Which in turn means, I need to thank those that
* inspired them. ;)
*/
(function() {
	var window = this,
	undefined,
	_bsolo = window.bSolo,
	_$ = window.$,
	bSolo = window.bSolo = window.$ = function(selector, context) {
		return new bSolo.fn.init(selector, context);
	};

	bSolo.fn = bSolo.prototype = {
		element : '',

		init : function( selector, context ) {
			selector = selector || document;
			var elem = (selector.nodeType) ? selector : null;
			var elemList = new Array();
			if(!elem && typeof selector === "string") {
				ch = selector.substr(0,1);
				switch(ch)
				{
					case '.':
					i = 0;
					while(e = document.getElementsByTagName('*')[i++])
					{
						match1 = selector.substr(1) + ' ';
						match2 = ' ' + selector.substr(1);
						if(e.className == selector.substr(1) ||
							e.className.match(match1) || 
							 e.className.match(match2))
						{
							elemList.push(e);
						}
					}
					break;
					case '#':
					elem = document.getElementById(selector.substr(1));
					break;
				};
			}

			if(elemList.length > 0)
			{
				i = 0;
				while(e = elemList[i])
				{
					this[i] = e;
					i++;
				};
				this.length = i + 1;
				this.element = this[0];
				this.context = selector;
				return this;
			}

			if(elem) {
				this[0] = elem;
				this.element = this[0];
				this.length = 1;
				this.context = selector;
				return this;
			}
		},

		selector : "",

		size : function() {
			return this.length;
		},

		toggle : function() {
			for(i = 0; i < this.length; i++)
			{
				element = this[i] ? this[i] : null;
				if(!element) return false;
				switch(arguments[0])
				{
					case 'appear':
					element.style.display = 'block';
					break;
					case 'hide':
					element.style.display = 'none';
					break;
					default:
					if(document.defaultView)
					{
						display = document.defaultView.getComputedStyle(element, "").getPropertyValue("display");
					}
					else
					{
						display = element.currentStyle['display'];
					}
					if(display != 'none') {
						element.style.display = 'none';
					} else {
						element.style.display = 'block';
					}
					break;
				};
			};
		},

		slide : function()
		{
			var speed			= arguments[0] ? arguments[0] : 20;
			var offsetBar		= arguments[1] ? arguments[1] : 0;
			var step			= arguments[2] ? arguments[2] : 15;
			var element			= this.element;
			var offsetTop 		= element.offsetTop;
			var offsetHeight	= element.offsetHeight;
			var sliderInterval	= false;

			// using 0 as our base, we determine whether
			// this element scrolls from the top down,
			// or from the bottom up
			//alert(offsetTop);
			if(offsetTop > 0)
			{
				var maxTop = 0;
			}
			else if (offsetTop < 0)
			{
				var maxTop = 0;
			}
			else
			{
				var maxTop = offsetBar - element.offsetHeight;
			}


			//alert(maxTop);
			if(offsetTop < 0) {
				element.setAttribute('maxTop', maxTop);
				sliderInterval = setInterval(down, speed);
			} else {
				//alert('maxtop:' + maxTop + 'offsettop: ' + offsetTop);
				var maxTop	= maxTop ? maxTop : parseInt(element.getAttribute('maxTop'));
				element.setAttribute('maxTop', offsetTop);
				if(maxTop > 0)
				{
					sliderInterval = setInterval(down, speed);
				}
				else
				{
					sliderInterval = setInterval(up, speed);
				}
			}

			function down()
			{
				if((offsetTop += step) >= maxTop) {
					//alert(maxTop);
					element.style.marginTop = maxTop + 'px';
					clearInterval(sliderInterval);
				} else {
					element.style.marginTop = offsetTop + 'px';
				}
			};

			function up()
			{
				if((offsetTop -= step) <= maxTop) {
					element.style.marginTop = maxTop + 'px';
					clearInterval(sliderInterval);
				} else {
					element.style.marginTop = offsetTop + 'px';
				}
			};

		},


		remove : function() {
			this[0].parentNode.removeChild(this[0]);
		},

		gotoSelectedHref : function() {
			for(i = 0; i < this[0].options.length; i++)
			{
				if(this[0].options[i].selected)
				{
					window.location.href = '#' + this[0].options[i].value;
				}
			};
		},

		html : function() {
			this.element.innerHTML = arguments[0];
		},
		
		prepend : function() {
			var html = this.element.innerHTML;
			this.element.innerHTML = arguments[0] + html;
		},

		getFirstElement : function() {
			return this.element.getElementsByTagName(arguments[0])[0];
		},

		duplicate: function() {
			return this.element.cloneNode(true);
			//return this[0].cloneNode(true);
		},

		fadein : function() {
			var element = this.element;
			var opacity = 10;
			var filterInterval = null;
			
			element.style.display = 'block';
			element.style.zIndex 	= '1000';
			if(!document.all)
			{
				element.style.opacity = opacity / 100;
			}
			else
			{
				element.style.filter = 'alpha(opacity=' + opacity + ')';
			}

			filterInterval = setInterval(fader, 15);
			function fader()
			{
				opacity += 4;
				if(opacity >= 100) 
				{ 
					opacity = 100; 
					clearInterval(filterInterval);					
				}
				
				if(!document.all)
				{
					element.style.opacity = opacity / 100;
				}
				else
				{
					element.style.filter = 'alpha(' + opacity + ')';
				}
				
			};
		},
		
		centerTo : function() {
			var element = this.element;
			element.style.visibility = 'hidden';
			element.style.position = 'absolute';
			element.style.display = 'block';
			var offsetTop 		= Math.round(Math.round(document.documentElement.clientHeight) - element.offsetHeight)/2;
			var offsetLeft 		= Math.round(Math.round(document.documentElement.clientWidth) - element.offsetWidth)/2;
			
	
			element.style.top 	= offsetTop + 'px';
			element.style.left 	= offsetLeft + 'px';
			element.style.visibility = 'visible';
						

			
		}

	};

})();

bSolo.fn.init.prototype = bSolo.fn;

bSolo.extend = bSolo.fn.extend = function() {
	var target = arguments[0] || {},
	i = 1,
	length = arguments.length,
	deep = false,
	options;

	if ( typeof target === "boolean" ) {
		deep = target;
		target = arguments[1] || {};
		i = 2;
	}

	if ( typeof target !== "object" && !bSolo.isFunction(target) )
	{
		target = {};
	}

	if ( length == i )
	{
		target = this;
		--i;
	}

	for ( ; i < length; i++ )
	{
		if ( (options = arguments[ i ]) != null )
		{
			for ( var name in options )
			{
				var src = target[ name ], copy = options[ name ];

				if ( target === copy )
				continue;

				if ( deep && copy && typeof copy === "object" && !copy.nodeType )
				{
					target[ name ] = bSolo.extend( deep,
					src || ( copy.length != null ? [ ] : { } )
					, copy );
				}
				else if ( copy !== undefined )
				{
					target[ name ] = copy;
				}
			};
		}
	};

	return target;
};

bSolo.extend({
	ajax: function(postURI, postData, postReturnHandler) {
		var postObj = false;
		if (window.XMLHttpRequest) {
			postObj = new XMLHttpRequest();
			if (postObj.overrideMimeType) { postObj.overrideMimeType('application/json'); }
		} else if (window.ActiveXObject) {
			postObj = new ActiveXObject('Microsoft.XMLHTTP');
		}
		postObj.open('POST', postURI, true);
		postObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		postObj.onreadystatechange = function() {
			if (postObj.readyState == 4) {
				eval(postReturnHandler + '(postObj);');
			}
		};
		postObj.send(postData);
	},

	jSON_parse : function(text) {
		text = this._utf8_decode(text);
		j = eval('(' + text + ');');
		return j;
	},

	jSON : function(request) {
		var data = this.jSON_parse(request.responseText);

		if(data.response === true)
		{
			if(typeof data.message === 'string')
			{
				alert(data.message);
			}
			if(typeof data.callback === 'string')
			{
				eval(data.callback);
			}
			if(typeof data.html === 'string')
			{
				$('#' + data.id).html($.urldecode(data.html));
				if(this.center)
				{
					var offsetTop = Math.round(Math.round(document.documentElement.clientHeight) - dlgElement.offsetHeight)/2;
					var offsetLeft = Math.round(Math.round(document.documentElement.clientWidth) - dlgElement.offsetWidth)/2;
					$('#' + data.id).element.style.top = offsetTop + 'px';
					$('#' + data.id).element.style.left = offsetLeft + 'px';
				}
				$('#' + data.id).element.style.visibility = 'visible';
			}
		}
	}
});

bSolo.extend({
	_utf8_decode : function() { // utf8_decode a string.
		var str 	= arguments[0];
		var string 	= '';
		var i		= 0;

		while(i < str.length)
		{
			c = str.charCodeAt(i);

			if(c < 128)
			{
				string += String.fromCharCode(c);
				i++;
			}
			else if ( (c > 191) && (c < 224) )
			{
				c2 = str.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else
			{
				c2 = str.charCodeAt(i+1);
				c3 = str.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		};

		return string;
	}
});

bSolo.extend({
	urldecode : function() {
		var utf8str = this._utf8_decode(arguments[0]);
		var string	= '';
		var i = 0;

		while(i < utf8str.length)
		{
			c	= utf8str.charCodeAt(i);

			if(c == 0x2b)
			{
				string += ' ';
			}
			else if (c == 0x25)
			{

				string += unescape(utf8str.substr(i,3));
				i += 2;
			}
			else
			{
				string += String.fromCharCode(c);
			}
			i++;
		};

		return string;
	},

	first : function(c, string) {
		return string.substr(0, string.indexOf(c));
	},

	rest : function(c, string) {
		return string.substr(string.indexOf(c)+1, string.length);
	}
});

/*
Dialog Box
Syntax: $.dialog(attach, 'myDialog', 'myDialogClass', '("center|top-left|top-right")|(startx,starty,width,height)' [, 'url']);

Ie: $.dialog(document.body, 'myDialog', 'myDialogClass', 'center|overlay', '/views/pages/filebrowser');
*/
bSolo.extend({
	center : '',

	close : function() {
		$('#' + arguments[0] + '_OVERLAY').remove();
		$('#' + arguments[0]).remove();
	},

	dialog : function() {
		dlgElement					= document.createElement('div');
		dlgElement.style.visibility = 'hidden';
		element						= arguments[0] ? arguments[0] : document.body;
		dlgElement.id				= arguments[1] ? arguments[1] : 'myDialog';
		dlgElement.className		= arguments[2] ? arguments[2] : 'myDialogClass';
		dlgElement.style.position 	= 'absolute';
		dlgPosition					= $.first('|', arguments[3]);
		overlay						= $.rest('|', arguments[3]);
		this.center					= false;

		switch(dlgPosition)
		{
			case "center":
			this.center = true;
			break;
			case "top-left":
			case "top-right":
			break;
			default:
			coords = arguments[3].split(',');
			dlgElement.style.left = coords[0] + 'px';
			dlgElement.style.top = coords[1] + 'px';
			dlgElement.style.width = coords[2] + 'px';
			dlgElement.style.height = coords[3] + 'px';
			break;
		};

		switch(overlay)
		{
			case "overlay":
			$.overlay(arguments[1]);
			break;
			default:break;
		};

		document.body.appendChild(dlgElement);

		if(arguments[4])
		{
			if(arguments[4].indexOf('?') > 0)
			{
				url	= $.first('?', arguments[4]);
				query = $.rest('?', arguments[4]);
			}
			else
			{
				url = arguments[4];
				query = '';
			}

			//alert('url: ' + url + ', query: ' + query);
			$.ajax(url, query, '$.jSON');
		}




	},

	overlay : function() {
		scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
		height = window.innerHeight;
		if(document.documentElement.offsetHeight > height)
		{
			height = document.documentElement.offsetHeight;
		}
		if(document.documentElement.clientHeight > height)
		{
			height = document.documentElement.clientHeight;
		}
		if(document.body.clientHeight > height)
		{
			height = document.body.clientHeight;
		}
		height += scrollTop;

//		infoStr			= 'document.body.scrollTop: ' + document.body.scrollTop +
//		'\r\nwindow.innerHeight: ' + window.innerHeight +
//		'\r\ndocument.documentElement.offsetHeight: ' + document.documentElement.offsetHeight +
//		'\r\ndocument.documentElement.clientHeight: ' + document.documentElement.clientHeight +
//		'\r\ndocument.body.clientHeight: ' + document.body.clientHeight +
//		'\r\ndocument.documentElement.scrollTop: ' + document.documentElement.scrollTop + 
//		'\r\ndocument.body.scrollHeight: ' + document.body.scrollHeight + 
//		'\r\ndocument.documentElement.scrollHeight: ' + document.documentElement.scrollHeight;
//alert(infoStr);

		overlay 					= document.createElement('div');
		overlay.id					= arguments[0] + '_OVERLAY';
		overlay.style.width 		= document.body.offsetWidth + 'px';
		overlay.style.height		= height + 'px';
		overlay.style.position		= 'absolute';
		overlay.style.left			= '0px';
		overlay.style.top			= '0px';
		overlay.style.opacity		= '.56';
		overlay.style.filter		= 'alpha(opacity=56)';
		overlay.style.background	= '#000';
		overlay.onclick				= function() {
			if($('#' + this.id.substr(0,this.id.length-8)).element)
			{
				$('#' + this.id.substr(0,this.id.length-8)).remove();
			}
			else if ($.elementToCenter)
			{
				$.elementToCenter.parentNode.removeChild($.elementToCenter);
				$.elementToCenter = '';
			}
			$('#' + this.id).remove();
		};
		document.body.appendChild(overlay);
	}				
});

