if(typeof NW=='undefined'){NW=function(){};}

NW.Api=function(){

	var urlRE=new RegExp("^((?:http|ftp)s?:)?(?:\/\/)?([^/:]+)?(:\d*)?([^#? ]*)([\w\-]+)?(#[\w\-]+)?$"),
		// topmost window, document and user agent shortcuts
		w=top,d=w.document,u=w.navigator.userAgent.toLowerCase(),
		// get source path for currently running script
		p=d.getElementsByTagName('head')[0].lastChild.src;

	NW.window=w;
	NW.document=d;
	NW.path=p.slice(0,p.lastIndexOf('/')+1);

	// browser capabilities (dom) and agent string sniffing
	NW.browser={
		dom:w.opera?2:d.all?0:d.getElementById?1:-1,
		ver:u.match(/.+(?:rv|it|ml|ra|ie)[\/: ]([\d.]+)/)[1],
		gecko:/gecko/.test(u)?parseFloat(u.split('rv:')[1]):0,
		opera:/opera/.test(u)?parseFloat(u.split('opera ')[1]):0,
		khtml:/khtml/.test(u)?parseFloat(u.split('khtml/')[1]):0,
		safari:/webkit/.test(u)?parseFloat(u.split('webkit/')[1]):0,
		msie:/msie/.test(u)&&!w.opera?parseFloat(u.split('msie ')[1]):0
	};

	// avoid multiple reloads of css background-images in ie
	if(NW.browser.msie>=6&&d.execCommand){
		d.execCommand('BackgroundImageCache',false,true);
	}

	/********** begin public methods **********/
	return {

	// (s)cope (m)ethod
	bind:
		function(s,m){
			return(
				function(e){
					return m.call(s,e);
				}
			);
		},

	// defer function execution or form submission actions
	//@f function reference, javascript code or form element
	//@t timeout number (defaults to 50ms)
	Timed:
		function(f,m){
			return setTimeout(
				function(){
					var r=false;
					if(typeof f=='function'){
						r=f();
					}else if(typeof f=='string'){
						r=eval(f);
					}else if(f.action){
						f.submit();
					}else if(f.form){
						f.form.submit();
					}
					return f.action||f.form?false:r;
				},m||50);
		},

	TimedClear:
		function(t){
			if(t!==null){
				t=clearTimeout(t);
			}
		},

	// periodic function execution
	//@f function reference or javascript code
	//@m timeout number (defaults to 50ms)
	Periodic:
		function(f,m){
			return setInterval(
				function(){
					var r=false;
					if(typeof f=='function'){
						r=f();
					}else if(typeof f=='string'){
						r=eval(f);
					}
					return r;
				},m||50);
		},

	PeriodicClear:
		function(t){
			if(t!==null){
				t=clearInterval(t);
			}
		},

	//@k key string
	//@v value string
	//@p path string
	//@d domain string
	//@e expires string
	//@s secure boolean
	setCookie:
		function(k,v,p,d,e,s){
			NW.document.cookie=k+'='+escape(v)+
				((p)?'; path='+p:'')+
				((d)?'; domain='+d:'')+
				((e)?'; expires='+e.toGMTString():'')+
				((s)?'; secure':'');
		},

	//@k key string
	getCookie:
		function(k){
			var v=NW.document.cookie.match('(?:^|;)\\s*'+k+'=([^;]*)');
			return v?unescape(v[1]):false;
		},

	//@k key string
	//@p path string
	//@d domain string
	deleteCookie:
		function(k,p,d){
			if(NW.getCookie(k)){
				NW.document.cookie=k+'='+
					((p)?'; path='+p:'')+
					((d)?'; domain='+d:'')+
					'; expires=Thu, 01-Jan-70 00:00:01 GMT';
			}
		},

	//@p parent to append to, null to skip
	//@e element type as string (tag name)
	//@i id string assigned to element
	//@c class name assigned to element
	//@t title attribute for the element
	//@s string of text or html to embed
	addElement:
		function(p,e,i,c,t,s){
			var d,n,x;
			if(p){
				if(p.nodeType!=9){
					d=NW.Dom.getDocument(p);
				}else{
					d=p;
				}
			}else{
				d=document;
			}
			if(e){
				n=NW.createElement(d,e);
			}
			if(n){
				if(i){n.id=i;}
				if(t){n.title=t;}
				if(c){n.className=c;}
				if(p&&p.nodeType!=9){
					n=p.appendChild(n);
				}
				if(s){
					x=NW.injectElement(n,s);
				}
			}else if(s){
				// if tag name not passed we want
				// to inject a string in parent
				if(p&&p.nodeType!=9){
					x=NW.injectElement(p,s);
				}
			}
			return n;
		},

	// replace an element content with the
	// passed in text string or html code
	//@e element reference
	//@s string (text or html)
	injectElement:
		function(e,s){
			var t,d=NW.Dom.getDocument(e);
			if(/<((![-]*)|\w+)[^>]*>/.test(s)){
				// passed string is an (X|H)TML fragment
				if(!NW.browser.msie){
					var f,r;
					r=d.createRange();
					r.setStartBefore(e);
					f=r.createContextualFragment(s);
					t=NW.clearElement(e).appendChild(f);
				}else{
					e.innerHTML='';
					e.innerHTML=s;
					t=e.firstChild;
				}
			}else if(s.search(/\S/)!=-1){
				// passed string contain symbols
				t=d.createTextNode(s);
				e.appendChild(t);
			}else{
				// passed string is plain text
				t=d.createTextNode(s);
				e.appendChild(t);
			}
			return t;
		},

	// remove element contents
	//@e element to clear
	clearElement:
		function(e){
			while(e.hasChildNodes()){
				e.removeChild(e.lastChild);
			}
			return e;
		},

	// namespace aware create element
	//@d document reference
	//@e element type
	createElement:
		function(d,e){
			if(typeof d.createElementNS!='undefined'){
				return d.createElementNS('http://www.w3.org/1999/xhtml',e);
			}
			if(typeof d.createElement!='undefined'){
				return d.createElement(e);
			}
			return false;
		},

	// return child elements by tag name (t)
	// starting from element (e), * for all
	// nodes including comments/whitespaces
	getElements:
		function(e,t){
			t=t.toUpperCase();
			return t=='*'?e.getElementsByTagName('*')||e.all:e.getElementsByTagName(t)||e.all.tags(t);
		},

	// get elements by id from document
	$GI:
		function(){
			var i=0,j=0,r=[],d=NW.document,a=arguments,l=a.length;
			if(typeof a[0]=='object'){
				// document as first argument
				d=a[0];
			}else if(typeof a[l-1]=='object'){
				// document as last argument
				d=a[l-1];
			}
			for(;i<l;i++){
				if(typeof a[i]=='string'){
					r[j]=d.getElementById(a[i]);
					j++;
				}
			}
			return (r.length==1)?r[0]:r;
		},

	// get elements by class (starting at element)
	//@c class name to search for
	//@e element to start from
	//@t tag filter to apply
	$GC:
		function(s,e,t){
			e=e||NW.document;
			var i=0,j=0,r=[],p=new RegExp("(^|\\s)"+s+"(\\s|$)");
			var c=$GT(e,t||'*'),l=c.length;
			for(;i<l;i++){
				if(p.test(c[i].className)){
					r[j]=c[i];
					j++;
				}
			}
			return r;
		},

	// get elements by tag name (starting at element)
	//@e element to start from
	//@t tag name to search for
	$GT:
		function(e,t){
			e=e||document;
			return e.getElementsByTagName?e.getElementsByTagName(t||'*'):e.all?t!='*'?e.all.tags[t]:e.all:[];
		},

	// create new object element
	addObject:
		function(doc,id,cl,pv){
			// pv is an object containing name=value pairs
			// and a nested object containing value for <parm>
			var i,j,p,o=doc.createElement('object');
			if(id){o.id=id;}
			if(id){o.name=id;}
			if(cl){o.className=cl;}
			for(i in pv){
				if(typeof pv[i]=='object'){
					for(j in pv[i]){
						p=doc.createElement('param');
						p.name=j;p.value=pv[i][j];
						o.appendChild(p);
					}
				}else{
					o[i]=pv[i];
				}
			}
			return o;
		},

	// protocol://hostname:port/pathname?search#hash
	makePath:
		function(u){
			var l=this.parseUrl(/^((?:http|ftp)s?:)/.test(u)?u:'/'+u);
			return ((l.protocol||location.protocol)+'//'+
					(l.hostname||location.hostname)+
					('/'+l.pathname).replace('//','/')+
					l.hash+l.search);
		},

	parseUrl:
		function(data){
			if(data.match(urlRE)){
				return {url:RegExp['$&'],protocol:RegExp.$1,hostname:RegExp.$2,port:RegExp.$3,pathname:RegExp.$4,hash:RegExp.$5,search:RegExp.$6};
			}else{
				return {url:'',protocol:'',hostname:'',port:'',pathname:'',hash:'',search:''};
			}
		},

	cleanUrl:
		function(u){
			if(u.indexOf('?')!=-1){
				u=u.replace(/\?(.*)/,'?');
				u+=encodeURIComponent(RegExp.$1);
				u=u.replace(/%3D/g,'=');
				u=u.replace(/%26/g,'&');
			}else{
				u+='?';
			}
			// make it an uncacheable request
			u+='&'+((new Date()).getTime());
			return u;
		},

	// set selected base seek (offset) for php paging module
	setSBase:
		function(el,pos){
			var s=el.form.sbase,
				i=s.selectedIndex,
				o=s.options,l=o.length;
			if(l>0){
				var t={'first':0,'prev':o[i>0?i-1:0].value,'next':o[i<l-1?i+1:l-1].value,'last':o[l-1].value}[pos];
				if(s.value!=t){
					s.value=t;
					el.form.submit();
				}
			}
		},

	// Timer prototype
	Timer:
		function(nPauseTime){
			this._pauseTime=nPauseTime?nPauseTime:1000;
			this._timer=null;
			this._isStarted=false;
			return {
				start:
					function(){
						var t=this;
						if(this.isStarted()){
							this.stop();
						}
						this._timer=setTimeout(
							function(){
								if(typeof t.ontimer=='function'){
									t.ontimer();
								}
							},this._pauseTime
						);
						this._isStarted=false;
					},
				stop:
					function(){
						if(this._timer!==null){
							clearTimeout(this._timer);
							this._isStarted=false;
						}
					},
				setPauseTime:
					function(nPauseTime){
						this._pauseTime=nPauseTime;
					},
				getPauseTime:
					function(){
						return this._pauseTime;
					},
				isStarted:
					function(){
						return this._isStarted;
					}
			}
		}

	/********** end public methods **********/
	};

}();

NW.bind=NW.Api.bind;

NW.makePath=NW.Api.makePath;
NW.parseUrl=NW.Api.parseUrl;

NW.getCookie=NW.Api.getCookie;
NW.setCookie=NW.Api.setCookie;

NW.Timed=NW.Api.Timed;
//NW.Periodic=NW.Api.Periodic;

NW.$GI=NW.Api.$GI;
NW.$GC=NW.Api.$GC;
NW.$GT=NW.Api.$GT;

NW.addElement=NW.Api.addElement;
NW.clearElement=NW.Api.clearElement;
NW.createElement=NW.Api.createElement;
NW.injectElement=NW.Api.injectElement;

// trim leading/trailing white spaces
String.prototype.trim = function(){
	// seems faster splitting replace in two calls
	return this.replace(/^\s+/g,'').replace(/\s+$/g,'');
};
