/*
 * Tab - jQuery plugin
 * Version: 1.0 (09/17/2009)
 * Copyright (c) 2009 Digicom Corp.
 * Requires: jQuery v1.3+
*/

function _uDraggable(obj,onmove,oninitdrag,onstartdrag,onstopdrag) {
	this.par=obj;
	this.x=this.y=this.w=this.h=this.m=0;
	this.moved=false;
	this.active=false;
	this.onmove=onmove || _uDraggable.dummy;
	this.oninitdrag=oninitdrag || _uDraggable.dummy;
	this.onstartdrag=onstartdrag || _uDraggable.dummy;
	this.onstopdrag=onstopdrag || _uDraggable.dummy;
    if(!_uDraggable.globalset) {
		_uDraggable.globalset=true;
		$(document).bind("mouseup",_uDraggable.onmouseup);
		$(document).bind("mousemove",_uDraggable.onmousemove);
//		if($.browser.msie)$(document).bind("mouseout",function(e) {if(!e.relatedTarget && !e.toElement)_uWnd._dragging=null});
	}
}
_uDraggable.dummy=function(){};
_uDraggable.obj=null;
_uDraggable.clkX=0;
_uDraggable.clkY=0;
_uDraggable.scrL=0;
_uDraggable.scrT=0;
_uDraggable.globalset=false;
_uDraggable.onmousemove=function(e) {
  with(_uDraggable) {
    var o=obj;
    if(!o) return;
	if(e.which!=1) {o.stop();obj=null;return;}
	e.stopPropagation();
	e.preventDefault();
    var d=_uWnd.getdims();
	o.event=e;
	if(!o.moved && (e.clientX!=clkX || e.clientY!=clkY)) {o.onstartdrag.apply(o.par,[o.x,o.y,o.w,o.h,o.m]);o.moved=true;}

	o.onmove.apply(o.par,[e.clientX-clkX-(scrL-d.clientLeft),e.clientY-clkY-(scrT-d.clientTop),o.x,o.y,o.w,o.h,o.m]);
	o.event=null;
	return false;
  }
};
_uDraggable.onmouseup=function(e) {
    if(e.which!=1) return;
  with(_uDraggable) {
    var o=obj;
    if(!o) return;
  	if(o.moved)onmousemove(e);
	o.event=e;
  	o.stop();
  	o.event=null;
  	obj=null;
  }
};
_uDraggable.prototype={
	start: function(e,x,y,w,h,m) {
		var r=_uDraggable;
		if(r.obj) r.obj.onstopdrag.apply(r.obj.par);
		this.x=x;
		this.y=y;
		this.w=w;
		this.h=h;
		this.m=m;
		this.active=true;
		this.moved=false;
		r.obj=this;
	    //var d=_uWnd.getdims();
	    r.clkX=e.clientX;
	    r.clkY=e.clientY;
	    //r.scrL=d.clientLeft;
	    //r.scrT=d.clientTop;
	    this.oninitdrag.apply(this.par,[x,y,w,h,m]);
//window.dump("drag start\n");

	},
	stop: function() {
		var r=_uDraggable;
		if(r.obj==this) r.obj=null;
		if(this.active) {
			this.onstopdrag.apply(this.par,[this.x,this.y,this.w,this.h,this.m]);
			this.active=false;
//window.dump("drag stop \n");
		}
	}

};

function _uTabCtrl (name,ntabs,opts,titles,datas,topts) {
	this.constructor=_uTabCtrl;
	this.name=name;
	this.ntabs=ntabs;

	this.props=$.extend({
		parentnode: null, //if null, then just append child
		wnd:null, //use wnd as parent node. window must be created
		app:opts && opts.wnd && opts.wnd.app || null, //parent app and 'this' for all handlers
		width: 'auto', //outer width
		height: 'auto', //outer height
		min_height: 50, //content height
		active_tab: -1, //if 'auto' then check current url for active tab
		close: 0, //default availability of close button
		design: 'std',
		noinit: false,
		markload: '<div align="left"><div class="myWinLoad"></div></div>', //default mark load text
		emptycontent: '', //content when no active tabs
		
					
		onload: null, //(tabctrl,idx,tabid) after tab content is loaded (reloaded)for the first time (called before onshow)
		onshow: null, //(tabctrl,idx,tabid) after tab content is loaded into DOM
		onhide: null, //(tabctrl,idx,tabid) when tab looses active state (if tab was closed then this event is called after onbeforeclose if closing was allowed)
		onbeforechange: null, //(tabctrl,idx,tabid) before tab is changed to idx. if false, than ignore click
		onchange: null, //(tabctrl,idx,tabid) after tab is changed to idx. if false, than do not load tab contents
		onbeforeclose: null, //(tabctrl,idx,tabid) before tab is closed. if false, than ignore close
		onclose: null, //(idx,tabid) after tab is closed. 
		ondestroy: null, //(tabctrl,name)
		onresize: null, //(cont_width,cont_height,tabctrl,name)
		rtl:0
	},opts || {});

	this.app=this.props.app;
	this.state={init:false,destroyed:false};
    this.design=this.props.design && _uTabCtrl.designs[this.props.design] ? _uTabCtrl.designs[this.props.design] : _uTabCtrl.designs['std'];
    this.idx=_uTabCtrl.nextidx++;
    _uTabCtrl.all[this.idx]=this;
	this.width=parseInt(this.props.width) || 0; //outer width
	this.height=parseInt(this.props.height) || 0;	//outer height
	this.data=[]; 
	this.pend_show=null;
	this.decor={cdw:0,cdh:0,pdw:0,pdh:0,ph:0}; //
	this.maxid=0;
	this.wnd=null;

	this.active_tab=this.props.active_tab;
	this.scrollpos={tabswidth:0,havewidth:0,pos:null};

	for(var i=0;i<ntabs;i++) {
		var opt=(topts && topts[i]) || {};
		var id=opt.id || '';
		if(!id || id.length==0) id='_tc'+this.idx+'tb'+(this.maxid++);
		this.data[i]={
			id:id,
			title:(titles && titles[i]) || '.',
			dat:(datas && datas[i]) || '',
			cont:null,
			markloadcont:null,
			obj:null,
			ishidden: opt.hidden,
			clbut:null,
			link:null,
			href:opt.href,
			target:opt.target,
			label:null,
			close:opt.close==undefined ? this.props.close : opt.close,
			icon:opt.icon,
			markload:opt.markload,
			firstload:0,
			onload:opt.onload==undefined ? this.props.onload : opt.onload,
			onshow:opt.onshow==undefined ? this.props.onshow : opt.onshow,
			onhide:opt.onhide==undefined ? this.props.onhide : opt.onhide,
			onbeforechange:opt.onbeforechange==undefined ? this.props.onbeforechange : opt.onbeforechange,
			onchange:opt.onchange==undefined ? this.props.onchange : opt.onchange,
			onbeforeclose:opt.onbeforeclose==undefined ? this.props.onbeforeclose : opt.onbeforeclose,
			onclose:opt.onclose==undefined ? this.props.onclose : opt.onclose
			};
	}

	if(!_uTabCtrl.globalset) {
		_uTabCtrl.globalset=true;
//	    $(document).bind("mousedown",_uMENU.hideallmenus);
//	    $(window).bind("resize",_uMENU.hideallmenus);
	}
	this.butdown=new _uDraggable(this,null,null,null,function(but,tab){this.design._onbuttonup(this,but,tab);});

	if(!this.props.noinit)this.init();
}


_uTabCtrl.all=[];
_uTabCtrl.nextidx=0;
_uTabCtrl.globalset=false;

_uTabCtrl.getbyname=function(name) {
    var a=this.all;
    for(var i=0;i<a.length;i++) if(a[i] && a[i].name==name) return a[i];
    return null;
};
_uTabCtrl.closeTab=function(name,idx) {
    var w=this.getbyname(name);
    if(w) w.closeTab(idx);
}
_uTabCtrl.content=function(name,idx,c) {
    var w=this.getbyname(name);
    if(w)w.content(idx,c);
}
_uTabCtrl.setTitle=function(name,idx,t) {
    var w=this.getbyname(name);
    if(w)w.setTitle(idx,t);
}

