/*
window.browser   __browser
getScrollPosition __scroll_pos
__set_style  __set_style
__get_style  __get_style
_Extend  __extend
__remove
__hide 
__show 
__create_styles_copy  
__compare_styles_copy
*/

__get_scrolls_offset = function(obj, fixed){
	var dect = 0;
	var decl = 0;
	var fobj = obj;
	  if(obj.parentNode){
		do{ 
			obj = fobj;  
			if(obj.scrollTop){
				dect +=  obj.scrollTop;
				decl +=  obj.scrollLeft; 
			}
		}while(fobj = obj.parentNode);  
	}
	if(!fixed){
		var winscroll = __scroll_pos();
		decl = decl - winscroll.left;
		dect = dect - winscroll.top;
	}
	return {left:decl , top:dect };
}

__center  = function(e){ 
	var b = document.getElementsByTagName("body")[0]; 
	__absolutize(e);
	var w =  __get_style(e,'width') ; var h = __get_style(e,'height');
	var l = __get_style(e,'left') ; var t = __get_style(e,'top'); 
	var bw = __get_style(b,'width') ; var bh = __get_style(b,'height');
	var bl = __get_style(b,'left') ; var bt = __get_style(b,'top'); 
	e.style.left = ( (bl + ( bw  - w) ) / 2 ) + "px";
	e.style.top = ( (bt + ( bh  - h) ) / 2 ) + "px";
}

__message = function(message){
	if(window.mBox) __remove(window.mBox);  
	var dbody = document.getElementsByTagName("body")[0];
	var messbox = __element_from_class('w_message');
	dbody.appendChild(messbox); 
	var messinbox = __element_from_class('w_inner_message'); 
	messbox.appendChild(messinbox); 
	messbox.style.position = 'absolute';
	messbox.style.top = '0px';
	messinbox.innerHTML = message;
	__show(messinbox); __show(messbox);  
	__center(messbox); 
	messbox.style.position = 'fixed';
	messbox.style.top = '200px';
	messbox.style.opacity = 0.0;
	new wSpring(messbox , {  opacity:1.0   } , 0.5,  false);    
	window.mBox = messbox;  
	var nfnc = function(){   
		var hfnc = function(){ __hide(this) ; }; 
		new wSpring(messbox , {  opacity:0.2   } , 0.3,  __scope(this,hfnc) );   	  
	}; 
	__scope_timeout(messbox,nfnc , 1000);   
}

__loader_show = function(e) {
	e = __e(e); 
	var w = __get_style(e,'width') ; 
	var h = __get_style(e,'height'); 
	var dbody = document.getElementsByTagName("body")[0];
	var pos = __get_pos(e);
	var m = __element_from_class('w_empty'); 
	var scrl = __get_scrolls_offset(e);
	__set_style(m,'opacity', 0.5);
    m.style.top = ( pos.top - scrl.top ) +  'px'; 
    m.style.left = ( pos.left - scrl.left ) +  'px';  
    dbody.appendChild(m);
    m.style.position = 'absolute';
    __set_style(m,'width', w);
    __set_style(m,'height', h);
    var blt =  __element_from_class('w_blt');
    var blta = __element_from_class('w_blt_anim');
    __show(blta); 
    dbody.appendChild(blt); 
    blt.appendChild(blta);  
    var decalx =  (parseInt(w/2)) ;
    var decaly =  (parseInt(h/2)) ; 
    blt.style.left = pos.left + decalx -  scrl.left -  18  + 'px'; 
    blt.style.top = pos.top + decaly -  scrl.top -  42 + 'px'; 
    e.mask = m;
    m.setAttribute('id', e.id + '_mask'); 
    e.mask.blt = blt; 
    __show(blt); 
    __show(m);
}

__loader_hide = function(e) {
	e = __e(e);
	if(e.mask.blt) __remove(e.mask.blt);
	if(e.mask) __remove(e.mask);
	e.mask.blt = false;
	e.mask = false;
}

