﻿/*KaisarCode Tools**********************************************

*@description:  KaisarCode Tools is a JavaScript toolkit with
				lots of useful features for the new wave of web
				developers. 

*@compatibility:	All major browsers, IE 6+
***************************************************************/


var kctools=function(){
	
	/* REQUEST TOOL */
	/*
	 * @title: request
	 * @description: HTTPRequest class
	 * @params: file[string] - the file URL to load
	 * @properties: 
	 * 				req= [object](read-only) the HTTPRequest Object
	 * 				method= ["GET" | "POST"] The file transfer method
	 * 				asynch= [true | false] asynchronous or not
	 * 				send= [string] A string to send to the file under
	 * 					  the POST method
	 * 				time= [number](read-only) the time spent in each 
	 * 					  file's loading state
	 * 				output= [string](read-only) the file's output string
	 * @methods:
	 * 				onstart= [function] script executed before load starts
	 * 				onstatechange= [function] script executed every time
	 * 								a load state changes
	 * 				onuninitialized= [function] script executed when
	 * 								 loading is uninitialized
	 * 				onloading= [function] script executed while loading
	 *				onloaded= [function] script executed when
	 * 						  loading is ready
	 * 				oninteractive= [function] XML files can be accessed
	 * 						       in this stage
	 * 				oncomplete= [function] script executed when loading
	 * 							is absolutely completed
	 * 				load= [function] (read-only) executes the request
	 * 								  process
	 * 									
	 *  
	*/
	this.request=function(file){
		var this_req=this;
		var kc_req=false;
		var starttime=0;
		var endtime=0;
		
		this_req.req=null;
		this_req.method="GET";
		this_req.asynch=true;
		this_req.send=null;
		this_req.time=null;
		this_req.onstart=function(){}
		this_req.onstatechange=function(){}
		this_req.onuninitialized=function(){}
		this_req.onloading=function(){}
		this_req.onloaded=function(){}
		this_req.oninteractive=function(){}
		this_req.oncomplete=function(){}
		this_req.output=null;
		this_req.XML=null;
		this_req.load=function(){
			starttime=new Date();
			starttime=starttime.getTime();
			this_req.onstart();
			this_req.req.onreadystatechange=function(){
				this_req.onstatechange();
				this_req.output=this_req.req.responseText;
				if(this_req.req.readyState==0){
					endtime=new Date();
					endtime=endtime.getTime();
					this_req.time=endtime-starttime;
					this_req.onuninitialized();
				}
				if(this_req.req.readyState==1){
					endtime=new Date();
					endtime=endtime.getTime();
					this_req.time=endtime-starttime;
					this_req.onloading();
				}
				if(this_req.req.readyState==2){
					endtime=new Date();
					endtime=endtime.getTime();
					this_req.time=endtime-starttime;
					this_req.onloaded();
				}
				if(this_req.req.readyState==3){
					endtime=new Date();
					endtime=endtime.getTime();
					this_req.time=endtime-starttime;
					this_req.oninteractive();
				}
				if(this_req.req.readyState==4){
					endtime=new Date();
					endtime=endtime.getTime();
					this_req.time=endtime-starttime;
					this_req.oncomplete();
					this_req=false;
				}
			}
			if(this_req.method.toUpperCase()=="POST"){
				kc_req.open(this_req.method,file,this_req.asynch);
				kc_req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				kc_req.send(this_req.send);
			}
			if(this_req.method.toUpperCase()=="GET"){
				kc_req.open(this_req.method,file+"?"+this_req.send,this_req.asynch);
				kc_req.send(null);
			}
		}
		
		if(window.ActiveXObject) kc_req = new ActiveXObject("Microsoft.XMLHTTP");
		if(window.XMLHttpRequest) kc_req = new XMLHttpRequest();
		
		this_req.req=kc_req;
	}
	
	
	/* PARSE XML TOOL */
	/*
	 * @title: parse XML
	 * @description: transforms a String into an XML object
	 * @params: str[string] - a String
	 * @return: xml [object] - the XML object
	*/
	this.parseXML=function(text){
		var kc_xml;
		var kc_parser;
		if(window.DOMParser){
			kc_parser=new DOMParser();
			kc_xml=kc_parser.parseFromString(text,"text/xml");
		}else{
			kc_xml=new ActiveXObject("Microsoft.XMLDOM");
			kc_xml.loadXML(text);
		}
		return kc_xml;
	}
	
	
	/* CONTENT LOAD READY TOOL */
	/*
	 * @title: ready
	 * @description: ready state for two main processes:
	 * 				 1- DOM content load complete (document.ready)
	 * 				 2- Any external file (images, videos, documents...)
	 * @params: elem [document | string | array of strings] - the element
	 * 				 or array of element URLs to analyze.
	 * 			callback [function] executed when load is completed
	*/
	this.ready=function(elem,callback){
		if(typeof(elem)!="undefined"){
			if(elem===document){
				/*Listen to document ready*/
				if(document.addEventListener){
					document.addEventListener("DOMContentLoaded",callback, false);
				}else{
					document.onreadystatechange=function(){
						if(document.readyState=="complete") callback();
					}
				}
			}else{
				/*Calculate external files loading*/
				if(typeof(elem)=="string"){/*Just one file*/
					var kc_stringreq=new this.request(elem);
					kc_stringreq.method="POST";
					kc_stringreq.oncomplete=function(){
						callback();
					}
					kc_stringreq.load();
				}else if(typeof(elem)=="object" && elem[0]){/*A group of files*/
					var kc_stringreq=new Object();
					var kc_cnt=0;
					for(var kci=0; kci<elem.length; kci++){
						kc_stringreq[kci]=new this.request(elem[kci]);
						kc_stringreq[kci].method="POST";
						kc_stringreq[kci].oncomplete=function(){
							kc_cnt++;
							if(kc_cnt==elem.length){
								callback();
							}
						}
						kc_stringreq[kci].load();
					}
				}
			}
		}else{
			return null;
		}
	}
	
	
	/* GET ELEMENT BY CLASS NAME TOOL */
	/*
	 * @title: get element by class name
	 * @description: retrieve all elements with a certain class attribute
	 * @params: className [string] the class value to search
	 * 			tagName [string] (optional) defines in which tags we
	 * 					want to search
	 * @return: tagsByClass [object] the collection of elements
	*/
	this.getElementsByClassName=function(className,tagName){
		var tag=(tagName)?tagName:"*";
		var tagsByClass=new Object();
		tagsByClass.length=0;
		var tags=document.getElementsByTagName(tag);
		for(i=0;i<tags.length;i++){
			if(tags[i].className.match(className)){
				tagsByClass[tagsByClass.length]=tags[i];
				tagsByClass.length++;
			}
		}
		return tagsByClass;
	}
	
	/* GET ELEMENT POSITION TOOL */
	/*
	 * @title: get position
	 * @description: Crossbrowser element Position on screen . Returns the
					 position (left,top) on screen of any HTML element.
	 * @params: elem [Object] - the HTML element object
				relative [Boolean] - if true returns the position
									 relative to its offsetParent;
	 * @return: elempos[Array] - x,y of the element
	 * @example: document.onclick=function(){
					return kc.getPosition(document);
				 }
	*/
	this.getPosition=function(elem,axis,relative){
		var elempos=new Array();
		try{
		/*Collecting Full Position*/
		elempos[0]=elem.offsetLeft;
		elempos[1]=elem.offsetTop;
		
		
		if(typeof(relative)=="undefined"){
			if(elem.offsetParent){
				do{
					elempos[0]+=elem.offsetLeft;
					elempos[1]+=elem.offsetTop;
				}while(elem=elem.offsetParent);
			}
		}
		
		/*Catching a possible zero mismatch*/
		if(typeof(elempos[0])=="undefined"){elempos[0]=0;}
		if(typeof(elempos[1])=="undefined"){elempos[1]=0;}
		}catch(err){
			elempos[0]=0;
			elempos[1]=0;
		}
		
		if(typeof(axis)=="undefined"){
			return elempos;
		}else{
			if(axis=="left" || axis===0){
				return elempos[0];
			}else if(axis=="top" || axis===1){
				return elempos[1];
			}
		}
	}
	
	/* GET ELEMENT SIZE TOOL */
	/*
	 * @title: get size
	 * @description: Crossbrowser elements height and width. Returns the full
					 sizes of any HTML element, with paddings and borders included.
	 * @params: elem [Object] - the HTML element object
	 * @return: elemsize [Array] - width,height of the element
	 * @example: document.onclick=function(){
					 return kc.getSize(document);
				 }
	*/
	this.getSize=function(elem,axis){
		var elemsize=new Array();
		if(elem===document){
			/*Shortcut for document Height*/
			elem=document.documentElement;
		}
		if(elem.offsetHeight){
			/*Collecting Full Sizes*/
			elemsize[0]=elem.offsetWidth;
			elemsize[1]=elem.offsetHeight;
			/*Catching a possible zero mismatch*/
			if(typeof(elemsize[0])=="undefined"){elemsize[0]=0;}
			if(typeof(elemsize[1])=="undefined"){elemsize[1]=0;}
		}
		if(typeof(axis)=="undefined"){
			return elemsize;
		}else{
			if(axis=="width" || axis===0){
				return elemsize[0];
			}else if(axis=="height" || axis===1){
				return elemsize[1];
			}
		}
	}
	
	/* GET ELEMENT SCROLL SIZE TOOL */
	/*
	 * @title: get scroll
	 * @description: Crossbrowser elements scroll height and width. Returns the full
					 scroll sizes of any HTML element.
	 * @params: elem [Object] - the HTML element object
	 * @return: elemsize [Array] - width,height of the element
	 * @example: document.onclick=function(){
					 return kc.getSize(document);
				 }
	*/
	this.getScroll=function(elem,axis){
		var elemsize=new Array();
		if(elem===document){
			/*Shortcut for document Height*/
			elem=document.documentElement;
		}
		if(elem.scrollHeight){
			/*Collecting Full Sizes*/
			elemsize[0]=elem.scrollWidth;
			elemsize[1]=elem.scrollHeight;
			/*Catching a possible zero mismatch*/
			if(typeof(elemsize[0])=="undefined"){elemsize[0]=0;}
			if(typeof(elemsize[1])=="undefined"){elemsize[1]=0;}
		}
		if(typeof(axis)=="undefined"){
			return elemsize;
		}else{
			if(axis=="width" || axis===0){
				return elemsize[0];
			}else if(axis=="height" || axis===1){
				return elemsize[1];
			}
		}
	}
	
	
	/* GET CURSOR POSITION TOOL */
	/*
	 * @title: get cursor position
	 * @description:  Crossbrowser mouse position. This
					  script must be used within a mouse event.
					  sizes of any HTML element, with paddings and
					  borders included.
	 * @params: e [event] - an event object
	 * @return: cursorPos [Array] - x,y position of the cursor
	 * @example: document.onclick=function(e){
					return kc.getCursorPos(e);
				 }
	*/
	this.getCursorPosition=function(e,axis){
		var cursorX=0;
		var cursorY=0;
		var cursorPos=new Array();
		if(document.captureEvents){
			cursorX=e.pageX;
			cursorY=e.pageY;
			if(cursorX<0) cursorX=0;
			if(cursorY<0) cursorY=0;
		}else{
			cursorX=event.clientX+document.body.scrollLeft;
			cursorY=event.clientY+document.body.scrollLeft;
		}
		cursorPos[0]=cursorX;
		cursorPos[1]=cursorY;
		
		if(typeof(axis)=="undefined"){
			return cursorPos;
		}else{
			if(axis=="x" || axis===0){
				return cursorPos[0];
			}else if(axis=="y" || axis===1){
				return cursorPos[1];
			}
		}
	}
	
	
		/* EVENT LISTENER TOOL */
	/*
	 * @title: event listener tool
	 * @description:  Crossbrowser event listener (add or remove).
	 * @params: elem [Object] - the HTML element object
				event_str [String] - event name
				callback [Function] - a function to execute on event
	 * @return: success [Boolean] - true | false
	 * @example: kc.addEventListener(document,"click",function(){
					alert("document clicked");
				});
	*/
	this.addEventListener=function(elem,event_str,callback,bubbles){
		if(document.addEventListener) {
			if(event_str=="mousewheel") elem.addEventListener("DOMMouseScroll",callback);
			elem.addEventListener(event_str,callback);
		}else{
			elem.attachEvent('on'+event_str,callback);
		}
		return true;
	}
	
	/*STYLESHEET MANIPULATION TOOL*/
	this.sheet=function(selector,value,index){
		var kc_sheetmethod=this.sheet;
		var kc_stylesheets=document.styleSheets;
		var kc_sheet={}
		
		var kccnt=0;
		
		
		for(var kci=0;kci<kc_stylesheets.length;kci++){
			kc_stylesheets[kci].index=kci;
		}
		
		/*DETECT STYLESHEET*/
		switch(typeof(selector)){
			case "undefined":
				for(var kci=0;kci<kc_stylesheets.length;kci++){
					kc_sheet[kci]=kc_stylesheets[kci];
					kccnt++;
				}
			break;
			case "number":
				kc_sheet[0]=kc_stylesheets[selector];
				kccnt++;
			break;
			case "string":
				
				/*Select Stylesheets by HREF match function*/
				function selectByAttr(kcstrict,kcattr,kcvalue,kcnum){
					var kc_parent=null;
					for(var kci=0;kci<kc_stylesheets.length;kci++){
						kc_stylesheets[kci].owningElement ? kc_parent=kc_stylesheets[kci].owningElement : kc_parent=kc_stylesheets[kci].ownerNode;
						/*Validate for attribute or href search*/
						try{
							var thisattrvalidate=false;
							if(kcstrict){
								thisattrvalidate=kc_parent.attributes[kcattr].value==kcvalue;
							}else{
								thisattrvalidate=kc_parent.attributes[kcattr].value.match(kcvalue);
							}
							if(thisattrvalidate){
								if(typeof(kcnum)=="undefined"){
									kc_sheet[kccnt]=kc_stylesheets[kci];
									kccnt++;
								}else{
									if(typeof(kcnum)=="number"){
										if(kci==kcnum){
											kc_sheet[kccnt]=kc_stylesheets[kci];
											kccnt++;
										}
									}
								}
							}
						}catch(err){}
					}
				}
				if(typeof(value)=="undefined"){
					/*Return all sheets with that selector as part of its HREF*/
					selectByAttr(false,"href",selector);
				}else{
					if(typeof(value)=="number"){
						/*Return a specific sheet with that selector as part of its HREF*/
						selectByAttr(false,"href",selector,value);
					}
					/*Select Stylesheets by Attribute/Value*/
					else if(typeof(value)=="string"){
						/*Return all sheets with that pair of attribute-value*/
						if(typeof(index)=="undefined"){
							selectByAttr(true,selector,value);
						}
						/*Return a specific sheet with that pair of attribute-value*/
						else{
							selectByAttr(true,selector,value,index);
						}
					}
				}
			break;
		}
		
		
		/*
		@title: Selected Stylesheets Length
		@description: length of all selected stylesheets
		@return: number
		*/
		kc_sheet.length=kccnt;
		
		
		/*
		@title: Stylesheets Index
		@description: return selected sheets Stack position index
		@return: object with all position numbers
		*/
		kc_sheet.index=function(index){
			var kc_index={}
			var kccnt=0;
			for(var kci=0;kci<kc_sheet.length;kci++){
				if(typeof(index)=="undefined"){
					kc_index[kccnt]=kc_sheet[kci].index;
					kccnt++;
				}else if(kc_sheet[kci].index == index){
					kc_index[kccnt]=kc_sheet[kci].index;
					kccnt++;
				}
			}
			return kc_index;
		}
		
		
		/*
		@title: Stylesheets Parent
		@description: return selected sheets Owner Node
		@return: object with HTML DOM elements
		*/
		kc_sheet.parent=function(index){
			var kc_parent={}
			var kccnt=0;
			for(var kci=0;kci<kc_sheet.length;kci++){
				if(typeof(index)=="undefined"){
					kc_sheet[kci].owningElement ? kc_parent[kccnt]=kc_sheet[kci].owningElement : kc_parent[kccnt]=kc_sheet[kci].ownerNode;
					kccnt++;
				}else if(kci==index){
					kc_sheet[kci].owningElement ? kc_parent[kccnt]=kc_sheet[kci].owningElement : kc_parent[kccnt]=kc_sheet[kci].ownerNode;
					kccnt++;
				}
			}
			return kc_parent;
		}
		
		/*
		@title: Disable/Enable Stylesheets
		@description: disable/enable selected sheets
		@params: boolean
		@return: object with boolean results
		*/
		kc_sheet.disabled=function(kc_bool){
			var kcdisable={}
			for(var kci=0;kci<kc_sheet.length;kci++){
				if(typeof(kc_bool)!="undefined"){
					if(kc_bool){
						kc_sheet[kci].disabled=true;
					}else{
						kc_sheet[kci].disabled=false;
					}
				}
				kcdisable[kci]=kc_sheet[kci].disabled;
			}
			return kcdisable;
		}
		
		/*
		@title: set CSS Rule
		@description: add a new CSS Rule
		@params: selector [string]
				 declaration
				 index [number]
		@return: the new created rules
		*/
		kc_sheet.set=function(selector,declaration,index){
			var kcrules={};
			for(var kci=0;kci<kc_sheet.length;kci++){
				if(typeof(index)=="undefined"){
					if(kc_sheet[kci].cssRules){
						index=kc_sheet[kci].cssRules.length;
					}else{
						index=kc_sheet[kci].rules.length;
					}
					var kc_auto_index=true;
				}
				if(kc_sheet[kci].cssRules){
					if(typeof(declaration)=="string"){
						kc_sheet[kci].insertRule(selector+"{"+declaration+"}",index);
					}else if(typeof(declaration)=="object"){
						var kc_newcreatedrulenum=kc_sheet[kci].insertRule(selector+"{ }",index);
						for(var kcd in declaration){
							kc_sheet[kci].cssRules[kc_newcreatedrulenum].style[kcd]=declaration[kcd];
						}
					}
				}else{
					if(typeof(declaration)=="string"){
						kc_sheet[kci].addRule(selector,declaration,index);
					}else if(typeof(declaration)=="object"){
						var kc_newcreatedrulenum=kc_sheet[kci].addRule(selector," ",index);
						for(var kcd in declaration){
							kc_sheet[kci].rules[kc_newcreatedrulenum].style[kcd]=declaration[kcd];
						}
					}
				}
				kcrules[kci]=kc_sheetmethod(kc).rule(index);
				if(typeof(kc_auto_index)!="undefined") index=false;
			}
			return kcrules;
		}
		
		/*
		@title: Stylesheets Rules
		@description: return all rules of the result stylesheets
		@params: selector [string]
				 index [number]
		@return: object with boolean results
		*/
		kc_sheet.rule=function(selector,index){
			var kcrule={}
			var kccnt=0;
			var kccnt2=0;
			var crossrules={};
			var kcselectors={};
			var kcparents={}
			var kccsstext={};
			var kcruleindex={};
			
			for(var kci=0;kci<kc_sheet.length;kci++){
				/*Crossbrowser CSS Rules call*/
				if(kc_sheet[kci].cssRules){
					crossrules=kc_sheet[kci].cssRules;
				}else{
					crossrules=kc_sheet[kci].rules;
				}
				/*Internal rule methods and properties*/
				function setRuleOptions(){
					/*Get selector text*/
					kcselectors[kccnt]=crossrules[kcr].selectorText;
					/*Parent Style Sheet*/
					kcparents[kccnt]=kc_sheet[kci];
					/*Rule CSS Text*/
					if(crossrules[kcr].cssText){
						kccsstext[kccnt]=crossrules[kcr].cssText.split("{")[1].split("}")[0].replace(/^\s+|\s+$/g, '');
					}else{
						kccsstext[kccnt]=crossrules[kcr].style.cssText.replace(/^\s+|\s+$/g, '');
					}
					/*Rule Index*/
					kcruleindex[kccnt]=kcr;
					
				}
				/*Collect CSS Rules*/
				for(var kcr=0;kcr<crossrules.length;kcr++){
					if(typeof(selector)=="undefined"){
						if(crossrules[kcr].selectorText){
							kcrule[kccnt]=crossrules[kcr];
							setRuleOptions();
							kccnt++;
						}
					}
					else if(typeof(selector)=="number"){
						if(kcr==0){
							kcrule[kccnt]=crossrules[selector];
							setRuleOptions();
							kccnt++;
						}
					}
					else if(typeof(selector)=="string"){
						if(crossrules[kcr].selectorText){
							if(crossrules[kcr].selectorText.toLowerCase().match(selector.toLowerCase())){
								if(typeof(index)=="undefined"){
									kcrule[kccnt]=crossrules[kcr];
									setRuleOptions();
									kccnt++;
								}else{
									if(kccnt2==index){
										kcrule[kccnt]=crossrules[kcr];
										setRuleOptions();
										kccnt++;
									}
									kccnt2++;
								}
							}
						}
					}
				}
			}
			
			/*
			@title: Rules Length
			@description: return the amount of selected rules
			*/
			kcrule.length=kccnt;
			
			/*
			@title: Rules Index
			@description: return the amount of selected rules
			@params: index [number]
			@return: object with index positions of the selected rules
			*/
			kcrule.index=function(index){
				if(typeof(index)=="undefined"){
					return kcruleindex;
				}else{
					return kcruleindex[index];
				}
			}
			
			/*
			@title: Rules Selector
			@description: return the selector strings of selected rules
			@params: index [number]
			@return: object with selector strings
			*/
			kcrule.selector=function(index){
				if(typeof(index)=="undefined"){
					return kcselectors;
				}else{
					return kcselectors[index];
				}
			}
			
			/*
			@title: Rules Selector
			@description: return the parent stylesheets of selected rules
			@params: index [number]
			@return: collection of stylesheets DOM objects
			*/
			kcrule.parent=function(index){
				var kcparents={};
				for(var kcr=0;kcr<kcrule.length;kcr++){
					kcparents[kcr]=kcrule[kcr].parentStyleSheet
				}
				if(typeof(index)=="undefined"){
					return kcparents;
				}else{
					return kcparents[index];
				}
			}
			
			/*
			@title: Rules CSS Text
			@description: return the CSS Text of selected rules
			@params: index [number]
			@return: object with CSS declaration strings
			*/
			kcrule.cssText=function(index){
				if(typeof(index)=="undefined"){
					return kccsstext;
				}else{
					return kccsstext[index];
				}
			}
			
			/*
			@title: Set Rule Styles
			@description: set up new declarations for the selected rules
			@params: declaration [string | object]
					 index [number]
			@return: object with the modified rules
			*/
			kcrule.set=function(declaration,index){
				var kcrules={};
				if(typeof(declaration)=="object"){
					for(var kcr=0;kcr<kcrule.length;kcr++){
						for(var kcdecl in declaration){
							if(typeof(index)=="undefined"){
								kcrule[kcr].style[kcdecl]=declaration[kcdecl];
								kcrules[kcr]=kcrule[kcr];
							}else{
								if(index==kcr){
									kcrule[kcr].style[kcdecl]=declaration[kcdecl];
									kcrules[kcr]=kcrule[kcr];
								}
							}
						}
					}
				}else if(typeof(declaration)=="string"){
					var each_decl=declaration.split(";");//we split the different declarations
					for(elem in each_decl){
						var decl_prop=each_decl[elem].split(":");//then we split each property-value pair
						var decl_left=decl_prop[0].split("-");//now, we have to transform the CSS properties names, to valid javaScript ones
						for(var ditem=0;ditem<decl_left.length;ditem++){
							if(ditem>0){
								decl_left[ditem]=decl_left[ditem].charAt(0).toUpperCase() + decl_left[ditem].slice(1);//Instead of the dash , JS uses Camel Cased CSS declarations. here, we make that change.
							}
						}
						decl_left=decl_left.join("");//Now we join all together to construct the new JS valid css property
						/* Finally, we apply the new styles */
						if(decl_prop[1]){
							for(var kcr=0;kcr<kcrule.length;kcr++){
								if(typeof(index)=="undefined"){
									kcrule[kcr].style[decl_left]=decl_prop[1];
									kcrules[kcr]=kcrule[kcr];
								}else{
									if(index==kcr){
										kcrule[kcr].style[decl_left]=decl_prop[1];
										kcrules[kcr]=kcrule[kcr];
									}
								}
							}
						}
					}
				}
				return kcrules;
			}
			
			/*
			@title: Unset Rules
			@description: removes the selected rules
			@params: index [number]
			@return: success [boolean]
			*/
			kcrule.unset=function(index){
				if(typeof(index)=="undefined"){
					var kcsheethref="";
					for(var kcr=0;kcr<kcrule.length;kcr++){
						if(kcsheethref==kcrule.parent(kcr).href){
							kcsheethref=kcrule.parent(kcr).href;
							kcrule.parent(kcr).deleteRule(kcrule.index(kcr)-1);
						}else{
							kcsheethref=kcrule.parent(kcr).href;
							kcrule.parent(kcr).deleteRule(kcrule.index(kcr));
						}
					}
					return true;
				}else{
					for(var kcr=0;kcr<kcrule.length;kcr++){
						if(kcr==index){
							kcrule.parent(kcr).deleteRule(kcrule.index(kcr));
						}
					}
					return true;
				}
			}
			
			return kcrule;
		}
		
		
		return kc_sheet;
	}
	
	
	
	
	/* DRAG ELEMENT TOOL */
	/*
	 * @title: drag element
	 * @description:  Drag any HTML element.
	 * @params: elem [Object] - the HTML element object.
				axis [String] (optional) - 'x' or 'y' - drag an element just in one direction
				bounds [Boolean] (optional) - Element can be dragged only inside its parent element
	 * @return: elem [Object] - the HTML element object
	 * @example: var elem=document.getElementById('elem');
				 kc.drag(elem);
	*/
	this.drag=function(elem,axis,bounds){
		var cursorX=0;
		var cursorY=0;
		var elemLeft=0;
		var elemTop=0;
		var elemW=0;
		var elemH=0;
		var elemWidth=0;
		var elemHeight=0;
		var moveX=0;
		var moveY=0;
		var boundX=0;
		var boundY=0;
		var posfix=new Array();
		var kc_parent=elem.parentNode;
		var parentLeft=0;
		
		var dragstatus=false;
		
		/*While dragging*/
		kc.addEventListener(document,'mousemove',function(e){
			if(dragstatus){
				
				cursorX=kc.getCursorPosition(e,0);
				cursorY=kc.getCursorPosition(e,1);
				
				elemLeft=kc.getPosition(elem,0,true);
				elemTop=kc.getPosition(elem,1,true);
				
				elemWidth=kc.getSize(elem,0);
				elemHeight=kc.getSize(elem,1);
				
				moveX=cursorX-posfix[0];
				moveY=cursorY-posfix[1];
				
				parentLeft=kc.getPosition(kc_parent,0,true);
				
				/*Drag inside bounds*/
				if(typeof(axis)=="boolean" || typeof(bounds)=="boolean"){
					if(axis===true || bounds===true){
						
						if(moveX>=boundX-elemWidth-1) {moveX=boundX-elemWidth-1};
						if(moveX<=0) {moveX=0};
						
						if(moveY>=boundY-elemHeight-1) {moveY=boundY-elemHeight-1};
						if(moveY<=0) {moveY=0};
					}
				}
				
				/*without 'axis' param, drag on x and y axis*/
				if(typeof(axis)=="undefined" || typeof(axis)=="boolean"){
					elem.style['left']=moveX+'px';
					elem.style['top']=moveY+'px';
				}
				/*You can optionally add an axis value "x,y" for the default behavior*/
				else if(axis=="x,y"){
					elem.style['left']=moveX+'px';
					elem.style['top']=moveY+'px';
				}
				/*with 'axis' param, drag on x or y*/
				else if(axis=="x"){
					elem.style['left']=moveX+'px';
				}else if(axis=="y"){
					elem.style['top']=moveY+'px';
				}
				
				
				
			}
		});
		
		/*Stop dragging*/
		kc.addEventListener(document,'mouseup',function(e){
			dragstatus=false;
		});
		
		/*Start Dragging event*/
		kc.addEventListener(elem,'mousedown',function(e){
			
			/*Dragging flag*/
			dragstatus=true;
			
			/*Posfix preserves the position of elem while dragging
			by positioning elem in relation with the mouse pointer*/
			cursorX=kc.getCursorPosition(e,0);
			cursorY=kc.getCursorPosition(e,1);
			elemLeft=kc.getPosition(elem,0,true);
			elemTop=kc.getPosition(elem,1,true);
			posfix=[cursorX-elemLeft,cursorY-elemTop];
			boundX=kc.getSize(kc_parent,0);
			boundY=kc.getSize(kc_parent,1);
			
			/*Prevent capturing images*/
			try{e.preventDefault();}catch(err){}
		});
		
		return elem;
	}
	
	
	/* HTML5 INITIALIZE TOOL */
	/*
	 * @title: HTML5 Init
	 * @description: Initializes the new HTML5 tags for Internet Explorer 8 and minors
	 * @params: tag_names[Array] (Optional) - List of elements to initialize
	 * @return: success [Boolean]
	 * @example: kc.HTML5Init();
	*/
	this.HTML5Init=function(tag_names){
		if(typeof(tag_names)=="undefined"){
			var kc_HTML5_elements=[
			"article",
			"aside",
			"audio",
			"bdi",
			"canvas",
			"command",
			"datalist",
			"details",
			"embed",
			"figcaption",
			"figure",
			"footer",
			"header",
			"hgroup",
			"keygen",
			"mark",
			"meter",
			"nav",
			"output",
			"progress",
			"rp",
			"rt",
			"ruby",
			"section",
			"source",
			"summary",
			"time",
			"track",
			"video",
			"wbr"
			];
		}else{
			var kc_HTML5_elements=tag_names;
		}
		function kcCreateElement(kc_arr){
			for(kc_elem in kc_arr){
				document.createElement(kc_arr[kc_elem]);
			}
		}
		try{kcCreateElement(kc_HTML5_elements);return true}catch(err){return false;}
	}		
}
kc=new kctools();

