
PA.makeNS( 'PA.widgets.CollapsibleTable' );

PA_widgets_CollapsibleTable_getInStateIndex = function( n, expanded ) {		// returns 0 if row doesn't exist and +/-1 if expanded/collapsed
	var t 					= this;
	var row					= t.doc.getElementById( t._getRowId( n ) );
	var shown 				= 0;
	if( row && row.firstChild ) {
		var el	 			= row.firstChild;	// wrapper div
		var m				= ( '' ==  el.style.marginTop ? 0 : parseInt( el.style.marginTop ) );
		if( expanded && m >= 0 ) {
			shown 				= 1;
		}
		if( !expanded && m < 0 ) {
			shown 				= -1;
		}
	}
	return shown;
}

PA_widgets_CollapsibleTable_collapse = function( el, el2, expand, cb ) {
////	return PA.utils.DOM.toggleDisplay( el, expand );
	if( !el || !el2 ) {
		if( cb ) { 
			cb();
		}
		return;
	}
	var toggle			= el2.firstChild;
	toggle.className	= 'rowToggle ' + ( expand ? 'hide' : 'show' );

	el 					= el.firstChild;	// wrapper div
	var m				= ( expand ? 0 : - el.offsetHeight );
	var slide 			= new Fx.Tween( el, { 
		duration: 	150, 
		transition:	'quad:in:out',
		onComplete: cb
	} );
	
	slide.start( 'margin-top', m ); 
	return ( !expand );
}