_uTabCtrl.designs={
    std: {
//    tab_height:'25px',
	tabctrl_init: function(o) {
	    var p={};
		$(o.top).attr('class',"x-unselectable u-tabc").html(
 '<div class="u-tabc-p"><div class="u-tabc-listp"><div class="u-tabc-list"></div><div class="u-tabc-pbot"></div></div><div class="u-tabc-scrbut"><div class="u-tabc-tabl"><div class="u-tabc-label"><div class="u-tabc-scrl"></div><div class="u-tabc-scrr"></div></div></div></div></div>'
+'<div class="u-tabc-body"><div class="u-tabc-content" style="height:'+o.props.min_height+'px">'+o.props.emptycontent+'</div></div>'
			);
	    p.pane=$(o.top).find(".u-tabc-p")[0];
	    p.panebot=$(o.top).find(".u-tabc-pbot")[0];
	    p.listp=$(o.top).find(".u-tabc-listp")[0];
	    p.list=$(o.top).find(".u-tabc-list")[0];
	    p.scrbut=$(o.top).find(".u-tabc-scrbut")[0];
	    p.scrl=$(o.top).find(".u-tabc-scrl")[0];
	    p.scrr=$(o.top).find(".u-tabc-scrr")[0];
	    p.body=$(o.top).find(".u-tabc-body")[0];
	    p.emptycontent=p.content=$(o.top).find(".u-tabc-content")[0];
		$(o.top).find("div,span").andSelf().attr("unselectable","on");
		$(p.scrl).bind("click mousedown mouseover mouseout",{obj:o,but:0},_uTabCtrl._onscrbutevent);
		$(p.scrr).bind("click mousedown mouseover mouseout",{obj:o,but:1},_uTabCtrl._onscrbutevent);

	    return p;
	},
	remove_item: function(o,idx) {
		o.parts.list.removeChild(o.data[idx].obj);
	},
	set_title: function(o,idx) {
		$(o.data[idx].label).html(
			(o.data[idx].icon ? '<img class="u-tabc-icon" border="0" src="'+o.data[idx].icon+'">' : ($.browser.msie && $.browser.version<8 ? '<img class="u-tabc-spacer" src="/img/1px.gif" width="1" height="1" border="0">' : ''))
			+o.data[idx].title
		);
	},
	insert_item: function(o,idx) {
		var a=document.createElement('div');
		$(a).attr('class','u-tabc-tab'+(o.data[idx].close ? ' u-tabc-wcl':'')).html(
(o.data[idx].href ?
'<a '+(o.data[idx].target ? 'target="'+o.data[idx].target+'" ':'')+'href="'+o.data[idx].href+'" class="u-tabc-tabl" style="display:block">' :
'<div class="u-tabc-tabl">' )
			+(o.data[idx].close ? '<div class="u-tabc-closebut"></div>' : '')
			+'<div class="u-tabc-tabr"><div class="u-tabc-label">'
			+(o.data[idx].icon ? '<img class="u-tabc-icon" border="0" src="'+o.data[idx].icon+'">' : ($.browser.msie && $.browser.version<8 ? '<img class="u-tabc-spacer" src="/img/1px.gif" width="1" height="1" border="0">' : ''))
			+o.data[idx].title
			+'</div></div>'+(o.data[idx].href ? '</a>' : '</div>')
		);
		o.data[idx].obj=a;
		o.data[idx].label=$(a).find(".u-tabc-label")[0];
		o.data[idx].link=$(a).find(".u-tabc-tabl")[0];
	    if(o.data[idx].close) {
	    	o.data[idx].clbut=$(a).find(".u-tabc-closebut")[0];
			$(o.data[idx].clbut).bind("mouseover",this._onclbutmouseover).bind("mouseout",this._onclbutmouseout).bind("click",{obj:o,tab:o.data[idx]},_uTabCtrl._onclbutclick).bind("mousedown",{obj:o,tab:o.data[idx]},_uTabCtrl._onclbutdown);
	    }
		$(o.data[idx].link).bind("mouseover",this._ontabmouseover).bind("mouseout",this._ontabmouseout).bind("mousedown",{obj:o,tab:o.data[idx]},_uTabCtrl._ontabclick);
		$(a).find("div,span,a,img").andSelf().attr("unselectable","on");
		if(o.data[idx].ishidden) a.style.display='none';

		var nc=o.parts.list.childNodes.length;
//		if(o.props.rtl || window._rtl)
//			o.parts.list.insertBefore(a,nc-idx>=nc ? null : o.parts.list.childNodes[nc-idx]);
//		else
			o.parts.list.insertBefore(a,idx>=nc ? null : o.parts.list.childNodes[idx]);
	},
	_ontabmouseover: function(e) {
		$(this.parentNode).addClass("u-tabc-tab-over");
	},
	_ontabmouseout: function(e) {
		$(this.parentNode).removeClass("u-tabc-tab-over");
	},
	_onclbutmouseover: function(e) {
		$(this).addClass("u-tabc-closebut-over");
	},
	_onclbutmouseout: function(e) {
		$(this).removeClass("u-tabc-closebut-over");
	},
	_onclbutmousedown: function(b,v) {
		if(v) $(b).addClass("u-tabc-closebut-down");
			else $(b).removeClass("u-tabc-closebut-down");
	},
	_ontabactivate: function(o,idx) {
		$(o.data[idx].obj).addClass("u-tabc-tab-act");
	},
	_ontabdeactivate: function(o,idx) {
		$(o.data[idx].obj).removeClass("u-tabc-tab-act");
	},
	_onscrbutactivate: function(o,but,v) { //0-left else right
		if(v) $(!but ? o.parts.scrl : o.parts.scrr).removeClass("u-tabc-scr-dis");
			else $(!but ? o.parts.scrl : o.parts.scrr).addClass("u-tabc-scr-dis");
	},
	_onscrbutover: function(o,but,v) { //0-left else right
		var b=!but ? o.parts.scrl : o.parts.scrr;
		if(v) $(b).addClass("u-tabc-scr-over");
			else $(b).removeClass("u-tabc-scr-over");
	},
	_onscrbutdown: function(o,but,v) { //0-left else right
		var b=!but ? o.parts.scrl : o.parts.scrr;
		if(v) $(b).addClass("u-tabc-scr-down");
			else $(b).removeClass("u-tabc-scr-down");
	},
	_onbuttonup: function(o,but,tab) { //0-left scroll,1-right scroll,2-tab close
		if(but<2) this._onscrbutdown(o,but,0);
			else this._onclbutmousedown(tab.clbut,0);
	}
    }	
};
_uTabCtrl._onclbutdown=function(e) {
		if(e.which==1) {
			e.stopPropagation();
			e.data.obj.design._onclbutmousedown(e.data.tab.clbut,1);
			e.data.obj.butdown.start(e,2,e.data.tab);
		}
		_uWnd.globalmousedown();
};
_uTabCtrl._onscrbutevent=function(e) {
		var o=e.data.obj,but=e.data.but;
		if(e.type=='click' && e.which==1) o.scrollTabPane(but ? 40 : -40);
			else if(e.type=='mouseover') o.design._onscrbutover(o,but,1);
			else if(e.type=='mouseout') o.design._onscrbutover(o,but,0);
			else if(e.type=='mousedown' && e.which==1) {
				o.design._onscrbutdown(o,but,1);
				o.butdown.start(e,but);
			}
};
_uTabCtrl._onclbutclick=function(e) {
		var d=e.data,o=d.obj;
		for(var i=0;i<o.data.length;i++) 
			if(o.data[i]==d.tab) {
				if(typeof o.data[i].onbeforeclose == 'function') if(!o.data[i].onbeforeclose.call(o.app,o,i,o.data[i].id)) break;
				o.closeTab(i);
				break;
			}
		e.preventDefault();
		e.stopPropagation();
};
_uTabCtrl._ontabclick=function(e) {
		var d=e.data,o=d.obj;
		e.preventDefault();
		for(var i=0;i<o.data.length;i++)
			if(o.data[i]==e.data.tab) {
				if(i==o.active_tab) return;
				if(typeof o.data[i].onbeforechange == 'function') if(!o.data[i].onbeforechange.call(o.app,o,i,o.data[i].id)) break;
				o.activateTab(i);
				break;
			}
};

