/*

Kinetics ajax/dhtml framework funcitons
CopyrightŪ Kinetics Multimedia (www.kinetics.com.br)

*/


/* basic browse components */

//gets up in the DOM hierachy and retrieve the component object
function getme( o, comptype )
{
	while( o != null && o != document.body )
	{
		if( isdefined( o.component ) && ( !isdefined( comptype ) || o.component.type == comptype ) )
		{
			return o.component;
		}
		o = o.parentNode;
	}
	return null;
}


//gets up in the DOM hierachy and retrieve the component object
// (with debug...)
function dgetme( o, comptype )
{
	debug( 'obj', o, 'type', comptype );
	while( o != null && o != document.body )
	{
		debug( 'oc', o.component );
		if( isdefined( o.component ) && ( !isdefined( comptype ) || o.component.type == comptype ) )
		{
			debug( 'found', o, o.tagName, o.id, o.className, 'component', o.component, 'type', o.component.type );
			return o.component;
		}
		debug( 'continuando', o.parentNode );
		o = o.parentNode;
		debug( 'up', o, o.tagName, o.id, o.className, 'component', o.component );
	}
	//debug( 'o',o,'o.parent', o.parentNode );
	return null
}

var componentvars = Array();

function browsecomponent( hang, title, script )
{
	this.type = 'browser';
	this.ajaxid = null;
	this.title = title;
	this.searchHTML = '';
	this.footerHTML = '';
	this.script = script;
	this.hang = hang;
	this.hang.className = 'browse';
	this.recs = Array();
	this.arecs = Array();
	this.firstrec = this.oldfirstrec = 0;
	this.totrec = -1;
	this.rows = 5;
	this.cols = 1;
	this.npages = 6;
	this.pagesize = this.rows*this.cols;
	this.direction = 0;
	this.numrec = this.pagesize*this.npages;
	this.txt_loading = 'Loading...';
	this.txt_notfound = 'No items found';
	this.drawn = false;
	this.debug_mode = false;
	this.parameters = new Object;
	this.tableview = false;
	this.force_col_width = [];
	this.tableview_col_padding = null;
	this.showlabels = false;
	this.last_click = -1;
	this.fill_void = false; 
	this.cellClassPrefix = '';
	this.ani = false;
	this.animating = false;
	this.a_orientation = -1;
	this.a_parc_clear = true;
	this.a_speed = 200;
	this.a_fade = true;
	this.a_transition = true;
	this.show_stack = [];
	this.a_topparc = [ .96, .87, .75, .50 ];
	this.a_botparc = [ .50, .25, .13, .04 ];
	if( !isdefined( hang.id ) || hang.id == '' ) hang.id = new Date().getTime();


	function mkid(v)
	{
		return [ '_', this.hang.id, v ].join('_');
	}

	function cname( s )
	{
		var ss = s.split( ' ' );
		return this.cellClassPrefix + ss.join( ' ' + this.cellClassPrefix );
	}

	function getdiv(v)
	{
		return $(this.mkid(v));
	}

	//process the ajax json output
	function result( txt )
	{
		var data = json( txt );
		if (data.status==0)
		{
			var tmp = this.txt_notfound;
			this.txt_notfound=data.errmess;
			this.notfound();
			this.txt_notfound = tmp;
			return;
		}
		if( (data.totrec == 0 || data.lastrec < 0) && this.txt_notfound > '' )
		{
			this.notfound();
			return;
		}
		data.firstrec *= 1;
		data.lastrec *= 1;
		data.totrec *= 1;
		this.labels = data.labels;
		for( var i = data.firstrec ; i <= data.lastrec ; i++ )
		{
			this.recs[i] = data.records[i-data.firstrec];
			this.arecs[i] = new Object;
			for( var r = 0 ; r < this.recs[i].length ; r++ )
				this.arecs[i][this.labels[r]] = this.recs[i][r];
		}
		this.totrec = data.totrec;
		if( this.firstrec >= this.totrec ) this.firstrec = this.totrec-1;
//		if( data.firstrec >= this.firstrec && data.firstrec <= (this.firstrec+this.numrec) )
//			this.show( data.firstrec );
		this.ajaxid = null;
		this.show( this.firstrec );
	}

	function savevars()
	{
		if( !isdefined( this.s_ident ) ) return;
		var save = new Object;
		save.firstrec = this.firstrec;
		save.last_click = this.last_click;
		save.parameters = this.parameters;
		savevar( 'browse_' + this.s_ident, jsonout( save ) );
	}

	function loadvars( s_ident, fromstart )
	{
		this.s_ident = s_ident;
		try
		{
//			var savedtxt = eval( 'browse_' + this.s_ident );
			var savedtxt = uservars['browse_' + this.s_ident];
			save = json( savedtxt );
			for (var v in save)	
				this[v] = save[v];
		}
		catch (e)
		{
		}
		if( fromstart == true )
		{
			this.firstrec = this.oldfirstrec = 0;
			this.last_click = -1;
		}
	}

	function ident( s_ident )
	{
		this.s_ident = s_ident;
	}

	function reset()
	{
		this.last_click = -1;
		this.firstrec = this.oldfirstrec = 0;
		this.totrec = -1;
		this.recs = Array();
		this.arecs = Array();
	}

	function refresh()
	{
		this.last_click = -1;
		this.recs = Array();
		this.arecs = Array();
		this.show();
	}

	//requests for a new set of records
	function get( idx )
	{
		if( this.ajaxid != null ) abort_ajax( this.ajaxid );
		this.pagesize = this.rows*this.cols;
		this.numrec = this.pagesize*this.npages;
		var frec = this.direction >= 0 ? this.firstrec : this.firstrec - this.numrec + this.pagesize;
		if( frec < 0 ) frec = 0;
		params = [];
		for (var p in this.parameters)
			params.push( p + '=' + this.parameters[p] );
		params = params.length ? '&' + params.join( '&' ) : '';
		var jpar = this.script.match( /\?/ ) ? '&' : '?';
		var url = this.script + jpar + 'numrec=' + this.numrec + '&firstrec=' + frec + params;
		if( this.debug_mode ) debug( '<a href="' + url + '" target="_blank">AJAX get</a>' );
		this.ajaxid = ajaxrequest( nocache(url), function( txt, browse ) { browse.result( txt ) }, this, 1 );
	}

	function nav( idx )
	{
		if( !isdefined( this.totrec ) || this.totrec <= 0 ) return '';
		var prev = idx > 0 ? '<div class="' + this.cname( 'b_prev' ) + '" onmousedown="return false;" onclick="getme(this).show(\'prev\')"></div>' : '<div class="' + this.cname( 'b_prev_off' ) + '" onmousedown="return false;" onclick="return false;"></div>';
		var next = idx+this.pagesize < this.totrec ? '<div class="' + this.cname( 'b_next' ) + '" onmousedown="return false;" onclick="getme(this).show(\'next\')"></div>' : '<div class="' + this.cname( 'b_next_off' ) + '" onmousedown="return false;" onclick="return false;"></div>';
		var idx2 = idx+this.pagesize;
		if( idx2 > this.totrec ) idx2 = this.totrec;
		var pos = (idx+1) + ' - ' + idx2 + ' of ' + (this.totrec);
		var output = '<div class="' + this.cname( 'b_nav' ) + '" onmousedown="return false;" onclick="return false;"><table class="' + this.cname( 'b_table' ) + '" cellpadding="0" cellspacing="0" border="0"><tr><td>' + prev + '</td><td><div class="' + this.cname( 'b_txt' ) + '">' + pos + '</div></td><td>' + next + '</td></tr></table></div>';
		return output;
	}

	function nav1( idx )
	{
		return this.nav( idx );
	}

	function nav2( idx )
	{
		return '';
	}

	function hide__( o )
	{
		if( isdefined(o.hidden) && o.hidden ) return;
//		debug('hide', o.id );
		o.hidden = true;
		o = o.parentNode;
		var prt = o.parentNode;
		o.prt = prt;
		prt.removeChild( o );
		prt.style.display = 'none';
		this.hiddenstuff.appendChild( o );
	}

	function unhide__( o )
	{
		if( !isdefined(o.hidden) || !o.hidden ) return;
//		debug('unhide', o.id );
		o.hidden = false;
		o = o.parentNode;
		var prt = o.parentNode;
		prt = o.prt;
		prt.style.display = '';
		this.hiddenstuff.removeChild( o );
		prt.appendChild( o );
	}

	function hide( o )
	{
		saveCSSValues( o, 'position,left,top,margin' );
		o.style.position = 'absolute';
		o.style.left = -3000;
		o.style.top = -3000;
		o.style.margin = 0;
		o.parentNode.parentNode.parentNode.hidden = 1;
	}

	function unhide( o )
	{
		restoreCSSValues( o );
		//this is a patch for chrome...
		if( browsername == 'chrome ' )
		{
			var tmp = function() {	po.innerHTML += '';  }
			var po = o.parentNode;
			if( po.clientWidth <= 1 )	
			{	
				setTimeout( tmp, 1 );
			}
		}
	}

	//display records in component content
	function show( idx )
	{

		function getCellPadding( obj, td )
		{
			if( ie ) obj.tableview_col_padding = 0;
			if( obj.tableview_col_padding == null && obj.force_col_width.length > 0 )
			{
				var div = ce( 'DIV' );
				div.className = obj.cname('label');
				var div2 = ce( 'DIV' );
				div2.className = obj.cname('cell');
				div2.id = 'bobo';
				div2.innerHTML = 'bobo';
				div.appendChild( div2 );
				td.appendChild( div );
				obj.tableview_col_padding =  getCSSValueNum( div2, 'paddingLeft' ) + getCSSValueNum( div2, 'paddingRight' );
				td.removeChild( div );
			}
		}
		nobubble();
		if( !this.drawn ) this.draw();
		if( !isdefined( idx ) )
		{
			this.loading();
			this.get( 0 );
			return;
		}
		if( this.a_orientation == -1 ) this.a_orientation = (this.tableview || !this.ani || this.rows >= this.cols ? 0 : 1);

		var fst = this.show_stack.length ? this.show_stack[this.show_stack.length-1] : this.firstrec;
		if( idx == 'next' && fst < ( this.totrec - this.pagesize ) )	idx = fst + this.pagesize;
		if( idx == 'prev' && fst > 0 ) idx = fst - this.pagesize;
		if( this.animating )
		{
			if( typeof( idx ) != 'string' && (this.show_stack.length == 0 || this.show_stack[0] != idx) ) this.show_stack.push( idx );
			return;
		}
		if( idx < 0 ) idx = 0;
		if( idx >= this.totrec && this.totrec > 0 ) idx = this.totrec - 1;
		this.firstrec = idx;

		this.savevars();

		var nav1 = this.nav1( idx );
		var nav2 = this.nav2( idx );

		var tabledrawn = this.getdiv( 'b_content_table' ) != null;
//		if( !this.ani ) tabledrawn = false;
		if( !tabledrawn )
		{
			var output = [];
			output.push( '<div><table cellpadding="0" cellspacing="0" border="0" class="b_content_table" id="' + this.mkid( 'b_content_table' ) + '">' );
			output.push( '</table></div>' );
			this.content.innerHTML = '<span id="' + this.mkid( 'nav1') + '">' + nav1 + '</span>' + output.join('') + '<span id="' + this.mkid( 'nav2') + '">' + nav2 + '</span>' + this.footerHTML;
			tabcontent = this.getdiv( 'b_content_table' );
			this.tabcontent = tabcontent;
			if( tabcontent != null )
			{
				tabcontent.className = 'b_content_table';
				var tbody = ce('TBODY');
				this.tbody = tbody;
				tabcontent.appendChild( tbody );
			}
		}
		else
		{
			this.getdiv('nav1').innerHTML = nav1;
			this.getdiv('nav2').innerHTML = nav2;
			tabcontent = this.getdiv( 'b_content_table' );
		}

		var i = idx;
		var tr, td;

		if( tabledrawn ) this.direction = this.firstrec > this.oldfirstrec ? 1 : -1;
		else this.direction = 0;


		if( !tabledrawn && this.showlabels && this.tableview && isdefined(this.tbody) )
		{
			this.tbody.appendChild(tr=ce('TR'));
			tr.appendChild(td=ce('TD'));
			getCellPadding( this, td );
			output = [ '<div id="' + this.mkid( 'labels' ) + '" class="' + this.cname('label') + '">' ];
			tds = this.table_labels();
			for( var c = 0 ; c < tds.length ; c++ )
			{
				var wid = this.force_col_width.length > c ? ' style="width: ' + (this.force_col_width[c]-this.tableview_col_padding) + 'px"' : '';
				if( c == tds.length-1 && wid == '' ) wid = ' style="width: auto"';
				output.push( '<div class="' + this.cname('cell') + '"' + wid + '>' + tds[c] + '</div>' );
			}
			output.push( '</div>' );
			td.innerHTML += output.join('');
		}
		
		var eof = false;
		dr = this.direction >= 0 ? 1 : -1;

		//if fistrec want drawn before
		var fr = this.showlabels?1:0;
		var rowidx = this.firstrec/this.cols;
//		debug( 'fr', fr, 'rowidx', rowidx );
		if( this.getdiv( this.firstrec ) == null && isdefined(this.tbody) )
		{
			var firstrow = this.tbody.rows[fr];
			for( var row = 0 ; row < this.rows ; row++ )
			{
				if( this.a_orientation == 1 && isdefined( this.tbody.rows[row] ) )
					tr = this.tbody.rows[row];
				else
				{
					tr=ce('TR');
					if( this.direction >= 0 )
					{
						if( this.tbody.rows.length == fr )
						{
							this.tbody.baseidx = rowidx;
						}
						this.tbody.appendChild(tr);
					}
					else
					{
						this.tbody.insertBefore(tr,firstrow);
						this.tbody.baseidx = rowidx;
					}
				}
				tr.style.width = 0;
				tr.style.margin = 0;
				tr.style.padding = 0;
				tr.style.border = 0;

				for( var col = 0 ; col < this.cols ; col++ )
				{
					if( i >= this.totrec ) { eof = true; }
					var rec = this.recs[i];
					var arec = this.arecs[i];
					if( isdefined( rec ) )
					{
						if( !this.tableview )
						{
							var cclick = i == this.last_click ? ' divclick item_click' :  '';
							if( row == 0 ) cclick += ' row0';
							if( col == 0 ) cclick += ' col0';
							var fcol = tr.cells.length > 0 ? tr.cells[col] : null;
							if( fcol == null ) this.fc = this.firstrec;
							if( this.a_orientation == 1 && this.direction < 0 && fcol != null )
							{
								tr.insertBefore(td=ce('TD'),fcol);
								this.fc = this.firstrec;
							}
							else
								tr.appendChild(td=ce('TD'));
							td.vAlign = 'top';
							td.style.margin = 0;
							td.style.padding = 0;
							td.style.width = 0;
							td.style.border = 0;
							var dcontainer = ce( 'DIV' );
							dcontainer.className = 'b_divcontainer';
							dcontainer.innerHTML = '<div id="' + this.mkid( i ) + '" class="' + this.cname( 'item cell ' + cclick ) + '" ' 
									 + 'onmouseover="getme(this).over( this, ' + i + ')" '
									 + 'onmouseout="getme(this).out( this, ' + i + ')" ' 
									 + 'onmousedown="getme(this).click( this, ' + i + ')">' 
									 +  this.cell( rec, arec, i ) + '</div>';
							td.appendChild( dcontainer );
							if( this.ani )
							{
								var d = this.getdiv( i );
								this.hide( d );
							}
						}
						else
						{
							var cclick = i == this.last_click ? ' rowclick' :  '';
							var cn = row & 1 ? 'odd' : 'even';
							if( row == 0 ) cclick += ' row0';
							tr.appendChild(td=ce('TD'));
							var dcontainer = ce( 'DIV' );
							dcontainer.className = 'b_divcontainer';
							output = [];
							output.push( '<div id="' + this.mkid( i ) + '" class="' + this.cname('row ' + cn + cclick ) + '" onmouseover="getme(this).over( this, ' + i + ')" onmouseout="getme(this).out( this, ' + i + ')" onmousedown="getme(this).click( this, ' + i + ')">' );
							var tds = this.table_row( rec, arec, i );
							getCellPadding( this, td );
							for( var c = 0 ; c < tds.length ; c++ )
							{
								var c0 = c == 0 ? ' col0' : '';
								var wid = this.force_col_width.length > c ? ' style="width: ' + (this.force_col_width[c]-this.tableview_col_padding) + 'px"' : '';
								if( c == tds.length-1 && wid == '' ) wid = ' style="width: auto"';
								output.push( '<div class="' + this.cname('cell' + c0) + '"' + wid + '>' + tds[c] + '</div>' );
							}
							output.push( '</div>' );
							dcontainer.innerHTML = output.join('');
							td.appendChild( dcontainer );
							if( this.ani ) this.hide( this.getdiv( i ) );
						}
					}
					else if( !eof )
					{
						this.get( this.firstrec );
						this.loading();
						return;
					}
					else if( this.fill_void )
					{
						var cclick = '';
						if( row == 0 ) cclick += ' row0';
						if( col == 0 ) cclick += ' col0';
						if( !this.tableview )
						{
							tr.appendChild(td=ce('TD'));
							td.vAlign = 'top';
							td.innerHTML = '<div class=b_divcontainer><div id="' + this.mkid( i ) + '" class="' + this.cname('item void' + cclick) + '"></div></div>';
						}
						else
						{
							var cn = row & 1 ? 'odd' : 'even';
							tr.appendChild(td=ce('TD'));
							output = [];
							output.push( '<div class=b_divcontainer><div id="' + this.mkid( i ) + '" class="' + this.cname('row ' + cn + ' void' + cclick) + '"><div class=cell>&nbsp;</div></div></div>' );
							td.innerHTML = output.join('');
						}
						if( this.ani ) this.hide( this.getdiv( i ) );
					}
					i++;
				}
			}
		}
		if( !this.ani )
		{
			if( this.a_orientation == 0 )
				for( var row = 0 ; row < this.rows ; row++ )
				{
					var myrow = fr+rowidx+row-this.tbody.baseidx;
					var ri = myrow - this.rows*dr;
//					if( ri >= fr && isdefined(this.tbody.rows[ri])) this.hide(this.tbody.rows[ri]);
//					this.unhide(this.tbody.rows[myrow]);
					if( ri >= fr && isdefined(this.tbody.rows[ri])) this.tbody.rows[ri].style.display = 'none';
					this.tbody.rows[myrow].style.display = '';
					i+=this.cols;
				}
			else
			{
				var mycol = (this.firstrec-this.fc)/this.cols;
				i = this.firstrec;
				for( var row = 0 ; row < this.rows ; row++ )
				{
					tr = this.tbody.rows[row];
					for( var col = 0 ; col < this.cols ; col++ )
					{
						d = this.getdiv( i );
						if( d != null )
						{
							td = d.parentNode.parentNode;
							td.style.display = '';
						}
						d = this.getdiv( i - dr*this.pagesize );
						if( d != null )
						{
							td = d.parentNode.parentNode;
							td.style.display = 'none';
						}
						i++;
					}
				}
			}
		}
		else
		{
			this.animate();
		}
//		debug( '<textarea> '+ this.content.innerHTML + '</textarea>' );
		this.oldfirstrec = idx;
	}

	function hidev( d, s, pos )
	{
		var pd = d.parentNode;
		if( s == 1 )
		{
			restoreCSSValues( pd );
			pd.style.height = '';
			pd.style.overflow = '';
			pd.style.opacity = '';
			pd.style.filter = '';
			restoreCSSValues( d )
			d.style.position = '';
			d.style.top = '';
			return;
		}
		saveCSSValues( pd, 'height,overflow,opacity,filter' );
		saveCSSValues( d, 'position,top' );
		if( pd.parentNode.clientHeight <= 1 ) s = 0;
		if( !isdefined( pd.s_height ) && pd.parentNode.clientHeight > 1)
			pd.s_height = pd.parentNode.clientHeight;
		var h = Math.floor( pd.s_height * s );
		if( h == 0 ) h = 1;
		pd.style.height = h;
		pd.style.overflow = 'hidden';
		if( this.a_fade )
		{
			pd.style.opacity= s;
			pd.style.filter = 'alpha(opacity=' + Math.floor(s*100) + ')';
		}
		var mt = pd.s_height - h;
		d.style.position = 'relative';
		if( !pos ) d.style.top = -mt;
		pd.style.overflow = 'hidden';
	}

	function hideh( d, s, pos )
	{
		var pd = d.parentNode;
		if( s == 1 )
		{
			pd.style.width = '';
			pd.style.overflow = '';
			pd.style.opacity = '';
			pd.style.filter = '';
			pd.style.display = '';
			d.style.position = '';
			d.style.left = '';
			return;
		}
		if( pd.parentNode.clientWidth <= 1 ) s = 0;
		if( !isdefined( pd.s_width ) && pd.parentNode.clientWidth > 1 )
			pd.s_width = pd.parentNode.clientWidth;
		var w = Math.floor( pd.s_width * s );
		if( w == 0 ) w = 1;
		pd.style.width = w;
		pd.style.overflow = 'hidden';
		if( this.a_fade )
		{
			pd.style.opacity= s;
			pd.style.filter = 'alpha(opacity=' + Math.floor(s*100) + ')';
		}
		var mt = pd.s_width - w;
		d.style.position = 'relative';
		if( !pos ) d.style.left = -mt;
		pd.style.overflow = 'hidden';
	}
	
	function animate( offset, repeat )
	{
		var obj = this;
		this.animating = true;

//		var increment = 1;
//		var cellcount = this.cols;
//		var hidefunc = this.hidev;

		this.tabwrapper = this.tabcontent.parentNode;
		if( this.a_orientation == 0 )
		{
			var increment = 1;
			var idxinc = this.cols;
			var cellcount = this.cols;
			this.hidefunc = this.hidev;
			var offsetcount = this.rows;
			this.tabwrapper.style.height = this.tabwrapper.clientHeight;
//			debug( this.tabwrapper.clientHeight );
			this.tabwrapper.style.overflow = 'hidden';
		}
		else
		{
			var idxinc = 1;
			var increment = this.cols;
			var cellcount = this.rows;
			this.hidefunc = this.hideh;
			var offsetcount = this.cols;
		}

		
		var now = new Date().getTime();
		var anirepeat = 0;
		if( !isdefined( offset ) )
		{
			offset = 0;
			this.a_parc = [];
			this.a_offset = [];
		}
		else
		{
			if( !isdefined( repeat ) )
			{
				var delay = now - this.a_time;
				anirepeat = Math.floor( delay/this.a_delay )-1;
			}
			else
			{
				anirepeat = --repeat;
			}
		}
		var show_stack = this.show_stack.length > 0;
		if( anirepeat < 0 || offset == 0 ) anirepeat = 0;
//		if( anirepeat > 0 ) anirepeat = 1;
//anirepeat = 0;

		if( anirepeat == 0 && !show_stack && this.a_parc_clear )
		{
			function parc( i, s, p )
			{
				if( offset == i && obj.a_offset[i] != 1 )
				{
					obj.a_parc = p;
					obj.a_offset[i] = 1;
				}
			}
			parc( 0, 0, [ .96, .87, .75, .50 ] );
			parc( 1, 2, [ .75, .50 ] );
			parc( 1, 3, [ .50 ] );
			parc( offsetcount-3, 3, [ .50, .25 ] );
			parc( offsetcount-2, 2, [ .50, .25, .13 ] );
			parc( offsetcount-1, 0, [ .50, .25, .13, .04 ] );
		}
		var endtransition = this.a_parc.length ? 0 : 1;
//endtransition = 1;
		if( anirepeat > 0 )
		{
			endtransition = 1;
			this.a_parc = [];
		}

		if( offset >= offsetcount && endtransition )
		{
//			this.tabwrapper.style.height = '';
//			this.tabwrapper.style.overflow = '';
			this.animating = false;
			if( show_stack ) this.show( this.show_stack.shift() );
			this.tabwrapper.style.height = this.tabcontent.clientHeight;
			return;
		}
		var off = offset;

		if( this.direction < 0 ) off = offsetcount - off - 1;

		var idx = off*idxinc + this.firstrec;

		if( !endtransition )
		{
			var a_parc_rate = this.a_parc.shift();
			var a_parc_dir = this.direction > 0 ? 0 : 1;
		}
		
		if( this.direction != 0 )
		{
			var firstd = null;
			for( i = 0 ; i < cellcount ; i++ )
			{
				var oldidx = (idx - this.direction*this.pagesize);
				var d = this.getdiv( oldidx + i*increment );
				if( firstd == null ) firstd = d;
				if( d != null )
				{
					if( endtransition )
					{
						if( this.a_orientation ) d.parentNode.parentNode.style.display = 'none'; //hide td
						else
							d.parentNode.parentNode.parentNode.style.display = 'none'; //hide tr
						this.hide( d );
					}
					else
						this.hidefunc( d, a_parc_rate, a_parc_dir );
				}
			}
			if( endtransition && firstd != null )
				firstd.parentNode.parentNode.parentNode.style.display = 'none';
		}
		var firstd = null;
		for( i = 0 ; i < cellcount ; i++ )
		{
			var d = this.getdiv( idx + i*increment );
			if( firstd == null && d != null )
			{
				firstd = d;
				firstd.parentNode.parentNode.parentNode.style.display = '';
			}
			if( d != null )
			{
				this.unhide( d );
				if( this.a_orientation ) d.parentNode.parentNode.style.display = '';
				else d.parentNode.parentNode.parentNode.style.display = ''
				if( endtransition )
				{
					this.hidefunc( d, 1, 1 );
//					debug( d.id, 1 );
				}
				else
				{
					this.hidefunc( d, 1-a_parc_rate, 1-a_parc_dir );
//					debug( d.id, 1-a_parc_rate );
				}
			}
		}
		var delay = Math.floor(this.a_speed/offsetcount)+1;
		this.a_parc_clear = endtransition;
		if( endtransition )	offset++;
		this.a_delay = delay;
		this.a_time = new Date().getTime();

		if( Math.abs( this.tabwrapper.clientHeight - this.tabcontent.clientHeight ) > 30 )
			this.tabwrapper.style.height = this.tabcontent.clientHeight;
/*
		var h = 0;
		var rows = this.tbody.rows;
		for( var i = 0 ; i < rows.length ; i++ )
		{
			if( !rows[i].hidden )
			{
				h += rows[i].clientHeight;
			}
		}
		if( h & 1 ) h++;
		var dtab = this.tabcontent.parentNode;
		dtab.style.height = h;
		dtab.style.overflow = 'hidden';
*/

		if( anirepeat > 0 )
			obj.animate(offset, anirepeat );
		else		
			setTimeout( function() { obj.animate(offset); }, delay );
	}

	//returns the the record HTML output
	function table_labels()
	{
		return this.labels;
	}

	//returns the the record HTML output
	function table_row( rec, arec, idx )
	{
		return rec;
	}

	//returns the the record HTML output
	function cell( rec, arec, idx )
	{
		return rec;
	}

	//cell mouse rollover event function
	function over( div, idx )
	{
		if( this.animating ) return;
//		debug( 'over', idx );
		if( div.tagName == 'TR' )
			addclass( div, this.cname("rowover") );
		else
			addclass( div, this.cname("divover item_sel") );
	}

	//cell mouse rolloout event function
	function out( div, idx )
	{
		if( this.animating ) return;
//		debug( 'out', idx );
		if( div.tagName == 'TR' )
			removeclass( div, this.cname("rowover") );
		else
			removeclass( div, this.cname("divover item_sel") );
	}

	//cell mouse click event function
	function click( div, idx )
	{
		if( this.animating ) return;
		if( this.last_click >= 0 )
		{
			var dclick = $(this.mkid(this.last_click));
			if( dclick != null )
			{
				removeclass( dclick, this.cname('rowclick') );
				removeclass( dclick, this.cname('divclick item_click') );
			}
		}
		if( div.tagName == 'TR' )
			addclass( div, this.cname("rowclick") );
		else
			addclass( div, this.cname("divclick item_click") );
		this.last_click = idx;
		if( this.debug_mode ) debug( 'click item', idx, div.id, div.className );
		this.savevars();
	}
	
	//loading message
	function loading()
	{
		this.content.innerHTML = '<div class="loading">' + this.txt_loading + '</div>';
		watch_animate( this.content, 0 );
	}

	//empty result message
	function notfound()
	{
		this.content.innerHTML = '<div class="notfound">' + this.txt_notfound + '</div>';
	}

	function search( frm )
	{
		var el = frm.elements;
		for( var i = 0 ; i < el.length ; i++ )
		{
			var name = el[i].name;
			var val = '';
			if( name.match( /^nothing/ ) ) continue;
			if( el[i].type == 'select-one' ) { val = el[i].options[el[i].selectedIndex].value }
			else if( el[i].type == 'radio' ) val = el[i].value;
			else if( el[i].type == 'checkbox' ) val = el[i].checked;
			else if( el[i].usevalue ) val = el[i].valueid;
			else val = el[i].value;

			var def = el[i].getAttribute( 'helper');
			if( val == def ) val = '';
			this.parameters[name] = val;
		}
		this.reset();
		this.show();
		return false;
	}

	function search_set_values()
	{
		frm = this.searcharea.getElementsByTagName("FORM")[0];
		var el = frm.elements;
		for( var i = 0 ; i < el.length ; i++ )
		{
			var name = el[i].name;
			var val = '';
			if( isdefined(this.parameters[name]) )
			{
				if( el[i].type == 'button' || el[i].type == 'submit' || el[i].type == 'reset' )
					;
				else if( el[i].type == 'select-one' )
				{ 
					el[i].setAttribute( 'defaultvalue', this.parameters[name] );
				}
				else if( el[i].type == 'radio' )
				{
					//need to make it work for radio
				}
				else if( el[i].type == 'checkbox' && isdefined(this.parameters[name]) ) el[i].checked = this.parameters[name];
				else if( isdefined(this.parameters[name]) )
				{
					el[i].value = this.parameters[name];
				}
			}
		}
	}


	//draw the component inside the hang div
	function draw()
	{
		this.hang.innerHTML = '';
		this.hang.component = this;
		this.head  = ce( 'DIV' );
		this.searcharea  = ce( 'DIV' );
		this.content = ce( 'DIV' );

		this.head.className = 'b_head';
		this.searcharea.className = 'b_search';
		this.content.className = 'b_content';
		this.hang.appendChild( this.head );
		this.hang.appendChild( this.searcharea );
		this.hang.appendChild( this.content );
		if( this.ani )
		{
			this.hiddenstuff = ce( 'DIV' );
			this.hiddenstuff.style.position = 'absolute';
			this.hiddenstuff.style.top = -40000;
			this.hiddenstuff.style.left = -40000;
			this.hiddenstuff.style.background = 'red';
			this.hang.appendChild( this.hiddenstuff );
		}

		this.searcharea.innerHTML = this.searchHTML;
		if( this.title != '' )
			this.head.innerHTML = this.title;
		else
			this.head.style.display = 'none';

		if( this.searchHTML != '' )
		{
			this.searcharea.innerHTML = '<form onsubmit="getme(this).search(this); return false">' + this.searchHTML + '</form>';
			this.search_set_values();
			formformat( this.searcharea );
			this.searchform = this.searcharea.getElementsByTagName("FORM")[0];
		}
		else
			this.searcharea.style.display = 'none';

		this.content.innerHTML = '';
		this.drawn = true;
	}

	this._show = this.show = show;
	this._nav = this.nav = nav;
	this._nav1 = this.nav1 = nav1;
	this._nav2 = this.nav2 = nav2;
	this._cell = this.cell = cell;
	this._get = this.get = get;
	this._result = this.result = result;
	this._search = this.search = search;
	this._search_set_values = this.search_set_values = search_set_values;
	this._draw = this.draw = draw;
	this._loading = this.loading = loading;
	this._notfound = this.notfound = notfound;
	this._over = this.over = over;
	this._out = this.out = out;
	this._click = this.click = click;
	this._reset = this.reset = reset;
	this._loadvars = this.loadvars = loadvars;
	this._savevars = this.savevars = savevars;
	this._ident = this.ident = ident;
	this._refresh = this.refresh = refresh;
	this._table_labels = this.table_labels = table_labels;
	this._table_row = this.table_row = table_row;
	this.cname = cname;
	this.getdiv = getdiv;
	this.mkid = mkid;
	this.cname = cname;
	this.animate = animate;
	this.hidev = hidev;
	this.hideh = hideh;
	this.hide = hide;
	this.unhide = unhide;
	return this;
}