__observe_event = function(object,  eventName, callBack){   
	if(object == null) return;
		object.addEventListener ?  object.addEventListener(eventName, callBack, false) : object.attachEvent("on" + eventName, callBack);
	return function(){
		__un_observe_event(object, eventName, callBack);
	}
}
 
__un_observe_event = function(object, eventName, callBack){
	object.removeEventListener ?  object.removeEventListener(eventName, callBack, false) : object.detachEvent("on" + eventName, callBack);
}

__scope = function(scope, method){
	if(!scope) throw '__scope unknow object ! ';  
	if(!method) throw '__scope unknow method ! ';    
	var f = function(){ 
		method.apply(scope, arguments);  
	}; 
	return f; 
}

__run = function(id, callName, info){ 
	var method = callName.replace('::', '_').replace('::', '_'); 
	__e(id, callName)[method](info); 
} 

__fire = function(sender, eventName , info){ 
	if(sender == window) sender = document;   
	if(!info) info = {}; 
	if(info.event) info.precEvent = info.event;   
	if (document.createEvent) { 
		var ev = document.createEvent('HTMLEvents');
		ev.initEvent(ALIAS_EVENT, false, false);   
		ev._name = eventName; ev.info = info; ev._sender =  sender;    
		if(sender)sender.dispatchEvent(ev);     
	} else if (document.createEventObject){
		var ev = document.createEventObject();
		var evalias = 'on' + ALIAS_EVENT;  
		ev.info = info; 
		ev._name = eventName; 
		ev._sender = sender; 
		//if(! sender.fireEvent) __log(sender.id  + ' ' + eventName);    
		if(sender)sender.fireEvent(evalias, ev);
	}
}

__observe  = function(observed,eventName,scope,callfnc,info){ 
	observed = __select_object(observed); 
	eventName = eventName + '';
	if(!eventName) throw '__observe unknow eventName ! ';
	if(!callfnc) throw '__observe unknow callfnc !  for :  ' + eventName;
	if(!scope) scope = observed;  
	if(!info) info = {};
	var pp = eventName.split('::');    
	if(pp.length > 1) { 
		var handle = function(){ 
			if(observed && eventName && arguments[0]._name) { 
				//__log('___' + eventName);
				if(arguments[0]) info.event = arguments[0];
				var fargs = []; fargs[0] = info; 
				if(arguments[0]._name == eventName && arguments[0]._sender == observed) { 
					if(info.event && info.event.info)info.data = info.event.info;
					callfnc.apply(scope, fargs); 
				} 
			}
			else callfnc.apply(observed, arguments);      
		};
		return __observe_event(observed, ALIAS_EVENT , handle);	
	} else {
		var handle = function(){ 
			if(arguments[0]) info.event = arguments[0];
			var fargs = []; 
			fargs[0] = info;  
			callfnc.apply(scope, fargs);
		};
		return __observe_event(observed, eventName , handle);
	}
}; 

__select_object = function(s){
	var obj = null;
	if(s =='document' || s =='window' ) obj = document;
	else obj = __e(s);
	if(obj !=null && !obj.id) obj.id = '' + (typeof obj);
	return obj;
}

__connect = function(observed,eventName,scope, method,info){  
	observedObject = __select_object(observed); 
	scope = __select_object(scope); 
	if(!scope)  scope = observedObject;
	if(observedObject == null )  throw '__connect unknow observed ! ' + observed + ' to ' + eventName;       
	if(!info) info = {}; 
    if(method && typeof method != 'function') {   
    	method = method.replace('::', '_').replace('::', '_'); 
    	method = scope[method];
    }
	if(eventName == 'load') {  
		var arr = []; arr[0] = info;  
		handle = method.apply(scope, arr);   
	} else {
		//alert(observed  + method + eventName);  
		__observe(observed, eventName , scope,  method , info);      
	} 
    //var uid = observed.id   + eventName +  scope.id  +  method;    
}