_uTabCtrl.prototype={
	init: function(noinit) {
		var t=document.createElement("div");
		t.id="_utabctrl"+this.idx;
		//if(this.props.parentnode) this.props.parentnode.appendChild(t);
		    if(this.props.parentnode) this.props.parentnode.append(t);
			else if(this.props.wnd) {
				var ww=this.props.wnd.parts.wndcont;/*
 * Tab - jQuery plugin
 * Version: 1.0 (09/17/2009)
 * Copyright (c) 2009 Digicom Corp.
 * Requires: jQuery v1.3+
*/

function _uDraggable(obj,onmove,oninitdrag,onstartdrag,onstopdrag) {
	this.par=obj;
	this.x=this.y=this.w=this.h=this.m=0;
	this.moved=false;
	this.active=false;
	this.onmove=onmove || _uDraggable.dummy;
	this.oninitdrag=oninitdrag || _uDraggable.dummy;
	this.onstartdrag=onstartdrag || _uDraggable.dummy;
	this.onstopdrag=onstopdrag || _uDraggable.dummy;
    if(!_uDraggable.globalset) {
		_uDraggable.globalset=true;
		$(document).bind("mouseup",_uDraggable.onmouseup);
		$(document).bind("mousemove",_uDraggable.onmousemove);
//		if($.browser.msie)$(document).bind("mouseout",function(e) {if(!e.relatedTarget && !e.toElement)_uWnd._dragging=null});
	}
}
_uDraggable.dummy=function(){};
_uDraggable.obj=null;
_uDraggable.clkX=0;
_uDraggable.clkY=0;
_uDraggable.scrL=0;
_uDraggable.scrT=0;
_uDraggable.globalset=false;
_uDraggable.onmousemove=function(e) {
  with(_uDraggable) {
    var o=obj;
    if(!o) return;
	if(e.which!=1) {o.stop();obj=null;return;}
	e.stopPropagation();
	e.preventDefault();
    var d=_uWnd.getdims();
	o.event=e;
	if(!o.moved && (e.clientX!=clkX || e.clientY!=clkY)) {o.onstartdrag.apply(o.par,[o.x,o.y,o.w,o.h,o.m]);o.moved=true;}

	o.onmove.apply(o.par,[e.clientX-clkX-(scrL-d.clientLeft),e.clientY-clkY-(scrT-d.clientTop),o.x,o.y,o.w,o.h,o.m]);
	o.event=null;
	return false;
  }
};
_uDraggable.onmouseup=function(e) {
    if(e.which!=1) return;
  with(_uDraggable) {
    var o=obj;
    if(!o) return;
  	if(o.moved)onmousemove(e);
	o.event=e;
  	o.stop();
  	o.event=null;
  	obj=null;
  }
};
_uDraggable.prototype={
	start: function(e,x,y,w,h,m) {
		var r=_uDraggable;
		if(r.obj) r.obj.onstopdrag.apply(r.obj.par);
		this.x=x;
		this.y=y;
		this.w=w;
		this.h=h;
		this.m=m;
		this.active=true;
		this.moved=false;
		r.obj=this;
	    //var d=_uWnd.getdims();
	    r.clkX=e.clientX;
	    r.clkY=e.clientY;
	    //r.scrL=d.clientLeft;
	    //r.scrT=d.clientTop;
	    this.oninitdrag.apply(this.par,[x,y,w,h,m]);
//window.dump("drag start\n");

	},
	stop: function() {
		var r=_uDraggable;
		if(r.obj==this) r.obj=null;
		if(this.active) {
			this.onstopdrag.apply(this.par,[this.x,this.y,this.w,this.h,this.m]);
			this.active=false;
//window.dump("drag stop \n");
		}
	}

};

function _uTabCtrl (name,ntabs,opts,titles,datas,topts) {
	this.constructor=_uTabCtrl;
	this.name=name;
	this.ntabs=ntabs;

	this.props=$.extend({
		parentnode: null, //if null, then just append child
		wnd:null, //use wnd as parent node. window must be already created
		app:opts && opts.wnd && opts.wnd.app || null, //parent app and 'this' for all handlers
		width: 'auto', //outer width
		height: 'auto', //outer height
		min_height: 50, //content height
		active_tab: -1, //if 'auto' then check current url for active tab
		close: 0, //default availability of close button
		design: 'std',
		noinit: false,
		markload: '<div align="left"><div class="myWinLoad"></div></div>', //default mark load text
		emptycontent: '', //content when no active tabs
		
					
		onload: null, //(tabctrl,idx,tabid,cont,headercont,footercont) after tab content is loaded (reloaded)for the first time (called before onshow)
		onshow: null, //(tabctrl,idx,tabid,cont,headercont,footercont) after tab content is loaded into DOM
		onhide: null, //(tabctrl,idx,tabid) when tab looses active state (if tab was closed then this event is called after onbeforeclose if closing was allowed)
		onbeforechange: null, //(tabctrl,idx,tabid) before tab is changed to idx. if false, than ignore click
		onchange: null, //(tabctrl,idx,tabid) after tab is changed to idx. if false, than do not load tab contents
		onbeforeclose: null, //(tabctrl,idx,tabid) before tab is closed. if false, than ignore close
		onclose: null, //(idx,tabid) after tab is closed. 
		ondestroy: null, //(tabctrl,name)
		onresize: null, //(cont_width,cont_height,tabctrl,name)
		rtl:0
	},opts || {});

	this.app=this.props.app;
	this.state={init:false,destroyed:false};
    this.design=this.props.design && _uTabCtrl.designs[this.props.design] ? _uTabCtrl.designs[this.props.design] : _uTabCtrl.designs['std'];
    this.idx=_uTabCtrl.nextidx++;
    _uTabCtrl.all[this.idx]=this;
	this.width=parseInt(this.props.width) || 0; //outer width
	this.height=parseInt(this.props.height) || 0;	//outer height
	this.data=[]; 
	this.pend_show=null;
	this.decor={cdw:0,cdh:0,pdw:0,pdh:0,ph:0}; //
	this.maxid=0;
	this.wnd=null;

	this.scrollpos={tabswidth:0,havewidth:0,pos:null};

	for(var i=0;i<ntabs;i++) {
		var opt=(topts && topts[i]) || {};
		var id=opt.id || '';
		if(!id || id.length==0) id='_tc'+this.idx+'tb'+(this.maxid++);
		this.data[i]={
			id:id, //id of tab. can be used anywhere instead of tab index. if not specified, then auto generated as '_tc[TCIDX]tb[INDEX]'
			title:(titles && titles[i]) || '.', 
			dat:(datas && datas[i]) || '', //tab content struct
                        footer: opt.footerc || null, //content of footer (string or html obj)
                        footerh: opt.footerh && opt.footerh>0 ? opt.footerh : 0, //height of footer block if it was specified
                        header: opt.headerc || null, //content of footer (string or html obj)
                        headerh: opt.headerh && opt.headerh>0 ? opt.headerh : 0, //height of header block if it was specified
                        footercont: null, //real footer content
                        headercont: null, //real footer content
			cont:null, //real tab content (html elem)
                        ismarkload:0, //if tab is in markload state
			markloadcont:null, //markload content obj (html elem)
			obj:null,
			ishidden: opt.hidden,
			clbut:null,
			link:null,
			href:opt.href, //is tab action is to open URL
			target:opt.target, //target for URL
			label:null,
			close:opt.close==undefined ? this.props.close : opt.close,
			icon:opt.icon,
			markload:opt.markload, //alternate markload text
			firstload:0,
			onload:opt.onload==undefined ? this.props.onload : opt.onload,
			onshow:opt.onshow==undefined ? this.props.onshow : opt.onshow,
			onhide:opt.onhide==undefined ? this.props.onhide : opt.onhide,
			onbeforechange:opt.onbeforechange==undefined ? this.props.onbeforechange : opt.onbeforechange,
			onchange:opt.onchange==undefined ? this.props.onchange : opt.onchange,
			onbeforeclose:opt.onbeforeclose==undefined ? this.props.onbeforeclose : opt.onbeforeclose,
			onclose:opt.onclose==undefined ? this.props.onclose : opt.onclose
			};
	}
	this.active_tab=this.props.active_tab=='auto' ? 'auto' : this.idxbyid(this.props.active_tab);
        this.sesupdate=0;
	if(!_uTabCtrl.globalset) {
		_uTabCtrl.globalset=true;
//	    $(document).bind("mousedown",_uMENU.hideallmenus);
//	    $(window).bind("resize",_uMENU.hideallmenus);
	}
	this.butdown=new _uDraggable(this,null,null,null,function(but,tab){this.design._onbuttonup(this,but,tab);});

	if(!this.props.noinit)this.init();
}


_uTabCtrl.all=[];
_uTabCtrl.nextidx=1;
_uTabCtrl.globalset=false;

_uTabCtrl.getbyname=function(name) {
    var a=this.all;
    for(var i=0;i<a.length;i++) if(a[i] && a[i].name==name) return a[i];
    return null;
};
_uTabCtrl.closeTab=function(name,idx) {
    var w=this.getbyname(name);
    if(w) w.closeTab(idx);
}
_uTabCtrl.content=function(name,idx,c) {
    var w=this.getbyname(name);
    if(w)w.content(idx,c);
}
_uTabCtrl.headerheight=function(name,idx,h) {
    var w=this.getbyname(name);
    if(w)w.headerheight(idx,h);
}
_uTabCtrl.footerheight=function(name,idx,h) {
    var w=this.getbyname(name);
    if(w)w.footerheight(idx,h);
}
_uTabCtrl.setTitle=function(name,idx,t) {
    var w=this.getbyname(name);
    if(w)w.setTitle(idx,t);
}

_uTabCtrl.designs={
    std: {
//    tab_height:'25px',
        content_class: 'u-tabc-content',
        header_class: 'u-tabc-header',
        footer_class: 'u-tabc-footer',
	tabctrl_init: function(o) {
	    var p={};
		$(o.top).attr('class',"x-unselectable u-tabc").html(
 '<div class="u-tabc-p"><div class="u-tabc-listp"><div class="u-tabc-list"></div><div class="u-tabc-pbot"></div></div><div class="u-tabc-scrbut"><div class="u-tabc-tabl"><div class="u-tabc-label"><div class="u-tabc-scrl"></div><div class="u-tabc-scrr"></div></div></div></div></div>'
+'<div class="u-tabc-body"><div class="u-tabc-content" style="height:'+o.props.min_height+'px">'+o.props.emptycontent+'</div></div>'
			);
	    p.pane=$(o.top).find(".u-tabc-p")[0];
	    p.panebot=$(o.top).find(".u-tabc-pbot")[0];
	    p.listp=$(o.top).find(".u-tabc-listp")[0];
	    p.list=$(o.top).find(".u-tabc-list")[0];
	    p.scrbut=$(o.top).find(".u-tabc-scrbut")[0];
	    p.scrl=$(o.top).find(".u-tabc-scrl")[0];
	    p.scrr=$(o.top).find(".u-tabc-scrr")[0];
	    p.body=$(o.top).find(".u-tabc-body")[0];
	    p.emptycontent=p.content=$(o.top).find(".u-tabc-content")[0];
	    $(o.top).find("div,span").andSelf().attr("unselectable","on");
	    $(p.scrl).bind("click mousedown mouseover mouseout",{obj:o,but:0},_uTabCtrl._onscrbutevent);
	    $(p.scrr).bind("click mousedown mouseover mouseout",{obj:o,but:1},_uTabCtrl._onscrbutevent);

	    return p;
	},
	remove_item: function(o,idx) {
		o.parts.list.removeChild(o.data[idx].obj);
	},
	set_title: function(o,idx) {
		$(o.data[idx].label).html(
			(o.data[idx].icon ? '<img class="u-tabc-icon" border="0" src="'+o.data[idx].icon+'">' : ($.browser.msie && $.browser.version<8 ? '<img class="u-tabc-spacer" src="/img/1px.gif" width="1" height="1" border="0">' : ''))
			+o.data[idx].title
		);
	},
	insert_item: function(o,idx) {
		var a=document.createElement('div');
		$(a).attr('class','u-tabc-tab'+(o.data[idx].close ? ' u-tabc-wcl':'')).html(
(o.data[idx].href ?
'<a '+(o.data[idx].target ? 'target="'+o.data[idx].target+'" ':'')+'href="'+o.data[idx].href+'" class="u-tabc-tabl" style="display:block">' :
'<div class="u-tabc-tabl">' )
			+(o.data[idx].close ? '<div class="u-tabc-closebut"></div>' : '')
			+'<div class="u-tabc-tabr"><div class="u-tabc-label">'
			+(o.data[idx].icon ? '<img class="u-tabc-icon" border="0" src="'+o.data[idx].icon+'">' : ($.browser.msie && $.browser.version<8 ? '<img class="u-tabc-spacer" src="/img/1px.gif" width="1" height="1" border="0">' : ''))
			+o.data[idx].title
			+'</div></div>'+(o.data[idx].href ? '</a>' : '</div>')
		);
		o.data[idx].obj=a;
		o.data[idx].label=$(a).find(".u-tabc-label")[0];
		o.data[idx].link=$(a).find(".u-tabc-tabl")[0];
	    if(o.data[idx].close) {
	    	o.data[idx].clbut=$(a).find(".u-tabc-closebut")[0];
			$(o.data[idx].clbut).bind("mouseover",this._onclbutmouseover).bind("mouseout",this._onclbutmouseout).bind("click",{obj:o,tab:o.data[idx]},_uTabCtrl._onclbutclick).bind("mousedown",{obj:o,tab:o.data[idx]},_uTabCtrl._onclbutdown);
	    }
		$(o.data[idx].link).bind("mouseover",this._ontabmouseover).bind("mouseout",this._ontabmouseout).bind("mousedown",{obj:o,tab:o.data[idx]},_uTabCtrl._ontabclick);
		$(a).find("div,span,a,img").andSelf().attr("unselectable","on");
		if(o.data[idx].ishidden) a.style.display='none';

		var nc=o.parts.list.childNodes.length;
//		if(o.props.rtl || window._rtl)
//			o.parts.list.insertBefore(a,nc-idx>=nc ? null : o.parts.list.childNodes[nc-idx]);
//		else
			o.parts.list.insertBefore(a,idx>=nc ? null : o.parts.list.childNodes[idx]);
	},
	_ontabmouseover: function(e) {
		$(this.parentNode).addClass("u-tabc-tab-over");
	},
	_ontabmouseout: function(e) {
		$(this.parentNode).removeClass("u-tabc-tab-over");
	},
	_onclbutmouseover: function(e) {
		$(this).addClass("u-tabc-closebut-over");
	},
	_onclbutmouseout: function(e) {
		$(this).removeClass("u-tabc-closebut-over");
	},
	_onclbutmousedown: function(b,v) {
		if(v) $(b).addClass("u-tabc-closebut-down");
			else $(b).removeClass("u-tabc-closebut-down");
	},
	_ontabactivate: function(o,idx) {
		$(o.data[idx].obj).addClass("u-tabc-tab-act");
	},
	_ontabdeactivate: function(o,idx) {
		$(o.data[idx].obj).removeClass("u-tabc-tab-act");
	},
	_onscrbutactivate: function(o,but,v) { //0-left else right
		if(v) $(!but ? o.parts.scrl : o.parts.scrr).removeClass("u-tabc-scr-dis");
			else $(!but ? o.parts.scrl : o.parts.scrr).addClass("u-tabc-scr-dis");
	},
	_onscrbutover: function(o,but,v) { //0-left else right
		var b=!but ? o.parts.scrl : o.parts.scrr;
		if(v) $(b).addClass("u-tabc-scr-over");
			else $(b).removeClass("u-tabc-scr-over");
	},
	_onscrbutdown: function(o,but,v) { //0-left else right
		var b=!but ? o.parts.scrl : o.parts.scrr;
		if(v) $(b).addClass("u-tabc-scr-down");
			else $(b).removeClass("u-tabc-scr-down");
	},
	_onbuttonup: function(o,but,tab) { //0-left scroll,1-right scroll,2-tab close
		if(but<2) this._onscrbutdown(o,but,0);
			else this._onclbutmousedown(tab.clbut,0);
	}
    }	
};
_uTabCtrl._onclbutdown=function(e) {
		if(e.which==1) {
			e.stopPropagation();
			e.data.obj.design._onclbutmousedown(e.data.tab.clbut,1);
			e.data.obj.butdown.start(e,2,e.data.tab);
		}
		_uWnd.globalmousedown();
};
_uTabCtrl._onscrbutevent=function(e) {
		var o=e.data.obj,but=e.data.but;
		if(e.type=='click' && e.which==1) o.scrollTabPane(but ? 40 : -40);
			else if(e.type=='mouseover') o.design._onscrbutover(o,but,1);
			else if(e.type=='mouseout') o.design._onscrbutover(o,but,0);
			else if(e.type=='mousedown' && e.which==1) {
				o.design._onscrbutdown(o,but,1);
				o.butdown.start(e,but);
			}
};
_uTabCtrl._onclbutclick=function(e) {
		var d=e.data,o=d.obj;
		for(var i=0;i<o.data.length;i++) 
			if(o.data[i]==d.tab) {
				if(typeof o.data[i].onbeforeclose == 'function') if(!o.data[i].onbeforeclose.call(o.app,o,i,o.data[i].id)) break;
				o.closeTab(i);
				break;
			}
		e.preventDefault();
		e.stopPropagation();
};
_uTabCtrl._ontabclick=function(e) {
		var d=e.data,o=d.obj;
		e.preventDefault();
		for(var i=0;i<o.data.length;i++)
			if(o.data[i]==e.data.tab) {
				if(i==o.active_tab) return;
				if(typeof o.data[i].onbeforechange == 'function') if(!o.data[i].onbeforechange.call(o.app,o,i,o.data[i].id)) break;
				o.activateTab(i);
				break;
			}
};

_uTabCtrl.prototype={
        saveSession: function() {
            this.sesupdate=0;
            return {tab: this.active_tab };
        },
	init: function(noinit) {
		var t=document.createElement("div");
		t.id="_utabctrl"+this.idx;
		if(this.props.parentnode) this.props.parentnode.appendChild(t);
		if(this.props.parentnode) this.props.parentnode.append(t);
			else if(this.props.wnd) {
				var ww=this.props.wnd.parts.wndcont;
				while(ww.firstChild) ww.removeChild(ww.firstChild);
				ww.appendChild(t);
				this.wnd=this.props.wnd;
				this.wnd.tabctrl=this;
				this.wnd.state.loaded=true;
				}
			else $($("body")[0]).append(t);

		this.top=t;
	        $(t).css({visibility:'hidden',display:'block'});
		if(this.width>0) $(t).css('width',this.width+'px');
//		if(this.height>0) $(t).css('height',this.height+'px');

	    this.parts=this.design.tabctrl_init(this);
	    this.parts.markloadcont=null;
            this.parts.headercontent=null;
            this.parts.footercontent=null;
		this.show();
		if(!noinit)setTimeout("var m=_uTabCtrl.all["+this.idx+"];if(m)m.init1();",10);
	},
	init1: function(noresize) { //noresize used internally by windows
//calculate decor
		var p=this.parts,d=this.decor;
		if(!(this.width>0)) this.width=this.top.offsetWidth;
		if(!(this.height>0)) this.height=this.top.offsetHeight;
		d.cdw=this.top.offsetWidth-p.content.offsetWidth; //content decor w
		d.cdh=this.top.offsetHeight-p.content.offsetHeight; //content decor h
		d.pdw=this.top.offsetWidth-p.listp.offsetWidth; //panelist decor w
                d.hh=0; //active tab header height
                d.fh=0; //active tab footer height
		if(!this.props.wnd && !noresize) {
			$(this.top).css('height',this.height+'px');
			$(p.content).css({width:(this.top.offsetWidth-d.cdw)+'px',height:(this.top.offsetHeight-d.cdh)+'px'});
			$(p.listp).css({width:(this.top.offsetWidth-d.pdw)+'px'});
		}

		$(p.listp).css({overflow:'hidden'});
		$(p.panebot).css('width','4000px');
		$(p.list).css('width','4000px');
		for(var i=0;i<this.ntabs;i++)
			this.design.insert_item(this,i);
		if(this.props.wnd)
			this.resizeTo(this.props.wnd.width-this.props.wnd.decor.w,this.props.wnd.height-this.props.wnd.decor.h);
		this.state.init=true;
		var at=this.active_tab;
		this.active_tab=-1;
		if(at=='auto')
			if(this.name && this.name.length>0 && self.location.hash.length>1) {
				var u=self.location.hash.substr(1).split(';');
				var s='T_'+this.name+'=';
				for(var ui=0;ui<u.length;ui++)
					if(u[ui].length>s.length && u[ui].substr(0,s.length)==s) {
						var tb=this.idxbyid(u[ui].substr(s.length));
						if(tb>=0 && tb<this.data.length) {at=tb;break;}
					}
			} else at=-1;
	    $(this.top).css("display",'block').css("visibility",'');
	    if(at==-1 && this.data.length>0) at=0;
	    if(at>=0 && at<this.ntabs) {
			for(var i=0;i<this.ntabs;i++) {
				var j=(at+i)%this.ntabs;
				if(!this.data[j].ishidden && (!this.data[j].onbeforechange || !!this.data[j].onbeforechange(this,j,this.data[j].id))) {
					this.activateTab(j,true);
					break;
				}
			}
		} else this.activateTab(-1,true);

	    $(this.top).css("display",'none').css("visibility",'');
	    if(pend_show) this.show(pend_show[0]);
	    if(this.props.wnd) this.props.wnd.onexternalload(); //activate autosize 
	},
	scrollTabPane: function(dx) { //>0 - right
		var pos=this.scrollpos.pos+=dx;
		var w=this.scrollpos.tabswidth,havew=this.scrollpos.havewidth;
		if(w<havew) {
			this.design._onscrbutactivate(this,0,0);
			this.design._onscrbutactivate(this,1,0);
			if((this.props.rtl || window._rtl) && this.data.length>0) {
				pos=this.data[this.data.length-1].obj.offsetLeft+havew-w;
			} else pos=0;
			this.scrollpos.pos=pos;
			this.parts.listp.scrollLeft=pos;
		} else {
			if(this.props.rtl || window._rtl) {
				var ol=this.data[this.data.length-1].obj.offsetLeft;
				if(pos<ol) pos=ol;
					else if(pos>ol+w-havew) pos=ol+w-havew;
			} else if(pos<0) pos=0;
					else if(pos>w-havew) pos=w-havew;
			this.scrollpos.pos=pos;
			this.parts.listp.scrollLeft=pos;
			if(pos>0) this.design._onscrbutactivate(this,0,1);
				else this.design._onscrbutactivate(this,0,0);
			if(pos<w-havew) this.design._onscrbutactivate(this,1,1);
				else this.design._onscrbutactivate(this,1,0);
		}
	},
	_setscrolls: function() { //set scroll buttons status according to tab widths
                if(!this.state.init) return;
		var w=0,havew=this.parts.listp.offsetWidth;
		if(this.parts.listp.clientWidth>0 && this.parts.listp.clientWidth<havew) havew=this.parts.listp.clientWidth;
		if(this.data.length>0) {
			var o=this.data[this.data.length-1];
			if(this.props.rtl || window._rtl) {
				var o2=this.data[0];
				w=o2.obj.offsetLeft+o2.obj.offsetWidth-o.obj.offsetLeft;
			} else w=o.obj.offsetLeft+o.obj.offsetWidth;
		}
		if(havew<w) { //enable scrolls
			this.parts.scrbut.style.display='block';
			havew-=this.parts.scrbut.offsetWidth;
		} else this.parts.scrbut.style.display='none';
			
		if(this.scrollpos.pos==null) {
			if((this.props.rtl || window._rtl) && this.data.length>0) this.scrollpos.pos=this.data[this.data.length-1].obj.offsetLeft+w-havew;
				else this.scrollpos.pos=0;
		} else if(this.scrollpos.havewidth!=havew) 
					if(this.props.rtl || window._rtl) this.scrollpos.pos+=this.scrollpos.havewidth-havew;

		this.scrollpos.havewidth=havew;
		this.scrollpos.tabswidth=w;
		this.scrollTabPane(0);
//		alert(w+','+havew);
	},
	show: function(rel) {
		if(!this.state.init) {pend_show=[rel];return;}
  		$(this.top).show();
	    this.state.visible=true;
//	    if(rel) load();
	},
	resizeTo: function(w,h) {
	  var d=this.decor;
          with(this) {
		width=w;
		height=h;
//		$(this.top).css({height:h+'px',width:w+'px'});
		$(top).width(w).height(h);
		$(parts.content).css({width:(w-d.cdw)+'px',height:(h-d.cdh-d.fh-d.hh)+'px'});
		if(parts.headercontent)$(parts.headercontent).css({width:(w-d.cdw)+'px',height:d.hh+'px'});
		if(parts.footercontent)$(parts.footercontent).css({width:(w-d.cdw)+'px',height:d.fh+'px'});
		$(parts.listp).css({width:(w-d.pdw)+'px'});
		if(props.onresize) props.onresize.call(app,w-d.cdw,h-d.cdh,this,name);
		_setscrolls();
          }
	},
	addTab: function(title,dat,topt,idx) {
		var i= idx!=undefined && idx>=0 && idx<this.data.length ? idx : this.data.length;
		var opt=topt || {};
		var id=opt.id || '';
		if(!id || id.length==0) id='_tc'+this.idx+'tb'+(this.maxid++);
		var data={
			id:id,
			title:title || '.',
			dat:dat || '',
                        footer: opt.footerc || null, //content of header (string or html obj)
                        footerh: opt.footerh && opt.footerh>0 ? opt.footerh : 0, //height of footer block if it was specified
                        header: opt.headerc || null, //content of footer (string or html obj)
                        headerh: opt.headerh && opt.headerh>0 ? opt.headerh : 0, //height of header block if it was specified
                        footercont: null, //real footer content
                        headercont: null, //real footer content
			cont:null,
                        ismarkload:0, //if tab is in markload state
			markloadcont:null,
			obj:null,
			ishidden: opt.hidden,
			clbut:null,
			link:null,
			href:opt.href,
			target:opt.target,
			label:null,
			close:opt.close==undefined ? this.props.close : opt.close,
			icon:opt.icon,
			markload:opt.markload,
			firstload:0,
                        firstshow:0,
			onload:opt.onload==undefined ? this.props.onload: opt.onload,
			onshow:opt.onshow==undefined ? this.props.onshow : opt.onshow,
			onhide:opt.onhide==undefined ? this.props.onhide : opt.onhide,
			onbeforechange:opt.onbeforechange==undefined ? this.props.onbeforechange : opt.onbeforechange,
			onchange:opt.onchange==undefined ? this.props.onchange : opt.onchange,
			onbeforeclose:opt.onbeforeclose==undefined ? this.props.onbeforeclose : opt.onbeforeclose,
			onclose:opt.onclose==undefined ? this.props.onclose : opt.onclose
			};

		if(i<this.data.length) this.data.splice(i,0,data);
			else this.data[i]=data;
		this.design.insert_item(this,i);
		this._setscrolls();
		return i;
	},
	tabHidden: function(idx,ishidden) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		var a=this.data[idx];
		a.obj.style.display=ishidden ? 'none' : ''; 
		a.ishidden=!!ishidden;
		this._setscrolls();
	},
	activateTab: function(idx,first) { //first used internally to indicate first call of this function
		idx=this.idxbyid(idx);
                if(!this.state.init) {this.active_tab=idx;return;}
		if(idx<0 || idx>=this.data.length || this.active_tab==idx) if(first && this.data.length>0) idx=0; else return;
		this.design._ontabactivate(this,idx);
		if(this.active_tab>=0 && this.active_tab<this.data.length) {
			if(typeof this.data[this.active_tab].onhide == 'function') this.data[this.active_tab].onhide.call(this.app,this,this.active_tab,this.data[this.active_tab].id);
			this.design._ontabdeactivate(this,this.active_tab);
		}
		this.active_tab=idx;
		this._setscrolls();
                if(!first) this.sesupdate=1;
                this.data[idx].firstshow=1;
		if(typeof this.data[idx].onchange == 'function') if(!this.data[idx].onchange.call(this.app,this,idx,this.data[idx].id)) return;
		this.load(idx);
	},
	closeTab: function(idx) {
                if(!this.state.init) return;
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		if(idx==this.active_tab && typeof this.data[idx].onhide == 'function') this.data[idx].onhide.call(this.app,this,idx,this.data[idx].id);

		this.design.remove_item(this,idx);
		var id=this.data[idx].id;
		var f=this.data[idx].onclose;
		this.data.splice(idx,1);
		if(idx==this.active_tab) {
			this.active_tab=-1;
			if(idx==this.data.length) 
				if(idx==0) this._assign_content(-1);
					else this.activateTab(idx-1);
				else this.activateTab(idx);
		} else if(idx<this.active_tab) this.active_tab--;
		this._setscrolls();
		if(f) f(this,idx,id);
	},
	setTitle: function(idx,title) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		this.data[idx].title=title;
		this.design.set_title(this,idx);
		this._setscrolls();
	},
        headerheight: function(idx,fh) {
	    idx=this.idxbyid(idx);
	    if(idx<0 || idx>=this.data.length) return;
            if(typeof(fh)!='number' || isNaN(fh)) return;
            this.data[idx].headerh=fh;
        },
        footerheight: function(idx,fh) {
	    idx=this.idxbyid(idx);
	    if(idx<0 || idx>=this.data.length) return;
            if(typeof(fh)!='number' || isNaN(fh)) return;
            this.data[idx].footerh=fh;
        },
	content: function(idx,c,hc,fc,iserror) { //c - content (can be null to leave current content), hc - header content (can be null to leave current), fc - footer content
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
                if((typeof(hc)=='undefined' || hc==null)) { //means that we do not want to change header, but must init it if it was provided during adding tab
                    if(!this.data[idx].headercont)
                        if(this.data[idx].header) hc=this.data[idx].header;
                        else hc='';
                    else hc=null;
                }
                if((typeof(fc)=='undefined' || fc==null)) {
                    if(!this.data[idx].footercont)
                        if(this.data[idx].footer) fc=this.data[idx].footer;
                        else fc='';
                    else fc=null;
                }
                if((typeof(c)=='undefined' || c==null)) { //we do not want to change its content
                    if(!this.data[idx].cont) c=''; //load should be called first to assign corrent main content
                    else c=null;
                }
		if(!this.data[idx].cont) {
			this.data[idx].cont=document.createElement('DIV');
			$(this.data[idx].cont).addClass(this.design.content_class);
		}
		if(c!=null) {
                    $(this.data[idx].cont).html(c);
		    this.data[idx].firstload=iserror ? 0 : 1;
		    this.data[idx].ismarkload=0;
                }
                if(hc || hc==null) {
    		    if(!this.data[idx].headercont) {
			this.data[idx].headercont=document.createElement('DIV');
			$(this.data[idx].headercont).attr("class",this.design.content_class+' '+this.design.header_class).css("overflow","hidden");
		    }
		    if(hc)$(this.data[idx].headercont).html(hc);
                } else if(this.data[idx].headercont) $(this.data[idx].headercont).html('');
                if(fc || fc==null) {
    		    if(!this.data[idx].footercont) {
			this.data[idx].footercont=document.createElement('DIV');
			$(this.data[idx].footercont).attr("class",this.design.content_class+' '+this.design.footer_class).css("overflow","hidden");
		    }
		    if(fc)$(this.data[idx].footercont).html(fc);
                } else if(this.data[idx].footercont) $(this.data[idx].footercont).html('');
		if(idx==this.active_tab) this._assign_content(idx);
	},
	_assign_content: function(idx) {
                var fh=0,hh=0,i; //footer height, header height
		if(idx<0) {this.parts.content=this.parts.emptycontent;this.parts.headercontent=this.parts.footercontent=null;}
		        else if(this.data[idx].ismarkload) {this.parts.content=this.data[idx].markloadcont;this.parts.headercontent=this.parts.footercontent=null;}
			else {
                            this.parts.content=this.data[idx].cont;
                            this.parts.headercontent=this.data[idx].headercont;
                            hh=this.data[idx].headerh;
                            this.parts.footercontent=this.data[idx].footercont;
                            fh=this.data[idx].footerh;
                        }
                i=0; //current child index
                //set header s first child
                if(this.parts.headercontent) {
		    $(this.parts.headercontent).css({width:(this.width-this.decor.cdw)+'px',height:hh+'px'});
                    if(this.parts.body.childNodes[i]) this.parts.body.replaceChild(this.parts.headercontent,this.parts.body.childNodes[i]);
                        else this.parts.body.appendChild(this.parts.headercontent);
                    this.decor.hh=hh;
                    i++;
                } else this.decor.hh=0;
                //set main content
		$(this.parts.content).css({width:(this.width-this.decor.cdw)+'px',height:(this.height-this.decor.cdh-fh-hh)+'px'});
                if(this.parts.body.childNodes[i]) this.parts.body.replaceChild(this.parts.content,this.parts.body.childNodes[i]);
                        else this.parts.body.appendChild(this.parts.content);
                i++;
                //set footer
                if(this.parts.footercontent) {
		    $(this.parts.footercontent).css({width:(this.width-this.decor.cdw)+'px',height:fh+'px'});
                    if(this.parts.body.childNodes[i]) this.parts.body.replaceChild(this.parts.footercontent,this.parts.body.childNodes[i]);
                        else this.parts.body.appendChild(this.parts.footercontent);
                    this.decor.fh=fh;
                    i++;
                } else this.decor.fh=0;
                //remove excess childs if any
                while(this.parts.body.childNodes[i]) this.parts.body.removeChild(this.parts.body.childNodes[i]);

		if(idx>=0 && !this.data[idx].ismarkload) {
                    if(typeof this.data[idx].onload == 'function' && this.data[idx].firstload) {
                        var dd,df;
                        try { for(dd=10,df=arguments.caller;dd>=0;dd--) if(!df || df.arguments.caller==arguments.callee) break; else df=df.arguments.caller; } catch(e) {}
                        if(!df || dd<0) //prevent looped recursion
                            this.data[idx].onload.call(this.app,this,idx,this.data[idx].id,this.parts.content,this.parts.headercontent,this.parts.footercontent);
                    }
		    if(typeof this.data[idx].onshow == 'function' && this.data[idx].firstshow) this.data[idx].onshow.call(this.app,this,idx,this.data[idx].id,this.parts.content,this.parts.headercontent,this.parts.footercontent);
                    this.data[idx].firstshow=0;
                }
		if(idx>=0) this.data[idx].firstload=0;
	},
	markload: function(idx) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		var c;
		if(this.data[idx].markload) { //this tab has its own markload page
			if(!this.data[idx].markloadcont) {
				this.data[idx].markloadcont=document.createElement('DIV');
				$(this.data[idx].markloadcont).addClass("u-tabc-content").html(this.data[idx].markload);
			}
//			c=this.data[idx].markloadcont;
		} else {
			if(!this.parts.markloadcont) {
				this.parts.markloadcont=document.createElement('DIV');
				$(this.parts.markloadcont).addClass("u-tabc-content").html(this.props.markload);
			}
                        this.data[idx].markloadcont=this.parts.markloadcont;
//			c=this.parts.markloadcont;
		}
                this.data[idx].ismarkload=1;
                this.data[idx].iserrorload=0;
		if(idx==this.active_tab) this._assign_content(idx);
	},
	idxbyid: function(id) {
		if(typeof id=='string') {
			for(var i=0;i<this.data.length;i++) if(this.data[i].id==id) return i;
			return -1;
		} else return id;
	},
        findintab: function(idx,sel) { //applies css selector to tab content, including footer and header
	    idx=this.idxbyid(idx);
	    if(idx<0 || idx>=this.data.length) return $([]);
            var ob=$(this.data[idx].cont);
            if(this.data[idx].headercont) ob=ob.add(this.data[idx].headercont);
            if(this.data[idx].footercont) ob=ob.add(this.data[idx].footercont);
            return ob.find(sel);
        },
	load: function(idx,reload) {
	    idx=this.idxbyid(idx);
	    if(idx<0 || idx>=this.data.length) return;
	    if(this.data[idx].cont!=null && !reload) { //content is already loaded
		if(idx==this.active_tab) this._assign_content(idx);
		return;
	    }
	    var c=this.data[idx].dat;
	    if(typeof (c) == 'string') this.content(idx,c,this.data[idx].header,this.data[idx].footer);
    	        else if(typeof c == 'function') this.content(idx,c(),this.data[idx].header,this.data[idx].footer);
    	        else if(typeof c == 'object') {
	            this.markload(idx);
                    if(!c.data)c.data={};
                    if(!('_tci' in c.data)) c.data._tci=this.idx;
                    if(!('_ti' in c.data)) c.data._ti=idx;
                    if(this.app && !('_ai' in c.data)) c.data._ai=this.app.pid;
                    if(this.app && !('app' in c)) c.app=this.app.pid;
                    if(this.wnd && !('wnd' in c)) c.wnd=this.wnd.idx;
                    if(!('tabctrl' in c)) c.tabctrl=this.idx;
                    if(!('tabidx' in c)) c.tabidx=idx;
		    if(!c.success && c.xml===false) {c.dataType='text';c.success=new Function("data","st","var w=_uTabCtrl.all["+this.idx+"];if(w)w.content('"+this.data[idx].id+"',data);");}
	   		else if(!c.success && c.xml!==false) c.success=new Function("data","st","var w=_uTabCtrl.all["+this.idx+"];_uParseXML(data,w,'"+this.data[idx].id+"',w.app);");
		    if(!c.error) c.error=new Function("xml","st","er","var w=_uTabCtrl.all["+this.idx+"];if(w)w._onerror('"+this.data[idx].id+"',xml,st,er);");
		    try {
			if(c.form && (c.form.length>0 || c.form.nodeType)) //have form
	   			_uPostForm(c.form,c);
	   		else if(c.url) _uAjaxRequest(c.url,c);
		    } catch(e) {this._onerror(this.data[idx].id,null,'',e);}
    	        }
    	return true;
	},
	_onerror: function(id,xml,st,er) {
		var idx=this.idxbyid(id);
		if(idx<0 || idx>=this.data.length) return;
	    var o=this.props.onerror;
	    if(o && typeof(o)=='function') o.apply(this.app,arguments);
			else this.content(idx,_txt('ErrorLoadTab',this.idx,idx),null,null,1);
	},
	destroy: function() {
		//remove items
		this.data.splice(0,this.data.length);
		this.parts=null;
		this.top.parentNode.removeChild(this.top);
		this.top=null;
		if(this.props.ondestroy) this.props.ondestroy(this,this.name);
	}
};