PA.widgets.CollapsibleTable = function( doc, handlerFnName, idObj, idTarget, tableClass, rowHdrClass, rowClasses, captionClass, rowData, captionData, initialState, initialStateTbl ) {

	var t			= this;
	
	t._init = function() {
		var t			= this;
		t.doc			= doc;
		t.id			= idObj; 
		t.idTarget		= idTarget; 
		t.tableClass	= tableClass;
		t.rowClasses	= rowClasses;
		t.rowHdrClass	= rowHdrClass;
		t.captionClass	= captionClass;
		t.rowData		= rowData;
		t.captionData	= captionData;
		t.handlerFnName	= handlerFnName;
		t._collapse		= PA_widgets_CollapsibleTable_collapse;
		t._getInStateIndex	= PA_widgets_CollapsibleTable_getInStateIndex;
		t._nRows		= ( t.rowData ? t.rowData.length : 0 );		// max number of rows; actual amount of rows can be less
		t._prevState	= initialState;
		t._prevStateTbl	= initialStateTbl;
		return 0;
	}	
	
	t.render = function() {
		var t						= this;
		var target					= t.doc.getElementById( t.idTarget );
		if( target ) {
			target.style.display	= ( t._prevStateTbl ? 'block' : 'none' );
			target.innerHTML		= t.getHtml();
		}
	}
	
	t.getHtml = function() {
		var t			= this;
		var rCls		= t.rowClasses;
		var i			= 0;
		var html	 	= '';
		var display 	= ( t._prevState ? 'block' : 'none' );
		var noCollapse	= ( t._prevState < 0 );
		if( t.captionData && t.captionClass ) {
			var txt		= ( noCollapse ? t.captionData[0] : t.captionData[ t._prevState ] );
			html		+= 	'<div><table cellpadding=0 cellspacing=0><tr>' + 
								'<td class=' + t.captionClass[0] + ' id="' + t._getLeftCaptionId() + '">&nbsp;</td><td style="width:100%">&nbsp;</td>' +
								'<td class=' + t.captionClass[1] + '>' +
									'<span class="captionText"><nobr>' +
										( noCollapse ? txt : '<a href="javascript:void(0);" id="' + t._getRightCaptionId() + '" class="' + t.rowHdrClass + '" onclick="' + t.handlerFnName + '(\'' + t.id + '\')">' + txt + '</a>' ) +
									'</nobr></span>' +
								'</td>' +
							'</tr></table></div>';
							
//			html		+= 	'<div class=' + t.captionClass[0] + ' id="' + t._getLeftCaptionId() + '">&nbsp;</div>';	
//			html		+= 	'<div class=' + t.captionClass[1] + '>' +
//								'<span class="captionText"><a href="javascript:void(0);" id="' + t._getRightCaptionId() + '" class="' + t.rowHdrClass + '" onclick="' + t.handlerFnName + '(\'' + t.id + '\')">' + 
//									t.captionData[ t._prevState ] + 
//								'</a></span>' +
//							'</div>';	
		}
		html			+= 	'<div class="' + t.tableClass + '" id=' + t._getTblId( i ) + '>';
		for( i=0; i<t._nRows; i++ ) {
			var rCl		= rCls[ i % rCls.length ];
			var hdr		= t.rowData[i][0];
			var data	= t.rowData[i][1];
			var inact 	= ( t.rowData[i][2] || noCollapse );
			var show	= ( inact ? 'block' : display );	// override generic initial display settings for particular row
			if( hdr ) {
				var txt	= ( inact ? hdr : '<a href="javascript:void(0);" class="' + t.rowHdrClass + '" ' + ( inact ? '' : 'onclick="' + t.handlerFnName + '(\'' + t.id + '\',' + i + ')"' ) + '>' + hdr + '</a>' );
				html	+= 	'<div id=' + t._getHdrId( i ) + ' class="' + rCl + ' header">' + 
								'<span class="headerText">' + txt + '</span>' +
							'</div>';
			}
			if( data ) { 
				html	+= 	'<div id=' + t._getRowId( i ) + ' class="' + rCl + '" style="display:' + show + '"><div class=wrap>' + data + '</div></div>';
			}
		}
		html 			+= 	'</div>';
		return html;
	}

	t._getNCollapsibleRows = function() {
		var t 			= this;
		var n	 		= 0;
		for( var i=0; i<t._nRows; i++ ) {
			var row		= t.doc.getElementById( t._getRowId( i ) );
			n 			+= ( row && row.firstChild ? 1 : 0 );
		}
		return n;
	}
	
	t._toggleRowDOM = function( n, state, cb ) {
		var t	= this;
		return t._collapse( t.doc.getElementById( t._getRowId( n ) ), t.doc.getElementById( t._getRowHdrId( n ) ), state, cb );
	}
	
	t.toggleRow = function( n, state ) {
		var t		= this;
		var rv		= 0;
		if( 'undefined' == typeof( n ) ) {
			rv		= t.toggleAllRows();
		} else {
			state 	= ( t._getInStateIndex( n, state ) < 0 );
			t._toggleRowDOM( n, state, function() { t._checkCaption( state ) } );
		}
		return rv;
	}

	t._checkCaption = function( state ) {
		var t 				= this;
		if( t._areAllRowsInState( state ) ) { 
			t._changeCaption( state );
		}	
	}
	
	t._changeCaption = function( state ) {
		var t 					= this;
		t._prevState	 		= ( state ? 1 : 0 );
		var caption				= t.doc.getElementById( t._getRightCaptionId() );
		if( caption && 'undefined' != typeof( t.captionData[ t._prevState ] ) ) {
			caption.innerHTML	= t.captionData[ t._prevState ];
		}		
	}

	t._areAllRowsInState = function( state ) {
		var t			= this;
		var index 		= 0;
		for( var i=0; i<t._nRows; i++ ) {
			index 		+= t._getInStateIndex( i, state );
		}
		var count 		= t._getNCollapsibleRows();
		return ( index == ( state ? 1 : -1 ) * count );
	}
	
	t.toggleAllRows = function( state ) {
		var t			= this;
		var show		= ( 'undefined' == typeof( state ) ? !t._prevState : state );
				
		var i 			= -1;
		while( i < t._nRows-2 ) {
			i++;
			if( 'undefined' != typeof( show ) ) { 	// protection from infinite loop
				if( t.rowData[i] && t.rowData[i][2] ) {			// uncollapsable rows
					continue;
				}
				t._toggleRowDOM( i, show );
			}
		}

		t._toggleRowDOM( t._nRows-1, show, function() { t._changeCaption( show ) } );	//  to fire callback only once
		return show;
	}

	t.toggleTable = function( state ) {
		var t			= this;
		var show		= ( 'undefined' == typeof( state ) ? !t._prevStateTbl : state );
		t._prevStateTbl	= ( show ? 1 : 0 ); 
		return t._collapse( t.doc.getElementById( t.idTarget ), show );
	}

	t._getRowId = function( n ) {
		return this.id + '_row' + n;
	}
	
	t._getRowHdrId = function( n ) {
		return this.id + '_hdr' + n;
	}
	
	t._getTblId = function() {
		return this.id + '_tbl';
	}

	t._getRightCaptionId = function() {
		return this.id + '_rcap';
	}

	t._getLeftCaptionId = function() {
		return this.id + '_lcap';
	}

	t._getHdrId = function( n ) {
		return this.id + '_hdr' + n;
	}
		
	if( !t._init() ) {
		t = null;
	}
}

