﻿window.fast = new function() {  

    function FastObject( e ) {
		this.isNull = false; 
        e = (typeof e == "string" ? document.getElementById( e ) : e);
        if( e ) {
		    e = fast.extend( e );
		} else {
			e = new Object();
			for( var i = 0; i < pl.length; i++ ) {
				e[pl[i].n] = function(){void(0);};
			}
			this.isNull = true;
			e.isNull = true;
		}
	    return e;
    };
    var FastArray = function() {   
	    var x=[], a=arguments;
	    for(var i=0;i<a.length;i++){x.push(a[i])};
	    for(var i in this){x[i]=this[i]}; 
        return x; 
    };
    FastArray.prototype = [];
	
	var pl = new Array();
	
	this.register = function( n, func ) {
		pl.push({ n : n, func : func });
		FastObject.prototype[n] = func;
		FastArray.prototype[n] = function() {
			for( var i = 0, l = this.length; i < l; i++) {
				this[i][n].apply( this[i], arguments );
			};
			return this;
		};
	}; 
	
	this.extend = function( o ) {
		for( var i = 0; i < pl.length; i++ ) {
			o[pl[i].n] = pl[i].func;
		}
		return o;
	}
   
    var $ = function() {
		var o = null;
		var ao = null;
		
		var args = new Array();
		for( var i = 0; i < arguments.length; i++ ) {
			if( typeof arguments[i] != "string" && arguments[i].length ) {
				
				for( var j = 0; j <arguments[i].length; j++ ) {
					args.push(arguments[i][j]);
				}
				
			} else if( typeof arguments[i] == "string" ) {
				var ids = arguments[i].split(",");
				for( var j = 0; j <ids.length; j++ ) {
					args.push(ids[j]);
				}
				
			} else {
				args.push(arguments[i]);
			}
		}

		var i = args.length;
		do {
			o = new FastObject(args[i-1]);
			
			if( args.length == 1 ) {
				ao = o;
			} else {				
				ao = ao ? ao : new FastArray();
				if( !o.isNull ) {
					ao.push(o);
				}
			};
			
		} while( (--i) > 0 );
		return ao;
	};  
    window.$ = $;
   
	//Get DOM elements based on the given CSS Selector - V 1.00.A Beta
	//http://www.openjs.com/scripts/dom/css_selector/
	function getElementsBySelector() {
		var args = new Array();
		for( var i = 0; i < arguments.length; i++ ) {
			args.push(arguments[i]);
		}
	
		var all_selectors = args.join(",");
		var selected = new Array();
		if(!document.getElementsByTagName) return selected;
		all_selectors = all_selectors.replace(/\s*([^\w])\s*/g,"$1");//Remove the 'beutification' spaces
		var selectors = all_selectors.split(",");
		// Grab all of the tagName elements within current context	
		var getElements = function(context,tag) {
			if (!tag) tag = '*';
			// Get elements matching tag, filter them for class selector
			var found = new Array;
			for (var a=0,len=context.length; con=context[a],a<len; a++) {
				var eles;
				if (tag == '*') eles = con.all ? con.all : con.getElementsByTagName("*");
				else eles = con.getElementsByTagName(tag);

				for(var b=0,leng=eles.length;b<leng; b++) found.push(eles[b]);
			}
			return found;
		}

		COMMA:
		for(var i=0,len1=selectors.length; selector=selectors[i],i<len1; i++) {
			var context = new Array(document);
			var inheriters = selector.split(" ");

			SPACE:
			for(var j=0,len2=inheriters.length; element=inheriters[j],j<len2;j++) {
				//This part is to make sure that it is not part of a CSS3 Selector
				var left_bracket = element.indexOf("[");
				var right_bracket = element.indexOf("]");
				var pos = element.indexOf("#");//ID
				if(pos+1 && !(pos>left_bracket&&pos<right_bracket)) {
					var parts = element.split("#");
					var tag = parts[0];
					var id = parts[1];
					var ele = document.getElementById(id);
					if(!ele || (tag && ele.nodeName.toLowerCase() != tag)) { //Specified element not found
						continue COMMA;
					}
					context = new Array(ele);
					continue SPACE;
				}

				pos = element.indexOf(".");//Class
				if(pos+1 && !(pos>left_bracket&&pos<right_bracket)) {
					var parts = element.split('.');
					var tag = parts[0];
					var class_name = parts[1];

					var found = getElements(context,tag);
					context = new Array;
 					for (var l=0,len=found.length; fnd=found[l],l<len; l++) {
 						if(fnd.className && fnd.className.match(new RegExp('(^|\s)'+class_name+'(\s|$)'))) context.push(fnd);
 					}
					continue SPACE;
				}

				if(element.indexOf('[')+1) {//If the char '[' appears, that means it needs CSS 3 parsing
					// Code to deal with attribute selectors
					if (element.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?['"]?([^\]'"]*)['"]?\]$/)) {
						var tag = RegExp.$1;
						var attr = RegExp.$2;
						var operator = RegExp.$3;
						var value = RegExp.$4;
					}
					var found = getElements(context,tag);
					context = new Array;
					for (var l=0,len=found.length; fnd=found[l],l<len; l++) {
 						if(operator=='=' && fnd.getAttribute(attr) != value) continue;
						if(operator=='~' && !fnd.getAttribute(attr).match(new RegExp('(^|\\s)'+value+'(\\s|$)'))) continue;
						if(operator=='|' && !fnd.getAttribute(attr).match(new RegExp('^'+value+'-?'))) continue;
						if(operator=='^' && fnd.getAttribute(attr).indexOf(value)!=0) continue;
						if(operator=='$' && fnd.getAttribute(attr).lastIndexOf(value)!=(fnd.getAttribute(attr).length-value.length)) continue;
						if(operator=='*' && !(fnd.getAttribute(attr).indexOf(value)+1)) continue;
						else if(!fnd.getAttribute(attr)) continue;
						context.push(fnd);
 					}

					continue SPACE;
				}

				//Tag selectors - no class or id specified.
				var found = getElements(context,element);
				context = found;
			}
			for (var o=0,len=context.length;o<len; o++) selected.push(context[o]);
		}
		
		return selected;
	} 
	
    window.$$ = function() {
		return $(getElementsBySelector.apply(document,arguments));
	};
   
    this.register("hide", function() {
	    this.style.display = "none"; 
	    return this;
    });

    this.register("show", function() {
	    this.style.display = "block"; 
	    return this;
    });
    	
    this.register("setClass", function( cn ) {
	    this.className = cn;
	    return this;
    });
    	
    this.register("removeClass", function( cn ) {
        var l = new String(this.className).split(" ");
        if( l.indexOf(cn) > -1 ) {
            l.splice(l.indexOf(cn),1);
        };
	    this.className = l.join(" ");	    
	    return this;
    });
    	
    this.register("addClass", function( cn ) {
        var l = new String(this.className).split(" ");
        if( l.indexOf(cn) == -1 ) {
            l.push(cn);
        };
	    this.className = l.join(" ");
	    return this;
    });

    this.register("setContent", function( data ) {
	    this.innerHTML = data;
	    return this;
    });

    this.register("setOpacity", function( data ) {
	    this.style.opacity = data > 0 ? data/100 : 0;	
	    this.style.filter = "alpha(opacity="+data+")";
	    return this;
    }); 

    this.register("left", function( left ) {
        if( typeof left == "undefined" ) {
			var obj = this;
			var left = 0;
			if (obj.offsetParent) {
				do {
					left += obj.offsetLeft;
    			} while (obj = obj.offsetParent);
			};
            return left;
        } else {
            this.style.left = left + "px";
            return this;
        }
    }); 

    this.register("top", function( top ) {
        if( typeof top == "undefined" ) {
			var obj = this;
			var top = 0;
			if (obj.offsetParent) {
				do {
					top += obj.offsetTop;
    			} while (obj = obj.offsetParent);
			};
            return top;
        } else {
            this.style.top = top + "px";
            return this;
        }
    }); 

    this.register("addElement", function( element, attributes, style ) {
        element = (typeof element == "string" ? fast.createElement( element, attributes, style ) : element);
        this.appendChild(element,false);
        return element;
    }); 
   
    this.createElement = function( element, attributes, style ) {
        var e = fast.extend( document.createElement(element) );
        
        if( attributes ) {
            for( a in attributes ) {
                e[a] = attributes[a];
            };
        };
        if( style ) {
            for( s in style ) {
                e.style[s] = style[s];
            };
        };
        return e;
    };
};