//ucoz specific
//wnd can be _uWnd _uTabCtrl or _uApp
function _uParseXML(xml,wnd,tabid) {xml = xml.documentElement;
var tabctrl=null,app=null;

if(typeof wnd=='object' && wnd.constructor==_uTabCtrl) {tabctrl=wnd;wnd=null;}
	else if(typeof _uApp!='undefined' && typeof wnd=='object' && wnd.appname) {app=wnd;wnd=null;}

if (xml == null) { alert("Server connection Error. Sorry."); }
for (var i = 0; i < xml.childNodes.length; i++) {
if (xml.childNodes[i].nodeName == "cmd"){ var cmd=''; var target=''; var data;
for (var j=0; j<xml.childNodes[i].attributes.length; j++) {
if (xml.childNodes[i].attributes[j].name == "p")cmd = xml.childNodes[i].attributes[j].value;
if (xml.childNodes[i].attributes[j].name == "t")target = xml.childNodes[i].attributes[j].value;}
if (xml.childNodes[i].firstChild && xml.childNodes[i].firstChild.data ) data = xml.childNodes[i].firstChild.data; else data = '';
if (cmd=='innerHTML' && target.match(/^layerContent(.+)/)) _uWnd.content(RegExp.$1,data);
if (cmd=='innerHTML' && target.match(/^layerTitle(.+)/)) _uWnd.setTitle(RegExp.$1,data);
if (cmd=='innerHTML') $('#'+target).html(data);
else if (cmd=='+innerHTML') $('#'+target).prepend(data);
else if (cmd=='innerHTML+') $('#'+target).append(data);
else if (cmd=='innerHTMLspanAll') $("span."+target).html(data);
else if (cmd=='innerHTMLdivAll') $("div."+target).html(data);
else if (cmd=='value') $('#'+target).val(data);
else if (cmd=='jsa') includeJSfile(data,target);
else if (cmd=='js') eval(data);
else if (cmd=='content' && target.length>0) {
	var r=target.match(/^([^:]+):(.+)/);
	if(r) _uTabCtrl.content(r[1],r[2],data);
	else _uWnd.content(target,data);
}
else if (cmd=='title' && target.length>0) {
	var r=target.match(/^([^:]+):(.+)/);
	if(r) _uTabCtrl.setTitle(r[1],r[2],data);
	else _uWnd.setTitle(target,data);
}
else if (cmd=='close' && target.length>0) {
	var r=target.match(/^([^:]+):(.+)/);
	if(r) 
		if(!data || parseInt(data)==NaN)_uTabCtrl.closeTab(r[1],r[2]);else setTimeout("_uTabCtrl.closeTab('"+r[1]+"','"+r[2]+"');",parseInt(data));
	else
		if(!data || parseInt(data)==NaN)_uWnd.close(target);else setTimeout("_uWnd.close('"+target+"');",parseInt(data));
}
else if(wnd) {
    if(cmd=='content') wnd.content(data);
    else if(cmd=='title') wnd.setTitle(data);
    else if(cmd=='close') if(!data || parseInt(data)==NaN)wnd.close();else setTimeout("var w=_uWnd.all["+wnd.idx+"];if(w)w.close();",parseInt(data));
    }
else if(tabctrl && tabid) {
    if(cmd=='content') tabctrl.content(tabid,data);
    else if(cmd=='title') {tabctrl.setTitle(tabid,data);}
    else if(cmd=='close') if(!data || parseInt(data)==NaN)tabctrl.closeTab(tabid);else setTimeout("var w=_uTabCtrl.all["+tabctrl.idx+"];if(w)w.closeTab('"+tabid+"');",parseInt(data));
    }
}}
}