function tableview( hang, title, script )
{
	var obj = new browsecomponent( hang, title, script );
	obj.tableview = true;
	obj.showlabels = true;
	obj.rows = 20;
	obj.cols = 1;
	obj.hang.className += ' tableview';
	return obj;
}

/* basic tab object */

function tabbar( hang, opts )
{
	this.hang = hang;
	this.opts = opts;

	this.type = 'tabbar';
	var tabdiv = ce( 'DIV' );
	tabdiv.component = this;
	tabdiv.className = 'tab';
	this.tabdiv = tabdiv;
	this.tabopts = opts;
	this.drawn = false;

	function draw()
	{
		this.drawn = true;
		var items = ce( 'DIV' ); items.className = 'tab_items';
		var table = ce( 'TABLE' ); table.className = 'tab_table'; items.appendChild( table );
		table.cellPadding = table.cellSpacing = table.border = 0;
		var tb = ce( 'TBODY' ); table.appendChild( tb );
		var tr = ce( 'TR' ); tb.appendChild( tr );
		for( var i = 0 ; i < this.opts.length ; i++ )
		{
			var td = ce( 'TD' );
			tr.appendChild( td );
			var item = ce( 'DIV' ); item.className = 'tab_item'; td.appendChild( item );
			item.innerHTML = this.opts[i].label;
			item.idx = i;

			var itemdiv = ce( 'DIV' ); itemdiv.className = 'tab_content';
			this.opts[i].item = item;
			this.opts[i].drawn = false;
			this.tabdiv.appendChild( itemdiv );
			itemdiv.innerHTML = 'bababa';
			this.opts[i].itemdiv = itemdiv;
			item.onclick = function() { getme(this).select( this.idx ); };
		}

		this.tabdiv.appendChild( items );
		this.hang.appendChild( this.tabdiv );
	}

	// selects a tab
	function select( idx )
	{
		if( !this.drawn ) this.draw();

		for( var i = 0 ; i < this.tabopts.length ; i++ )
		{
			var opt = this.tabopts[i];
			if( i == idx )
			{
				opt.item.className = 'tab_item_sel';
				opt.itemdiv.style.display = 'block';
				this.currentdiv = opt.itemdiv;
				if( !opt.drawn )
				{
					if( isdefined( opt.html ) )
					{
						opt.itemdiv.innerHTML = opt.html;
					}
					if( isdefined( opt.script ) )
					{
						var ns = ce('SCRIPT');
						ns.type = 'text/javascript';
						ns.text = opt.script;
						document.body.appendChild( ns );
					}
					if( isdefined( opt.load ) )
					{
						opt.itemdiv.innerHTML = '<div class="loading">Loading...</div>';
						var url = nocache(opt.load);
						ajaxrequest( url, 'resultform', opt.itemdiv, 0 );
					}
					if( isdefined( opt.sticky ) && opt.sticky == true )
						opt.drawn = true;
				}
			}
			else
			{
				opt.item.className = 'tab_item';
				opt.itemdiv.style.display = 'none';
			}
		}
	}

	//loads the url on a "notab" div under tabbar. All tabs get unselected
	function loadurl( url )
	{
		this.currentdiv.innerHTML = '<div class="loading">Loading...</div>';
		this.currentdiv.style.display = 'block';
		ajaxrequest( nocache(url), 'resultform', this.currentdiv, 0 );
	}
	this.loadurl = loadurl;
	this.draw = draw;
	this.select = select;
	return this;
}