__class('wServerOperation', { 
	initialize:function(url, sender, eventName , fncSuccess, fncAbort , postData ,  parameters){
		if(!window.requestCount) window.requestCount = 0;
		if(!url)  {
			var loader = __get_parent_by_property(sender, 'sectionUrl'); 
			url =   loader.sectionUrl;  
			if(typeof url == 'undefined') url ='' ;
		}
		if(fncSuccess) this.onSuccess = __scope(sender, fncSuccess); 
		if(fncAbort) this.onAbort = __scope(sender, fncAbort); ; 
		this.sender = sender;    
		this.method = 'POST';
		var sdata = null;
		var c =0;
		if(! postData || postData==null) {   
			this.method = 'GET'; 
			postData = null; 
		} else {
			 var sep ='';
			 sdata = '';
			 for( p in postData){
				c++;
				sdata = sdata + sep + p  + '=' +  encodeURIComponent(postData[p]); 
				sep = '&';   
			}	
		}
		if(c==0)  {
			sdata = null;
			this.method = 'GET'; 
		}
		this.sdata = sdata;
		if(!parameters) parameters =  {};
		if(this.sender.id) parameters.sender = this.sender.id;
		else parameters.sender = 'object' ;
	 	parameters.event = eventName; 
	 	parameters._wid = _wid; 
	 	
	 	if(parameters.data ){ 
	 		for( pi in  parameters.data){   
	 			var pdat = parameters.data[pi];    
	 			if( (typeof pdat) != 'object') parameters['_' + pi] = pdat; 
			}
	 	}  
	 	
	 	var sep = '?';
		for(p in parameters){  
			 if(typeof parameters[p] != 'object') {
				 url =  url + sep + encodeURIComponent(p) + '=' + encodeURIComponent(parameters[p]);
				 sep = '&'; 
			 }
		} 
		this.parameters = parameters;
		var cb = __scope(this, this.onStateChange); 
		this.url = url;   
		try { 
			if (window.XMLHttpRequest) this.http_request = new XMLHttpRequest(); 
			else if (window.ActiveXObject) this.http_request = new ActiveXObject("Microsoft.XMLHTTP");
			__fire(this.sender,'request::start',this.http_request);
			__fire(window,'request::start',this.http_request);
			window.status = "contacting server..." ;
			this.http_request.onreadystatechange = cb;
			this.http_request.open(this.method, this.url, true);   
			if(this.method == 'POST' && sdata != null){ 
				this.http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
				//this.http_request.setRequestHeader("Content-length", postData.length);
				this.http_request.setRequestHeader("Connection", "close"); 
			} else {
				this.http_request.setRequestHeader("Content-Type", "application/json;charset=utf-8");
			}
			this.http_request.send(sdata); 
			window.requestCount++;
		} catch(e) {
			if(this.onAbort)this.onAbort.call(this , this.http_request, e); 
			 alert(e.message + ' ' + this.url+ ' ' +  this.method + ' ' + this.sdata ); 
			//__log(e );  	 __log(e + this.url +  this.method + this.sdata);  
			__fire(this.sender,'request::finish',this.http_request);
			__fire(document,'request::finish',this.http_request);
			__fire(document,'request::error',this.http_request);
			if(this.onAbort)this.onAbort.call(this.sender , this.http_request); 
			window.status = "...!" ; 
			window.requestCount--;
		}
	},
	onStateChange:function(){
		 if(this.http_request.readyState == 4) {
			  window.requestCount--;
			  if(this.http_request.status == 200) { 
				  __fire(this.sender,'request::finish',this.http_request);
				  __fire(document,'request::finish',this.http_request);
				  var jsonResponse  = '';
				  try {
					 jsonResponse = eval('(' + this.http_request.responseText + ')');
					 jsonResponse.isJson = true; 
				  }catch(e){
					 jsonResponse  = this.http_request.responseText; 
					 __fire(document,'request::error',this.http_request);
					 return;
				  }
				  window.status = "" ;
 
				  if(jsonResponse.validate == false){ 
					    if(this.onAbort)this.onAbort.call(this.sender , jsonResponse , this.http_request);   
					    __fire(this.sender,'request::abort', this.http_request);   
				  } else {
					  if(this.onSuccess) { 
						  this.onSuccess.call(this.sender, jsonResponse, this.http_request); 
						  __fire(this.sender,'request::success', this.http_request);  
					  }
				  }
				  if(jsonResponse.message &&  jsonResponse.message != '') {
					  __message(jsonResponse.message);
				  } 
				  
			  }else{ 
				  if(this.onAbort)this.onAbort.call(this.sender , this.http_request); 
				  __fire(document,'request::error',this.http_request);
				  __fire(this.sender,'request::abort',this.http_request);
			  } 
			  
		  }else {
			  __fire(this.sender,'request::progress',this.http_request);
			  __fire(document,'request::progress',this.http_request);
	      }
	}
});