var _defAjaxError=function(xmlreq, status, err) {
//this - options for request
//typically only one of status or err (exception) will have info
	try {
		_show_log_form();return;
	} catch(e){}
	window.location.reload();
}
var _hookAjaxError=null; //function(xmlreq, status, err)
//this - options for request

function _uAjaxRequest(url,options) {
    if(!url) return null;
    var o = $.extend({
//noerrorhook:1   - can be used to prevent error hook from being used    	
		app: 0, //application PID
		async: 1,
		cache: true,
		dataType: 'xml',
		error: _defAjaxError,
	    type: 'GET',
		success: _defAjaxSuccess,
		timeout: 25000
// 		data: {f1: val1, f2: val2, f3: [val4,val5]}
    }, options || {});
    if(_hookAjaxError && !o.noerrorhook) {o.prev_error=o.error;o.error=_hookAjaxError;}
    o.url=url;
//    if(o.app>0 && !o.nosuccesshook) {o.prev_success=o.success;o.success=_hookAjaxSuccess;}

    return jQuery.ajax(o);
}
//by default use app in options
var _hookAjaxSuccess=function(data, status) {
	if(!this.prev_success) return;
	if(this.app>0 && typeof _uApp!='undefined' && _uApp.all[this.app] && !_uApp.all[this.app].exited && this.prev_success!=_defAjaxSuccess) this.prev_success.call(_uApp.all[this.app],data,status);
		else this.prev_success.call(this,data,status);
};