if (!Array.prototype.indexOf){
	Array.prototype.indexOf = function(elt /*, from*/) {
		var len = this.length;
		var from = Number(arguments[1]) || 0;
		from = (from < 0)	
			? Math.ceil(from)
			: Math.floor(from);
		if (from < 0) {
			from += len;
		};
		for (; from < len; from++) {
			if (from in this && this[from] === elt)
				return from;
		};
		return -1;
	};
};

if( !String.prototype.trim ) {
	String.prototype.trim = function() {
		return this.replace(/^\s*/,'').replace(/\s*$/,'');
	};
};

window.fast.window = (new function() {

    this.width = function() {
        var myWidth = 0;
          if( typeof( window.innerWidth ) == 'number' ) {
            //Non-IE
            myWidth = window.innerWidth;
          } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
            //IE 6+ in 'standards compliant mode'
            myWidth = document.documentElement.clientWidth;
          } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
            //IE 4 compatible
            myWidth = document.body.clientWidth;
          }
         return myWidth; 
    };

    this.height = function() {
        var myHeight = 0;
          if( typeof( window.innerWidth ) == 'number' ) {
            //Non-IE
            myHeight = window.innerHeight;
          } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
            //IE 6+ in 'standards compliant mode'
            myHeight = document.documentElement.clientHeight;
          } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
            //IE 4 compatible
            myHeight = document.body.clientHeight;
          }
         return myHeight; 
    };

    this.scrollLeft = function() {
        var scrOfX = 0;
        if( typeof( window.pageYOffset ) == 'number' ) {
            //Netscape compliant
            scrOfX = window.pageXOffset;
        } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
            //DOM compliant
            scrOfX = document.body.scrollLeft;
        } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
            //IE6 standards compliant mode
            scrOfX = document.documentElement.scrollLeft;
        }
       return scrOfX; 
    }; 

    this.scrollTop = function() {
        var scrOfY = 0;
        if( typeof( window.pageYOffset ) == 'number' ) {
            //Netscape compliant
            scrOfY = window.pageYOffset;
        } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
            //DOM compliant
            scrOfY = document.body.scrollTop;
        } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
            //IE6 standards compliant mode
            scrOfY = document.documentElement.scrollTop;
        }
       return scrOfY; 
    }; 

});