__class('wAnimator' , { 
	initialize:function(element ,  duration, scopeElement , endCallBack){
		if(!duration) duration = 0.1;
		this.duration = duration;
		this.element = element;
		this.scopeElement = scopeElement;
		if(endCallBack) this.endCallBack = endCallBack;
		else this.endCallBack = false;
		this.endtimer = false; 
	}, 
	step:function(ratio){
		 for(p in this.diffProps){
			key = p + '';
			 
			if(key == 'opacity' || key == 'zoom' ) {
				var startval = parseFloat(this.startStyleSet.getVal(p));
				var stopval = parseFloat(this.stopStyleSet.getVal(p));
			} else {
				var startval = parseInt(this.startStyleSet.getVal(p));
				var stopval = parseInt(this.stopStyleSet.getVal(p)); 
			}
			var val  = ((stopval - startval) * ratio) + startval;
			if(val + '' == 'NaN') continue;
			__set_style(this.element, p , val); 
	
		 }
		 	
	},
	go:function(stopStyleSet, startStyleSet){
		this.endtimer = false; 
		this.startStyleSet = startStyleSet;
		this.stopStyleSet = stopStyleSet;
		this.diffProps =  __compare_styles_copy(startStyleSet ,stopStyleSet);   
		this.start = new Date().getTime();
		this.runHandle =  __scope(this, this.run);
		this.timer = window.setTimeout( __scope(this,this.runHandle) , 30);
	}, 
	stopIn:function(set){
		window.clearTimeout(this.timer); 
	},
	stop:function(){ 
		window.clearTimeout(this.timer); 
		this.step(1); 
	},
	run:function(){
		now = new Date().getTime();
		diff = now - this.start;
		ratio = diff / (this.duration*1000);
		var endtimer = false;
		if(diff > (this.duration*1000)) {
			endtimer = true; 
			ratio = 1.0;
		}
		this.step(ratio);
		if(endtimer && this.endCallBack){ 
			__scope(this.scopeElement,this.endCallBack).apply();  
		}
		if(!endtimer)this.timer = window.setTimeout(__scope(this, this.runHandle),30);  
		this.endtimer = true; 
	}
});


__class('wSpring', { 
	initialize:function(object, props , duration , endFnc){ 
		if(!duration) duration = 0.2;
		if(endFnc) this.endFnc =  endFnc; 
		 this.element = object;
		 this.props = props;
		 this.startStyle = __create_styles_copy(this.element );
		 this.endStyle = __create_styles_copy(this.element );
		 for(p in props ) {
			  this.endStyle[p] = props[p];
		 }
		 this.animator = new wAnimator(object, 
			  duration   , this,   this.endAnimate); 
		 this.animator.go( this.endStyle, this.startStyle );
	},
	endAnimate:function(){
		if(this.endFnc) this.endFnc();
	},
	inRun:function(){
		 return this.animator.endtimer; 
	},
	stop:function(){
		this.animator.stopIn();
	},
	cancel:function(endFnc){
		if(endFnc) this.endFnc = endFnc;  
		this.animator.stopIn();
		this.endStyle =  this.startStyle;
		this.startStyle = __create_styles_copy(this.element);
		this.animator.go( this.endStyle, this.startStyle ); 
	}
	
});


