String.prototype.trim = function() {
  var i = 0, j = 0;
  while ( this.charAt(i)==" " ) i++;
  j = this.length-1;
  while ( this.charAt(j)==" " ) j--;
  return this.substring(i,j+1);
} 

// JavaScript Document

	// colors to use for the types of seats
	var SeatColors = { 
		 season:	'#F7ABA9'
		,sold:		'#d06060'
		,comp:		'#ff0000'
		,pending:	'#8c8a00'
		,reserved:	'yellow'
		,seat:		'#D0D0D0'			
		,starter:	'#80c080'
		,aisle: 	'white'
		,outstanding: '#6666ff'
	};
	var OptionColors = [ '#8c0070', '#d000a6', '#ff2bd5' ];
	
	// map a single character to a color
	var SeatTypeColorMap = {
		 'a'	: SeatColors.aisle
		,'g'	: SeatColors.available
		,'s'	: SeatColors.seat
		,'*'	: SeatColors.starter
		,'c'	: SeatColors.comp
		,'p'	: SeatColors.pending
		,'$'	: SeatColors.sold
		,'r'	: SeatColors.reserved
		,'y'	: SeatColors.season
		,'o'	: SeatColors.outstanding
	};
	//  just some nice blues	#38008c #4e00d0

function DrawSeatLegend(){
	document.write( '<table class="seat_legend"><tr>' );
	for( var key in SeatColors ){
		document.write( '<td style="background-color:'+SeatColors[key]+';"></td>' );
		document.write( '<th>'+key+'</th>' );
	}
	document.write( '</tr></table>' );
}

//	var OptionColors = [ '#00B0A6', '#2EB000', '#B0AE00' ];
	var OptionColors = [ '#00FFFF', '#0099FF', '#0033FF' ];

//-----------------------------------------------------------------------------------
// class Chart                                                                       
//-----------------------------------------------------------------------------------
function Chart( table_id ){

	// init base stuff so we can call GetSeat();
	this.table = document.getElementById( table_id );
	this.row_count = this.table.rows.length;
	this.col_count = this.table.rows[0].cells.length;
	this.index_count = this.row_count * this.col_count;
	this.reverse_columns = false;
	this.text_find = new Object();
}

Chart.prototype.GetSeat       = function( index ){ 
	var col = index%this.col_count;
	if( this.reverse_columns ) col = this.col_count - 1 - col;
	return this.table.rows[ this.GetRow( index ) ].cells[ col ].childNodes[0]; 
}

Chart.prototype.GetRow = function( index ){	return Math.floor( index/this.col_count );	}

// ----- Color -----
Chart.prototype.SetSeatColor  = function( index, value )      { this.GetSeat( index ).style.backgroundColor = value; }
Chart.prototype.SetSeatsColor = function( index_array, value ){ for( var i=0; i<index_array.length; ++i ){ this.SetSeatColor( index_array[i], value          ); } }
Chart.prototype.LoadSeatColor = function( value_array )       { for( var i=0; i<value_array.length; ++i ){ this.SetSeatColor( i,              value_array[i] ); } }

// ----- Text -----
Chart.prototype.SetSeatText   = function( index, value )      { 
	var seat = this.GetSeat( index );
	if( seat.nodeName == 'DIV' ){
		seat.innerHTML = value;
	} else {
		seat.value = value ; 
	}
	this.text_find[ value.toLowerCase() ] = index;	// store so we can find if fast
}
Chart.prototype.GetSeatText  = function( index ) {
	var seat = this.GetSeat( index );
	if( seat.nodeName == 'DIV' ){
		return seat.innerHTML;
	} else {
		return seat.value;
	}
}
Chart.prototype.SetSeatsText  = function( index_array, value ){ for( var i=0; i<index_array.length; ++i ){ this.SetSeatText( index_array[i], value          ); } }
Chart.prototype.LoadSeatText  = function( value_array )       { for( var i=0; i<value_array.length; ++i ){	this.SetSeatText( i,              value_array[i] );	} }
Chart.prototype.SaveSeatText  = function( value_array )       { for( var i=0; i<value_array.length; ++i ){	value_array[i]=this.GetSeat( i ).value;			} }
Chart.prototype.FindSeatText  = function( needle ){
	if( (needle==null) || (needle.length==0) ) return null;
	return this.text_find[ needle.toLowerCase() ];
}