//by default call _uParseXML for xml reply
var _defAjaxSuccess=function(data, status) {
//this - options for request
	if(this.dataType=='xml') {
		if(this.app>0 && typeof _uApp!='undefined' && _uApp.all[this.app] && !_uApp.all[this.app].exited) 
			_uParseXML(data,_uApp.all[this.app]);
			else
			_uParseXML(data);
	}
}


//by default try to find onerror attribute and execute it
var _defAjaxFormError=function(xmlreq, status, err) {
//this - options for request
//typically only one of status or err (exception) will have info
	if(!this._formobj) return;
	var a=this._formobj.onerror || this._formobj.getAttribute('onerror');
	if(!a) return;
	if(typeof a == 'string') {
		try {a=new Function(a);} catch(e){return;}
	}
	if(typeof a == 'function' || typeof a=='object') {
		try {a.call(this._formobj,xmlreq, status, err);} catch(e){return;}
	}
}

function _uPostForm(formid,options) {
    if(!formid && options && options.url) { _uAjaxRequest(options.url,options);return;}
    var f;
    if(typeof(formid)!='object') f=$('#'+formid); else f=$(formid);
    if(!f.length) return;
    var o = $.extend({
//noerrorhook:1   - can be used to prevent error hook from being used    	
		app: 0, //pid of application
		url: f.attr('action') || window.location.toString(),
		type: f.attr('method') || 'GET',
		error: _defAjaxFormError,
		success: _defAjaxSuccess,
		dataType: 'xml',
		semantic: false //true if form contains type=image
    }, options || {});
    if(_hookAjaxError && !o.noerrorhook) {o.prev_error=o.error;o.error=_hookAjaxError;}
    o._formobj=f[0];
    if(o.app>0 && !o.nosuccesshook) {o.prev_success=o.success;o.success=_hookAjaxSuccess;}
    f.ajaxSubmit(o);
}

/**
 * jCarouselLite - jQuery plugin to navigate images/any content in a carousel style widget.
 * @requires jQuery v1.2 or above
 *
 * http://gmarwaha.com/jquery/jcarousellite/
 *
 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.1
 * Note: Requires jquery 1.2 or above from version 1.0.1
 */

(function($) {                                          // Compliant with jquery.noConflict()
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {                           // Returns the element collection. Chainable.

        var running = false, animCss=o.vertical?"top":"left", sizeCss=o.vertical?"height":"width";
        var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        var li = $("li", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({overflow: "hidden", float: o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

        var liSize = o.vertical ? height(li) : width(li);   // Full li size(incl margin)-Used for animation
        var ulSize = liSize * itemLength;                   // size of full ul(total length, not just for the visible items)
        var divSize = liSize * v;                           // size of entire div(total length for just the visible items)

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        div.css(sizeCss, divSize+"px");                     // Width of the DIV. length of visible images

        if(o.btnPrev)
            $(o.btnPrev).click(function() {
                return go(curr-o.scroll);
            });

        if(o.btnNext)
            $(o.btnNext).click(function() {
                return go(curr+o.scroll);
            });

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        function go(to) {
            if(!running) {

                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to==o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -( (v) * liSize ) + "px" );
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to==itemLength-v+1 ? v+1 : v+o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first, and enable when not
                if(!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    $( (curr-o.scroll<0 && o.btnPrev)
                        ||
                       (curr+o.scroll > itemLength-v && o.btnNext)
                        ||
                       []
                     ).addClass("disabled");
                }

            }
            return false;
        };
    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};
function width(el) {
    return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
};
function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
};

})(jQuery);
				while(ww.firstChild) ww.removeChild(ww.firstChild);
				ww.appendChild(t);
				this.wnd=this.props.wnd;
				this.wnd.tabctrl=this;
				this.wnd.state.loaded=true;
				}
			else $($("body")[0]).append(t);

		this.top=t;
	    $(t).css({visibility:'hidden',display:'block'});
		if(this.width>0) $(t).css('width',this.width+'px');
