/*
 Author: GuiPeng
 Email: guipeng@tomonline-inc.com
 Blog: http://guipeng.org
 Supports: $('#id'), $('.class'), $('#id .class'), $('.class .class'), $('tagname'), $('#id tagname'), $('.class tagname'), $(dom) , $(domsets), $(exp).find(exp)
*/
( function() {
	var $ = window.$ = window.$$ = function(selector) {
		return new $.fn.init(selector);
	}
	$.fn = $.prototype = {
		init : function(selector) {
			this.ret = {
		    length :0,
		    ori :null,
		    each :$.fn.each,
		    find :$.fn.find,
		    back :$.fn.back,
		    css :$.fn.css,
		    attr :$.fn.attr,
		    addClass :$.fn.addClass,
		    removeClass :$.fn.removeClass,
		    hide :$.fn.hide,
		    show :$.fn.show,
		    bind :$.fn.bind,
		    click :$.fn.click
		  }
			if (typeof selector == "string") {
				var match = $.fn.exp.exec(selector);
				if(!match) return false;
				if (match[1]) {
					this.ret[0] = document.getElementById(match[1]);
					this.ret.length = 1;
					return this.ret;
				}
				if (match[2]) {
					var elems = document.getElementsByTagName('*');
					for (var i = 0,l=elems.length; i < l; i++) {
						var cl = elems[i].className;
						if (cl==''||cl==undefined) continue;
						if (cl.indexOf(' ') == -1) {
							if (cl == match[2])
								$.fn.add(elems[i],this.ret,this.ret.length);
						} else if ($.fn.inArr(match[2], cl.split(' ')))
							$.fn.add(elems[i],this.ret,this.ret.length);
					}
					return this.ret;
				}
				if(match[3] && match[4]){
					return $('#'+match[3]).find('.'+match[4])
				}
				if(match[5]||(match[7]&&match[9])){
					if(match[5])
						var ret=document.getElementsByTagName(match[5]);
					else
						var ret=$('#'+match[7])[0].getElementsByTagName(match[9]);
					for(var i=0;i<ret.length;i++){
						this.ret[i]=ret[i];
					}
					this.ret.length=ret.length;
					return this.ret;
				}
				if(match[8]&&match[9]){
					return $('.'+match[8]).find(match[9]);
				}
				if(match[10]&&match[11]){
					return $('.'+match[10]).find('.'+match[11]);
				}
			}
			if (typeof selector == 'function')
				return $.fn.ready(selector);
			if(selector&&selector.nodeType==1||(selector&&selector[0]&&selector[0].nodeType==1&&selector.length)){
				if(selector&&selector.nodeType==1){ 
					this.ret[0]=selector;
					this.ret.length=1;
					return this.ret
				}
				if(selector.length==1){
					this.ret[0] = selector[0];
					this.ret.length = 1;
				}else if(selector.length>1){
					$.fn.multiAdd(selector,this.ret)
				}
				return this.ret;
			}
		},
		exp : /^#(\w+)$|^\.(\w+)$|^#(\w+)\s+\.(\w+)$|^(\w+)$|^(#(\w+)|\.(\w+))\s+(\w+)$|^\.(\w+)\s+\.(\w+)$/,
		ready:function(fn) {
			if (!document || !document.getElementById|| !document.getElementsByTagName || !document.body) {
					setTimeout( function() {return $.fn.ready(fn)}, 10);
				} else fn();
		},
		add:function(val,elem,i){
			if(i){
				elem[i]=val;
				elem.length=i+1;
			}else{
				elem[elem.length]=val;
				elem.length++;
			}
		},
		handleClass:function(obj){
			if(this.nodeType==1){
				return this.className.indexOf(' ')==-1?true:false;
			}
		},
		inArr:function(val, arr){
			for(var i=0,l=arr.length;i<l;i++){
				if (arr[i] === val) {
					return true;
				}
			}
		},
		delArr:function(val,arr){
			for(var i=0,l=arr.length;i<l;i++){
				if (arr[i] === val) {
					delete arr[i] ;
				}
			}
			return arr=$.fn.cleanArr(arr);
		},
		cleanArr:function(arr){
			var newarr={};
			newarr.length=0;
			for(var i=0,l=arr.length;i<l;i++){
				if(/^\s+$/.test(arr[i])||arr[i]===undefined||arr[i].length==0) continue;
				newarr[newarr.length++]=arr[i];
			}
			return newarr;
		},
		multiAdd:function(val,elems){
			for(var i=0,l=val.length;i<l;i++){
				$.fn.add(val[i],elems)
			}
		},
		find:function(sel){
			var match=$.fn.exp.exec(sel);
			var ret={length:0};
			if(match&&(match[5]||match[2])){
				this.each(function(){
					if(match[5]){
						var tags=this.getElementsByTagName(match[5]);
						$.fn.multiAdd(tags,ret)
					}
					else if (match[2]){
						var tags=this.getElementsByTagName('*');
						for(var i=0,l=tags.length;i<l;i++){
							if($.fn.inArr(match[2],tags[i].className.split(' '))){
								$.fn.add(tags[i],ret)
							}
						}
					}
				})}
			var re=$(ret);re.ori=this;
			return re;
		},
		back:function(){
			return this.ori?this.ori:this;
		},
		css:function(JSON) {
			this.each(function(){
				if (this.nodeType == 1) {
					for (x in JSON) {
						this.style[x] = JSON[x];
					}
				}
			})
			return this;
		},
		hide:function(){
			this.each(function(){
				this.style.display="none";
			})
			return this;
		},
		show:function(){
			this.each(function(){
				this.style.display="block";
			})
			return this;
		},
		addClass:function(cl){
			this.each(function(){
				if($.fn.handleClass(this))
					this.className=cl;
				else
					this.className+=' '+cl;
			})
			return this;
		},
		removeClass:function(cl){
			this.each(function(){
				 if(!cl)this.className='';
				if(cl&&$.fn.inArr(cl,this.className.split(' '))){
					var temp=$.fn.delArr(cl,this.className.split(' '));
					this.className='';
					for(var i=0,l=temp.length;i<l;i++){
							this.className+=' '+temp[i];
					}
				}
			})
			return this;
		},
		each:function(fn){
			var index=0;
			for(var i=0,l=this.length;i<l;i++){
				fn.call(this[i],index);
				index++;
			}
			return this;
		},
		attr:function(attName,val){
		if(!val||val.length==0) {
				var vals={};
				vals.length=this.length;
				this.each(function(index){
					vals[index]=this[attName];
				})
					return vals.length==1?vals[0]:vals;
			}
			else {
				this.each(function(){
					this[attName]=val;
				})
				return this;
			}
		},
		bind:function(type,fn){
			this.each(function(){
				this['on'+type]=fn;
			})
			return this;
		},
		click:function(fn){
			this.each(function(){
				this.onclick=fn;
			})
			return this;
		}
	}
})()