// ----- Border Color ----
Chart.prototype.SetSeatBorderColor= function( index, value )      { this.GetSeat( index ).style.borderColor = value; }
Chart.prototype.SetSeatsBorderColor=function( index_array, value ){ for( var i=0; i<index_array.length; ++i ){ this.SetSeatBorderColor( index_array[i], value ); } }





//---------------------------------------------------------------------------------------------------------
//   class Selecter                                                                                        
//---------------------------------------------------------------------------------------------------------

function Selecter( chart ){
	this.chart = chart;

	this.selected = new Array( this.chart.index_count );

	this.notify = true; // of changes
	this.dirty = false; 
	this.SelectedColor = 'black';

	// point all of the seats to call the .Click function
	for( var ii=0; ii<this.selected.length; ++ii ){
		var seat = this.chart.GetSeat( ii );
		seat.chart = this;
		seat.onclick = new Function( 'this.chart.Click('+ii+')' );
	}
	
}
Selecter.prototype.Notify = function(){}
Selecter.prototype.Selectable = function( index ) { return true; }// override  this function to prevent certain cells from being selected / deselected
Selecter.prototype.Click = function( index ){
	this.SetSelect( index, !this.selected[ index ] );
}
Selecter.prototype.SetSelect = function( index, isSelected ){ 
	if( !this.Selectable( index ) ) return;		
	var dirty = (this.selected[ index ] != isSelected);
	this.selected[ index ] = isSelected; 
	this.chart.SetSeatBorderColor( index, isSelected ? this.SelectedColor : 'white' ); 
	if( dirty ) {
		if( this.notify ){ this.Notify(); } else { this.dirty = true; }
	}
}

Selecter.prototype.SuspendNotify = function (){ this.notify = false; }
Selecter.prototype.ResumeNotify = function (){ this.notify=true; if( this.dirty ) { this.Notify(); this.dirty=false; } }

Selecter.prototype.SetSelectAll = function( bSelectedState ){ this.SuspendNotify(); for( var index in this.selected ){ this.SetSelect( index, bSelectedState ); } this.ResumeNotify();	}
Selecter.prototype.SetSelectIndexes = function( indexes, bSelectedState ){ this.SuspendNotify(); for( var index in indexes){ this.SetSelect( indexes[index], bSelectedState ); } this.ResumeNotify(); }
Selecter.prototype.GetSelectedIndexes = function(){ var a = new Array(); for( var index in this.selected ){ if( this.selected[ index ] ) a.push( index ); } return a; }
Selecter.prototype.ClearAll = function(){ this.SuspendNotify(); for( var index in this.selected ){ if( this.selected[ index ] ) this.SetSelect( index, false ); } this.ResumeNotify(); }
Selecter.prototype.SelectRange = function( low, high ){
	this.SuspendNotify();
	if( low > high ){	var temp = low;	low = high;	high = temp; }
	for( var index=low; index<=high; ++index ){	this.SetSelect( index, !this.selected[ index ] );	}
	this.ResumeNotify();
}


//---------------------------------------------------------------------------------------------------------
//   class SeatTypes                                                                                       
//---------------------------------------------------------------------------------------------------------
function SeatTypes( chart ){
	this.chart = chart;
	this.types = new Array( this.chart.index_count );
}
SeatTypes.prototype.SetSeatType = function( index, value ){ this.types[ index ]=value;	this.chart.SetSeatColor( index, SeatTypeColorMap[ value ] );	}
SeatTypes.prototype.GetSeatType = function( index ){ return this.types[ index ]; }
SeatTypes.prototype.SetSeatsType = function( index_array, value ){ for( var i=0; i<index_array.length; ++i ){	this.SetSeatType( index_array[i],    value ); } }
SeatTypes.prototype.LoadSeatType = function( value_array ) { for( var i=0; i<value_array.length; ++i ){ this.SetSeatType( i, value_array[i] ); } }