/* specific tab components */

function maintabbar( hang, opts )
{
	var tab = new tabbar( hang, opts );
	tab.tabdiv.className += ' maintab';
	return tab;
}


function subtabbar( hang, opts )
{
	var tab = new tabbar( hang, opts );
	tab.tabdiv.className += ' subtab';
	return tab;
}

/* ------------------------------------ end basic browse components --------------------------*/


var collapsible = new function ()
{
	this.ani = 1;
	this.a_fade = true;
	this.save = 1;
	function make( d, s )
	{
		if( isdefined( d.collapsibleDiv ) ) return;
		if( !isdefined( s ) )
		{
			try
			{
				s = uservars['collapsible_'+d.id] != 0 ? 1 : 0;
			}
			catch( e ) { s = 1; }
		}
		var par = d.parentNode;
		var nextDiv = null;
		for( var i = 0 ; i < par.childNodes.length ; i++ )
			if( par.childNodes[i] == d ) break;
		for( i++ ; i < par.childNodes.length ; i++ )
			if( par.childNodes[i].tagName == 'DIV' )
			{
				nextDiv = par.childNodes[i];
				break;
			}
		if( nextDiv == null ) return;
		d.collapsible_div = nextDiv;
				
		var div = ce( 'DIV' );
		div.className = 'collapsible_button';
		d.appendChild( div );
		d.collapsibleDiv = div;
		if( !isdefined( s ) ) s = 1;
		if( !d.className.match( /wide/ ) )
			d._width = d.style.width = ie ? d.collapsible_div.clientWidth : d.collapsible_div.clientWidth - 22;
		else
			d._width = d.offsetWidth;
		var obj = this;
		d._onclick = d._onmousedown = null;
		if( isfunction(d.onclick) ) d._onclick = d.onclick;
		if( isfunction(d.onmousedown) ) d._onmousedown = d.onmousedown;
		d.onclick = function(ev) { obj.click( this ); if( this._onclick != null ) this._onclick(ev); };
		d.onmousedown = function(ev) { if( this._onmousedown != null ) this._onmousedown(ev); return false; };
		d.onstartdrag = function() { return false; };
		d.onmouseover = function() { addclass( this, 'collapsible_over' ); };
		d.onmouseout = function() { removeclass( this, 'collapsible_over' ); };
		this.set( d, s, 1 );
	}

	function aniinout( d, h, s )
	{
		if( h == 0 )
		{
			d.style.position = '';
			d.style.top = '';
			d.style.left = '';
			d.style.overflow = 'hidden';
			if( !isdefined( d.sh ) ) d.sh = d.clientHeight;
			d.ch = s > 0 ? 0 : d.sh;
			h = d.sh/5;
			if( h < 10 ) h = 10;
			h *= s;
		}
		d.ch += h;
		if( d.ch <= 0 )
		{
			hide( d );
			return;
		}
		if( d.ch >= d.sh )
		{
			unhide( d );
			return;
		}
		d.style.height = d.style.minHeight = d.ch;
		if( this.a_fade )
		{
			var op = d.ch / d.sh;
			d.style.opacity= op;
			d.style.filter = 'alpha(opacity=' + Math.floor(op*100) + ')';
		}
		var obj = this;
		setTimeout( function() { obj.aniinout( d, h, s ) }, 20 );
	}

	function hide( d )
	{
		d.style.position = 'absolute';
		d.style.top = -3000;
		d.style.left = -3000;
	}

	function unhide( d )
	{
		d.style.position = '';
		d.style.top = '';
		d.style.left = '';
		d.style.overflow = '';
		d.style.height = '';
		d.style.minHeight = '';
		d.style.opacity = '';
		d.style.filter = '';
	}
	function set( d, s, first )
	{
		d.collapsibleDiv.innerHTML = s ? '[-]' : '[+]';
		d.collapsibleStatus = s;
		if( !first && this.save ) savevar( 'collapsible_' + d.id, s );
		if( first != 1 && this.ani )
		{
			if( s ) this.aniinout( d.collapsible_div, 0, 1 );
			else this.aniinout( d.collapsible_div, 0, -1 );
		}
		else
		{
			if( s ) unhide( d.collapsible_div );
			else hide( d.collapsible_div );
		}
		if( s ) addclass( d, 'collapsible_open' );
		else removeclass( d, 'collapsible_open' );
		//d.style.width = d.clientWidth;
	}

	function click( d )
	{
		this.set( d, 1-d.collapsibleStatus );
	}

	this.make = make;
	this.set = set;
	this.click = click;
	this.aniinout = aniinout;

	return this;
}