__class('wMovables', {
	initialize:function(){
		this.movables = {};
		__observe(document, 'mouseup', this, this.mvup); 
		__observe(document, 'mousemove',this,  this.mvmove);
		this.isdown = false;
		this.senderElement = false;
		this.calls = [];
		this.autoScrollIsActive = false;
	},
	registerCallBack:function(fnc){
		this.calls[this.calls.length] = fnc;
	},
	execCallBacks:function(ev, context){
		for(var i=0; i < this.calls.length; i++){
			this.calls[i](ev, context); 
		}
	},
	replace:function(idHandle, idMovable){
		this.movables[idHandle] = _E(idMovable);
	},
	register:function(idHandle, idMovable){ 
		if(! idMovable ) idMovable = idHandle;  
		if(this.movables[idHandle]) this.movables[idHandle]['unobs'](); 
		this.movables[idHandle] = __e(idMovable);
		this.movables[idHandle].handle = __e(idHandle);  
		this.movables[idHandle].unobs =   
			__observe(this.movables[idHandle].handle,  'mousedown', this , this.mvdown , 
					 { sender : this.movables[idHandle].handle }    
			);	  
	},
	mvup:function(info){
		if(this.isdown == true){
			__fire(this.senderElement,'move::up',info);
			__fire( document ,'drag::up', info);
			this.execCallBacks('drag::up', info);
			this.senderElement = false;  
		}
		this.isdown = false;
	},
	clear:function(info){	
		var e;
		for(p in this.movables) {   
			e = __e(this.movables[p].handle);
		    if(e==null)this.movables[p].unobs();
		}
	},
	mvdown:function(info){	
		this.clear(); 
		if(!info) return;
		ev = info.event;
		if(window.event){ 
			 ev.returnValue = false;
			 ev.cancelBubble = true; 
			 }else{
			 ev.preventDefault();
			 ev.stopPropagation();
		}
		this.isdown = true;	
		this.senderElement = info.sender;
		__fire(this.senderElement,'move::down', info);
		this.mvhandle = this.mvmovable =  this.senderElement;
		if(this.movables[this.senderElement.id]) this.mvmovable =  this.movables[this.senderElement.id];	
		if(this.mvmovable.style.position != 'fixed')__absolutize(this.mvmovable);
		this.mvdownX =  ev.clientX;
		this.mvdownY =  ev.clientY;
		this.mvposition = __get_pos(this.mvmovable); 
		this.mvhandleposition = __get_pos(this.mvhandle);
		__fire( document ,'drag::down', info);
		this.execCallBacks('drag::down', info);
	},
	mvmove:function(info){
		ev = info.event;
		if(this.isdown == true){
			this.mvdcX =  this.mvdownX - ev.clientX;
			this.mvdcY =  this.mvdownY - ev.clientY;
			var nleft = this.mvposition.left - this.mvdcX ;
			var ntop =  this.mvposition.top  - this.mvdcY ;
			info.clientX = ev.clientX;
			info.clientY = ev.clientY; 
			if(ntop<0) ntop=0;
			__set_style(this.mvmovable,'left',nleft);
			__set_style(this.mvmovable,'top',ntop);
			__fire( document ,'drag::move', info);
			this.execCallBacks('drag::move', info);
			__fire(document ,'move::move', info);  
			this.autoScroll(nleft,ntop, ev.clientX, ev.clientY);
		}
	}, 
	autoScroll:function(nleft,ntop , x, y){
		if(!this.autoScrollIsActive)return;
		var bodyd = __get_dims(__e('body'));
		var screen = __window_dims();
		var pos = __scroll_pos();  
		var maxy = screen.height; 
		if(y <0  && pos.top > 0 ) {
			window.scrollTo( pos.left , pos.top - 20);
			this.mvdownY = this.mvdownY + 20;
		}
		if(y > maxy && ntop < bodyd.height) { 
			window.scrollTo( pos.left , pos.top + 20);
			this.mvdownY = this.mvdownY - 20;
		}
	}	
});

window.movables = new wMovables();
__register_movable = function(h, o){
	window.movables.register(h,o);
}

__observe_event(window , 'load' ,  function(){ 
     
});  