//--------------------------------------
//  Selections (Set / Clear)            
//--------------------------------------

function SetSelectedSeatTypeAndClear( selected_obj, seating_obj, value ){ 
	var selected = selected_obj.GetSelectedIndexes();	// get selection
	selected_obj.SetSelectIndexes( selected, false );	// clear selection
	seating_obj.SetSeatsType( selected, value );		// change state of selection
}

// saves the old assigned array, sets the new array, and loads its text into the table
var currentTextAssignment = null;
function AssignSeatText( newAssignment, selecter ){
	if( currentTextAssignment != null ){
		selecter.chart.SaveSeatText( currentTextAssignment );
	}
	currentTextAssignment = newAssignment;
	selecter.chart.LoadSeatText( currentTextAssignment );
}

function SetSelectedText( value, selecter ){
	var selected = selecter.GetSelectedIndexes();
	selecter.SetSelectIndexes( selected, false );
	selecter.chart.SetSeatsText( selected, value );
}



//--------------------------------------------------
//  Misc                                            
//--------------------------------------------------


// !! Don't Delete - VERY USEFUL
function ShowParts(obj,show_functions){
	var keys = new Array();
	// get keys
	for(key in obj){	try{  if( typeof obj[key] != 'function' || show_functions ) keys.push( key ); } catch(ex){}	}
	// sort them
	keys.sort( function ( a, b ){ return a-b; } );

	// display them
	var k = ''; 
	var count = 0;
	for(index in keys) {
		var key = keys[index];
		var t = typeof obj[key];
		k = k + key +'(' + t + ') =' + obj[key] + "\r\n";
		if( ++count == 20 ){ 
			if( confirm(k)==false ) return;
			k='';count=0;
		}
	}
	if( count != 0 ) alert( k );
}


var Now = new Date();

function Popup( url ) {	
	var load = window.open( url, '', 'scrollbars=yes,menubar=no,height=600,width=800,resizable=yes,toolbar=no,location=no,status=no');	
}


// checks if the date is valid
// used when creating performances and order_edit
function ValidateDate( mm, dd, yyyy ){
	yyyy = parseInt( yyyy );
	if( yyyy < 100 ) {
		yyyy += 2000;
	}
	var tst = new Date(yyyy,mm-1,dd);
	if( (mm==tst.getMonth()+1) && (dd==tst.getDate()) && (yyyy==tst.getFullYear()) ) return true;
	alert( 'Invalid Date: '+mm+'/'+dd+'/'+yyyy );
	return false;
}


// places the specified date in the given form
function FillDate( form, group_name, date ) {
	form[group_name+'m'].value = (date!=null) ? (date.getMonth()+1)  : '';
	form[group_name+'d'].value = (date!=null) ? (date.getDate())     : '';
	form[group_name+'y'].value = (date!=null) ? (date.getFullYear()) : '';
}




//===========================================
// For drawing the time counter
function GetAnchorByName( name ){
	var o = document.getElementById( name );	// IE
	if( o == null ){
		o = document.getElementsByName( name )[0];	// netscape / firefox
	}
	return o;
}

var remaining_seconds;
function ShowRemainingTime( init_secs, new_location ){
	if( init_secs != null ) remaining_seconds = init_secs;
	if( remaining_seconds == -1 ){
		window.location=new_location;
	} else {
		var m = Math.floor(remaining_seconds/60);
		var s = remaining_seconds - (m*60);	
		if( s<10 ) s = '0' + s;
		GetAnchorByName( 'minutes' ).innerHTML = m;
		GetAnchorByName( 'seconds' ).innerHTML = s;
		--remaining_seconds;
		setTimeout( "ShowRemainingTime(null,'"+new_location+"')", 1000 );
	}
}