//		if(this.height>0) $(t).css('height',this.height+'px');

	    this.parts=this.design.tabctrl_init(this);
	    this.parts.markloadcont=null;
		this.show();
		if(!noinit)setTimeout("var m=_uTabCtrl.all["+this.idx+"];if(m)m.init1();",10);
	},
	init1: function(noresize) { //noresize used internally by windows
//calculate decor
		var p=this.parts,d=this.decor;
		if(!(this.width>0)) this.width=this.top.offsetWidth;
		if(!(this.height>0)) this.height=this.top.offsetHeight;
		d.cdw=this.top.offsetWidth-p.content.offsetWidth;
		d.cdh=this.top.offsetHeight-p.content.offsetHeight;
		d.pdw=this.top.offsetWidth-p.listp.offsetWidth;
		if(!this.props.wnd && !noresize) {
			$(this.top).css('height',this.height+'px');
			$(p.content).css({width:(this.top.offsetWidth-d.cdw)+'px',height:(this.top.offsetHeight-d.cdh)+'px'});
			$(p.listp).css({width:(this.top.offsetWidth-d.pdw)+'px'});
		}

		$(p.listp).css({overflow:'hidden'});
		$(p.panebot).css('width','4000px');
		$(p.list).css('width','4000px');
		for(var i=0;i<this.ntabs;i++)
			this.design.insert_item(this,i);
		if(this.props.wnd)
			this.resizeTo(this.props.wnd.width-this.props.wnd.decor.w,this.props.wnd.height-this.props.wnd.decor.h);
		var at=this.active_tab;
		this.active_tab=-1;
		if(at=='auto')
			if(this.name && this.name.length>0 && self.location.hash.length>1) {
				var u=self.location.hash.substr(1).split(';');
				var s='T_'+this.name+'=';
				for(var ui=0;ui<u.length;ui++)
					if(u[ui].length>s.length && u[ui].substr(0,s.length)==s) {
						var tb=this.idxbyid(u[ui].substr(s.length));
						if(tb>=0 && tb<this.data.length) {at=tb;break;}
					}
			} else at=-1;
	    $(this.top).css("display",'block').css("visibility",'visible');
	    if(at==-1 && this.data.length>0) at=0;
	    if(at>=0 && at<this.ntabs) {
			for(var i=0;i<this.ntabs;i++) {
				var j=(at+i)%this.ntabs;
				if(!this.data[j].ishidden && (!this.data[j].onbeforechange || !!this.data[j].onbeforechange(this,j,this.data[j].id))) {
					this.activateTab(j,true);
					break;
				}
			}
		} else this.activateTab(-1,true);

	    $(this.top).css("display",'none').css("visibility",'visible');
		this.state.init=true;
	    if(pend_show) this.show(pend_show[0]);
	    if(this.props.wnd) this.props.wnd.onexternalload(); //activate autosize 
	},
	scrollTabPane: function(dx) { //>0 - right
		var pos=this.scrollpos.pos+=dx;
		var w=this.scrollpos.tabswidth,havew=this.scrollpos.havewidth;
		if(w<havew) {
			this.design._onscrbutactivate(this,0,0);
			this.design._onscrbutactivate(this,1,0);
			if((this.props.rtl || window._rtl) && this.data.length>0) {
				pos=this.data[this.data.length-1].obj.offsetLeft+havew-w;
			} else pos=0;
			this.scrollpos.pos=pos;
			this.parts.listp.scrollLeft=pos;
		} else {
			if(this.props.rtl || window._rtl) {
				var ol=this.data[this.data.length-1].obj.offsetLeft;
				if(pos<ol) pos=ol;
					else if(pos>ol+w-havew) pos=ol+w-havew;
			} else if(pos<0) pos=0;
					else if(pos>w-havew) pos=w-havew;
			this.scrollpos.pos=pos;
			this.parts.listp.scrollLeft=pos;
			if(pos>0) this.design._onscrbutactivate(this,0,1);
				else this.design._onscrbutactivate(this,0,0);
			if(pos<w-havew) this.design._onscrbutactivate(this,1,1);
				else this.design._onscrbutactivate(this,1,0);
		}
	},
	_setscrolls: function() { //set scroll buttons status accroding to tab widths
		var w=0,havew=this.parts.listp.offsetWidth;
		if(this.parts.listp.clientWidth>0 && this.parts.listp.clientWidth<havew) havew=this.parts.listp.clientWidth;
		if(this.data.length>0) {
			var o=this.data[this.data.length-1];
			if(this.props.rtl || window._rtl) {
				var o2=this.data[0];
				w=o2.obj.offsetLeft+o2.obj.offsetWidth-o.obj.offsetLeft;
			} else w=o.obj.offsetLeft+o.obj.offsetWidth;
		}
		if(havew<w) { //enable scrolls
			this.parts.scrbut.style.display='block';
			havew-=this.parts.scrbut.offsetWidth;
		} else this.parts.scrbut.style.display='none';
			
		if(this.scrollpos.pos==null) {
			if((this.props.rtl || window._rtl) && this.data.length>0) this.scrollpos.pos=this.data[this.data.length-1].obj.offsetLeft+w-havew;
				else this.scrollpos.pos=0;
		} else if(this.scrollpos.havewidth!=havew) 
					if(this.props.rtl || window._rtl) this.scrollpos.pos+=this.scrollpos.havewidth-havew;

		this.scrollpos.havewidth=havew;
		this.scrollpos.tabswidth=w;
		this.scrollTabPane(0);
//		alert(w+','+havew);
	},
	show: function(rel) {
		if(!this.state.init) {pend_show=[rel];return;}
  		$(this.top).show();
	    this.state.visible=true;
//	    if(rel) load();
	},
	resizeTo: function(w,h) {
		this.width=w;
		this.height=h;
		var d=this.decor;
//		$(this.top).css({height:h+'px',width:w+'px'});
		$(this.top).width(w).height(h);
		$(this.parts.content).css({width:(w-d.cdw)+'px',height:(h-d.cdh)+'px'});
		$(this.parts.listp).css({width:(w-d.pdw)+'px'});
		if(this.props.onresize) this.props.onresize(w-d.cdw,h-d.cdh,this,this.name);
		this._setscrolls();
	},
	addTab: function(title,dat,topt,idx) {
		var i= idx!=undefined && idx>=0 && idx<this.data.length ? idx : this.data.length;
		var opt=topt || {};
		var id=opt.id || '';
		if(!id || id.length==0) id='_tc'+this.idx+'tb'+(maxid++);
		var data={
			id:id,
			title:title || '.',
			dat:dat || '',
			cont:null,
			markloadcont:null,
			obj:null,
			ishidden: opt.hidden,
			clbut:null,
			link:null,
			href:opt.href,
			target:opt.target,
			label:null,
			close:opt.close==undefined ? this.props.close : opt.close,
			icon:opt.icon,
			markload:opt.markload,
			firstload:0,
			onload:opt.onload==undefined ? this.props.onload: opt.onload,
			onshow:opt.onshow==undefined ? this.props.onshow : opt.onshow,
			onhide:opt.onhide==undefined ? this.props.onhide : opt.onhide,
			onbeforechange:opt.onbeforechange==undefined ? this.props.onbeforechange : opt.onbeforechange,
			onchange:opt.onchange==undefined ? this.props.onchange : opt.onchange,
			onbeforeclose:opt.onbeforeclose==undefined ? this.props.onbeforeclose : opt.onbeforeclose,
			onclose:opt.onclose==undefined ? this.props.onclose : opt.onclose
			};

		if(i<this.data.length) this.data.splice(i,0,data);
			else this.data[i]=data;
		this.design.insert_item(this,i);
		this._setscrolls();
		return i;
	},
	tabHidden: function(idx,ishidden) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		var a=this.data[idx];
		a.obj.style.display=ishidden ? 'none' : ''; 
		a.ishidden=!!ishidden;
		this._setscrolls();
	},
	activateTab: function(idx,first) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length || this.active_tab==idx) if(first && this.data.length>0) idx=0; else return;
		this.design._ontabactivate(this,idx);
		if(this.active_tab>=0 && this.active_tab<this.data.length) {
			if(typeof this.data[this.active_tab].onhide == 'function') this.data[this.active_tab].onhide.call(this.app,this,this.active_tab,this.data[this.active_tab].id);
			this.design._ontabdeactivate(this,this.active_tab);
		}
		this.active_tab=idx;
		this._setscrolls();
		if(typeof this.data[idx].onchange == 'function') if(!this.data[idx].onchange.call(this.app,this,idx,this.data[idx].id)) return;
		this.load(idx);
	},
	closeTab: function(idx) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		if(idx==this.active_tab && typeof this.data[idx].onhide == 'function') this.data[idx].onhide.call(this.app,this,idx,this.data[idx].id);

		this.design.remove_item(this,idx);
		var id=this.data[idx].id;
		var f=this.data[idx].onclose;
		this.data.splice(idx,1);
		if(idx==this.active_tab) {
			this.active_tab=-1;
			if(idx==this.data.length) 
				if(idx==0) this._assign_content(-1);
					else this.activateTab(idx-1);
				else this.activateTab(idx);
		} else if(idx<this.active_tab) this.active_tab--;
		this._setscrolls();
		if(f) f(this,idx,id);
	},
	setTitle: function(idx,title) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		this.data[idx].title=title;
		this.design.set_title(this,idx);
		this._setscrolls();
	},
	content: function(idx,c) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		if(!this.data[idx].cont) {
			this.data[idx].cont=document.createElement('DIV');
			$(this.data[idx].cont).addClass("u-tabc-content");
		}
		$(this.data[idx].cont).html(c);
		this.data[idx].firstload=1;
		if(idx==this.active_tab) this._assign_content(idx);
	},
	_assign_content: function(idx,altcont) {
		if(altcont) this.parts.content=altcont;
			else if(idx<0) this.parts.content=this.parts.emptycontent;
			else this.parts.content=this.data[idx].cont;
		$(this.parts.content).css({width:(this.width-this.decor.cdw)+'px',height:(this.height-this.decor.cdh)+'px'});
		this.parts.body.replaceChild(this.parts.content,this.parts.body.firstChild);
		if(!altcont && idx>=0 && typeof this.data[idx].onload == 'function' && this.data[idx].firstload) this.data[idx].onload.call(this.app,this,idx,this.data[idx].id);
		if(!altcont && idx>=0 && typeof this.data[idx].onshow == 'function') this.data[idx].onshow.call(this.app,this,idx,this.data[idx].id);
		this.data[idx].firstload=0;
	},
	markload: function(idx,txt) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		var c;
		if(this.data[idx].markload) { //this tab has its own markload page
			if(!this.data[idx].markloadcont) {
				this.data[idx].markloadcont=document.createElement('DIV');
				$(this.data[idx].markloadcont).addClass("u-tabc-content").html(this.data[idx].markload);
			}
			c=this.data[idx].markloadcont;
		} else {
			if(!this.parts.markloadcont) {
				this.parts.markloadcont=document.createElement('DIV');
				$(this.parts.markloadcont).addClass("u-tabc-content").html(this.props.markload);
			}
			c=this.parts.markloadcont;
		}
		this._assign_content(idx,c);
	},
	idxbyid: function(id) {
		if(typeof id=='string') {
			for(var i=0;i<this.data.length;i++) if(this.data[i].id==id) return i;
			return -1;
		} else return id;
	},
	load: function(idx,reload) {
		idx=this.idxbyid(idx);
		if(idx<0 || idx>=this.data.length) return;
		if(this.data[idx].cont!=null && !reload) { //content is already loaded
			this._assign_content(idx);			
			return;
		}
	    var c=this.data[idx].dat;
    	if(typeof (c) == 'string') this.content(idx,c);
    	else if(typeof c == 'function') this.content(idx,c());
    	else if(typeof c == 'object') {
			this.markload(idx);
			if(!c.success && c.xml===false) {c.dataType='text';c.success=new Function("data","st","var w=_uTabCtrl.all["+this.idx+"];if(w)w.content('"+this.data[idx].id+"',data);");}
	   			else if(!c.success && c.xml!==false) c.success=new Function("data","st","var w=_uTabCtrl.all["+this.idx+"];_uParseXML(data,w,'"+this.data[idx].id+"');");
			if(!c.error) c.error=new Function("xml","st","er","var w=_uTabCtrl.all["+this.idx+"];if(w)w._onerror('"+this.data[idx].id+"',xml,st,er);");
			try {
			if(c.form && (c.form.length>0 || c.form.nodeType)) //have form
	   			_uPostForm(c.form,c);
	   		else if(c.url) _uAjaxRequest(c.url,c);
			} catch(e) {this._onerror(this.data[idx].id,null,'',e);}
    	}
    	return true;
	},
	_onerror: function(id,xml,st,er) {
		var idx=this.idxbyid(id);
		if(idx<0 || idx>=this.data.length) return;
	    var o=this.props.onerror;
	    if(o && typeof(o)=='function') o.apply(this.app,arguments);
			else this.content(idx,'<a href="javascript://" onclick="var w=_uTabCtrl.all[\''+this.idx+'\'];if(w)w.load(\''+this.data[idx].id+'\',1);">Reload</a>.');
	},
	destroy: function() {
		//remove items
		this.data.splice(0,this.data.length);
		this.parts=null;
		this.top.parentNode.removeChild(this.top);
		this.top=null;
		if(this.props.ondestroy) this.props.ondestroy(this,this.name);
	}
};

//ucoz specific
//wnd can be _uWnd _uTabCtrl or _uApp
function _uParseXML(xml,wnd,tabid) {xml = xml.documentElement;
var tabctrl=null,app=null;

if(typeof wnd=='object' && wnd.constructor==_uTabCtrl) {tabctrl=wnd;wnd=null;}
	else if(typeof _uApp!='undefined' && typeof wnd=='object' && wnd.appname) {app=wnd;wnd=null;}

if (xml == null) { alert("Server connection Error. Sorry."); }
for (var i = 0; i < xml.childNodes.length; i++) {
if (xml.childNodes[i].nodeName == "cmd"){ var cmd=''; var target=''; var data;
for (var j=0; j<xml.childNodes[i].attributes.length; j++) {
if (xml.childNodes[i].attributes[j].name == "p")cmd = xml.childNodes[i].attributes[j].value;
if (xml.childNodes[i].attributes[j].name == "t")target = xml.childNodes[i].attributes[j].value;}
if (xml.childNodes[i].firstChild && xml.childNodes[i].firstChild.data ) data = xml.childNodes[i].firstChild.data; else data = '';
if (cmd=='innerHTML' && target.match(/^layerContent(.+)/)) _uWnd.content(RegExp.$1,data);
if (cmd=='innerHTML' && target.match(/^layerTitle(.+)/)) _uWnd.setTitle(RegExp.$1,data);
if (cmd=='innerHTML') $('#'+target).html(data);
else if (cmd=='+innerHTML') $('#'+target).prepend(data);
else if (cmd=='innerHTML+') $('#'+target).append(data);
else if (cmd=='innerHTMLspanAll') $("span."+target).html(data);
else if (cmd=='innerHTMLdivAll') $("div."+target).html(data);
else if (cmd=='value') $('#'+target).val(data);
else if (cmd=='jsa') includeJSfile(data,target);
else if (cmd=='js') eval(data);
else if (cmd=='content' && target.length>0) {
	var r=target.match(/^([^:]+):(.+)/);
	if(r) _uTabCtrl.content(r[1],r[2],data);
	else _uWnd.content(target,data);
}
else if (cmd=='title' && target.length>0) {
	var r=target.match(/^([^:]+):(.+)/);
	if(r) _uTabCtrl.setTitle(r[1],r[2],data);
	else _uWnd.setTitle(target,data);
}
else if (cmd=='close' && target.length>0) {
	var r=target.match(/^([^:]+):(.+)/);
	if(r) 
		if(!data || parseInt(data)==NaN)_uTabCtrl.closeTab(r[1],r[2]);else setTimeout("_uTabCtrl.closeTab('"+r[1]+"','"+r[2]+"');",parseInt(data));
	else
		if(!data || parseInt(data)==NaN)_uWnd.close(target);else setTimeout("_uWnd.close('"+target+"');",parseInt(data));
}
else if(wnd) {
    if(cmd=='content') wnd.content(data);
    else if(cmd=='title') wnd.setTitle(data);
    else if(cmd=='close') if(!data || parseInt(data)==NaN)wnd.close();else setTimeout("var w=_uWnd.all["+wnd.idx+"];if(w)w.close();",parseInt(data));
    }
else if(tabctrl && tabid) {
    if(cmd=='content') tabctrl.content(tabid,data);
    else if(cmd=='title') {tabctrl.setTitle(tabid,data);}
    else if(cmd=='close') if(!data || parseInt(data)==NaN)tabctrl.closeTab(tabid);else setTimeout("var w=_uTabCtrl.all["+tabctrl.idx+"];if(w)w.closeTab('"+tabid+"');",parseInt(data));
    }
}}
}

var _defAjaxError=function(xmlreq, status, err) {
//this - options for request
//typically only one of status or err (exception) will have info
	try {
		_show_log_form();return;
	} catch(e){}
	window.location.reload();
}
var _hookAjaxError=null; //function(xmlreq, status, err)
//this - options for request

function _uAjaxRequest(url,options) {
    if(!url) return null;
    var o = $.extend({
//noerrorhook:1   - can be used to prevent error hook from being used    	
		app: 0, //application PID
		async: 1,
		cache: true,
		dataType: 'xml',
		error: _defAjaxError,
	    type: 'GET',
		success: _defAjaxSuccess,
		timeout: 25000
// 		data: {f1: val1, f2: val2, f3: [val4,val5]}
    }, options || {});
    if(_hookAjaxError && !o.noerrorhook) {o.prev_error=o.error;o.error=_hookAjaxError;}
    o.url=url;
//    if(o.app>0 && !o.nosuccesshook) {o.prev_success=o.success;o.success=_hookAjaxSuccess;}

    return jQuery.ajax(o);
}
//by default use app in options
var _hookAjaxSuccess=function(data, status) {
	if(!this.prev_success) return;
	if(this.app>0 && typeof _uApp!='undefined' && _uApp.all[this.app] && !_uApp.all[this.app].exited && this.prev_success!=_defAjaxSuccess) this.prev_success.call(_uApp.all[this.app],data,status);
		else this.prev_success.call(this,data,status);
};

//by default call _uParseXML for xml reply
var _defAjaxSuccess=function(data, status) {
//this - options for request
	if(this.dataType=='xml') {
		if(this.app>0 && typeof _uApp!='undefined' && _uApp.all[this.app] && !_uApp.all[this.app].exited) 
			_uParseXML(data,_uApp.all[this.app]);
			else
			_uParseXML(data);
	}
}


//by default try to find onerror attribute and execute it
var _defAjaxFormError=function(xmlreq, status, err) {
//this - options for request
//typically only one of status or err (exception) will have info
	if(!this._formobj) return;
	var a=this._formobj.onerror || this._formobj.getAttribute('onerror');
	if(!a) return;
	if(typeof a == 'string') {
		try {a=new Function(a);} catch(e){return;}
	}
	if(typeof a == 'function' || typeof a=='object') {
		try {a.call(this._formobj,xmlreq, status, err);} catch(e){return;}
	}
}

function _uPostForm(formid,options) {
    if(!formid && options && options.url) { _uAjaxRequest(options.url,options);return;}
    var f;
    if(typeof(formid)!='object') f=$('#'+formid); else f=$(formid);
    if(!f.length) return;
    var o = $.extend({
//noerrorhook:1   - can be used to prevent error hook from being used    	
		app: 0, //pid of application
		url: f.attr('action') || window.location.toString(),
		type: f.attr('method') || 'GET',
		error: _defAjaxFormError,
		success: _defAjaxSuccess,
		dataType: 'xml',
		semantic: false //true if form contains type=image
    }, options || {});
    if(_hookAjaxError && !o.noerrorhook) {o.prev_error=o.error;o.error=_hookAjaxError;}
    o._formobj=f[0];
    if(o.app>0 && !o.nosuccesshook) {o.prev_success=o.success;o.success=_hookAjaxSuccess;}
    f.ajaxSubmit(o);
}

/**
 * jCarouselLite - jQuery plugin to navigate images/any content in a carousel style widget.
 * @requires jQuery v1.2 or above
 *
 * http://gmarwaha.com/jquery/jcarousellite/
 *
 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.1
 * Note: Requires jquery 1.2 or above from version 1.0.1
 */

(function($) {                                          // Compliant with jquery.noConflict()
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {                           // Returns the element collection. Chainable.

        var running = false, animCss=o.vertical?"top":"left", sizeCss=o.vertical?"height":"width";
        var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        var li = $("li", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({overflow: "hidden", float: o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

        var liSize = o.vertical ? height(li) : width(li);   // Full li size(incl margin)-Used for animation
        var ulSize = liSize * itemLength;                   // size of full ul(total length, not just for the visible items)
        var divSize = liSize * v;                           // size of entire div(total length for just the visible items)

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        div.css(sizeCss, divSize+"px");                     // Width of the DIV. length of visible images

        if(o.btnPrev)
            $(o.btnPrev).click(function() {
                return go(curr-o.scroll);
            });

        if(o.btnNext)
            $(o.btnNext).click(function() {
                return go(curr+o.scroll);
            });

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        function go(to) {
            if(!running) {

                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to==o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -( (v) * liSize ) + "px" );
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to==itemLength-v+1 ? v+1 : v+o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first, and enable when not
                if(!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    $( (curr-o.scroll<0 && o.btnPrev)
                        ||
                       (curr+o.scroll > itemLength-v && o.btnNext)
                        ||
                       []
                     ).addClass("disabled");
                }

            }
            return false;
        };
    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};
function width(el) {
    return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
};
function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
};

})(jQuery);
