/**
	JS Debug Console
	
	@author	Brian Grayless
			Copyright 2000-2005 (c) Sunergize Inc.
			Visit http://www.sunergize.com
 	 				
 	@license	This library is free software; you can redistribute it and/or
			modify it under the terms of the GNU Lesser General Public
			License as published by the Free Software Foundation; either
			version 2.1 of the License, or (at your option) any later version.
			
			This library is distributed in the hope that it will be useful,
			but WITHOUT ANY WARRANTY; without even the implied warranty of
			MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
			Lesser General Public License for more details.
			
			If you did not receive a copy of the GNU Lesser General Public
			License along with this library, write to the Free Software
			Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
function Js_Debug(debug_mode, error_array)
{
	// track number of output messages (starts over on page load)
	this.output_num = 0;
	
	// set display values
	this.display = new Object();
	this.display.primary_row_color = '#EEEEEE';
	this.display.alt_row_color = '#DDDDDD';
	
	// set error array if exists
	if(error_array)
	{
		this.error_array = error_array;	
	}
	
	// set debug mode
	switch(true)
	{
		case ((debug_mode == false) || (debug_mode === 0)):
			this.debug_mode = 0;
			break;
		case ((debug_mode == true) || (debug_mode === 0)):
			this.debug_mode = 1;
			break;
		case (debug_mode > 1):
			this.debug_mode = debug_mode;
			break;
	}
	
	js_inst = this;
	if(this.debug_mode > 0)
	{
		this._verify_Pop();
		window.onerror = this._capture_Error;
	}
	else
	{
		window.onerror = null;
	}

	return true;
};

Js_Debug.prototype.error = function(error)
{
	var success = false;
	
	if(this.debug_mode > 0)
	{
		if(this._verify_Pop())
		{
			var error_info = '';
			
			// if error array exists and type of passed error is a number
			if(this.error_array && (typeof(error) == 'number') && this.error_array[error])
			{
				error_info = '#' + error + ' - ' + this.error_array[error];
			}
			else
			{
				// find variable type and convert to string
				switch(typeof(error))
				{
					case 'array':
					case 'object':
						error_info = error.toSource();
						break;
					case 'boolean':
					case 'number':
					case 'string':
						error_info = error.toString();
						break;
					default:
						// unable to convert error to string
						error_info = '***Given error message cannot be determined.***';
						break;
				}
			}
			
			// output to window
			this._show_Debug('<font color="#FF0000"><b>ERROR: </b></font>' + error_info);
			
			success = true;
		}
		else
		{
			success = false;
		}
	}
	else
	{
		success = false;	
	}
	
	return success;
};

Js_Debug.prototype.boolean_Test = function(description, expr)
{	
	var success = false;
	
	if((this.debug_mode > 0) && (this.debug_mode < 4))
	{
		if(this._verify_Pop())
		{
			var test = null;
			
			// handle expression or object and determine boolean value
			switch(typeof(expr))
			{
				case 'boolean':
					test = expr;
					break;
				case 'string':
					eval('test = (' + expr + ') ? true : false; ');
					break;
				default:
					test = (expr) ? true : false;
					break;
			}
			
			// output proper test string
			switch(test)
			{
				case (null || undefined):
					// output to window
					this._show_Debug('<b>BOOLEAN TEST: </b><i>' + description + '</i> - Given expression does not resolve to boolean. Result: <font color="#FFE721"><b>' + test.toString().toUpperCase() + '</b</font>');
					success = true;
					break;
				case true:
					// output to window
					this._show_Debug('<b>BOOLEAN TEST: </b><i>' + description + '</i> - <font color="#25DE00"><b>' + test.toString().toUpperCase() + '</b></font>');
					success = true;
					break;
				case false:	
					// output to window
					this._show_Debug('<b>BOOLEAN TEST: </b><i>' + description + '</i> - <font color="#FF0000"><b>' + test.toString().toUpperCase() + '</b></font>');
					success = true;
					break;
				default:
					this.error('***Boolean Test Failed. Cannot determine given expression/object: ' + expr.toSource() + ' ***');
					success = false;
					break;
			}
		}
		else
		{
			success = false;
		}
	}
	else
	{
		success = false;	
	}

	return success;
};

Js_Debug.prototype.warning = function(warning)
{
	var success = false;
	
	if((this.debug_mode > 0) && (this.debug_mode < 3))
	{
		if(this._verify_Pop())
		{
			var warning_info = '';
			
			// if warning is not a string, display other error
			if(typeof(warning) == 'string')
			{
				warning_info = warning;
				this._show_Debug('<b>WARNING!: </b>' + warning_info);
			
				success = true;
			}
			else
			{
				this.error('***Cannot display given warning. Data type must be a string.***');
				
				success = false;
			}
		}
	}
	else
	{
		success = false;
	}
	
	return success;
};

Js_Debug.prototype.message = function(msg)
{
	var success = false;
	
	if(this.debug_mode == 1)
	{
		if(this._verify_Pop())
		{
			var message = '';
			
			// find variable type and convert to string
			switch(typeof(msg))
			{
				case 'array':
				case 'object':
					message = msg.toSource();
					break;
				case 'boolean':
				case 'number':
				case 'string':
					message = msg.toString();
					break;
			}
			
			// output to window
			this._show_Debug('<b>Message: </b>' + message);
			
			success = true;
		}
		else
		{
			success = false;	
		}
	}
	else
	{
		success = false;
	}
	
	return success;
};

Js_Debug.prototype.backend_Dump = function(backend_dump, language)
{
	var success = false;
	
	if(this.debug_mode == 1)
	{
		if(this._verify_Pop())
		{
			// determine which language to show
			var lang = 'BACKEND';
			if(typeof(language) == 'string')
			{
				lang = language;
			}
			
			// replace escaped line breaks with regular line breaks
			backend_dump = backend_dump.split("\\n");
			backend_dump = backend_dump.join("\n");
			
			// output to window
			this._show_Debug('<div style="background-color: #BCD0E4; height: 200px; overflow: auto;"><b>' + lang + ' DUMP: </b>\n<blockquote>' + backend_dump + '</blockquote></div>');
		}
		else
		{
			success = false;
		}
	}
	else
	{
		success = false;
	}
	
	return success;
};

Js_Debug.prototype._show_Debug = function(output_string)
{	
	this.output_num++;
	
	// determine row color
	if((this.output_num % 2) == 0)
	{
		var row_bg = this.display.alt_row_color;
	}
	else
	{
		var row_bg = this.display.primary_row_color;
	}
	
	// write to window
	this.js_debug_console.document.writeln('<div style="background-color: ' + row_bg + '; padding: 1px;"><pre>' + this.output_num + '. ' + output_string + '</pre></div>')
	// scroll to bottom
	this.js_debug_console.scrollTo(0, this.js_debug_console.document.height);
	// make sure focus stays on opening window
	this.js_debug_console.blur();
	try
	{
		this.js_debug_console.opener.focus();
	}
	catch(e)
	{
		// unable to focus on parent window	
	}
	
	return true;
};

Js_Debug.prototype._verify_Pop = function()
{
	var success = false;
	
	// check for window and document
	if(this.js_debug_console && this.js_debug_console.document)
	{
		success = true;
	}
	else
	{
		// open window
		success = this._open_Pop();
	}

	return success;
};

Js_Debug.prototype._open_Pop = function()
{
	var success = false;
	
	this.js_debug_console_name = 'js_debug_console';
	this.js_debug_console = window.open('', this.js_debug_console_name, 'width=400,height=200,menubar=yes,toolbar=no,status=no,scrollbars=yes,resizable=yes');

	if(this.js_debug_console)
	{
		var now_date = new Date();
		var this_time = (now_date.getMonth() + 1) + '/' + now_date.getDate() + '/' + now_date.getYear().toString().substring(1) + '-' + now_date.getHours() + ':' + now_date.getMinutes() + ':' + now_date.getSeconds();
		with(this.js_debug_console.document)
		{
			writeln('<html><head><title>JS Debug Console</title></head><body><p><font face="Arial, Verdana, Helvetica" size="-2"><div style="background-color: #FF0000;">JS Debugger Output ' + this_time + '</div>');
		}
		this.js_debug_console.blur();
		this.js_debug_console.opener.focus();
		// scroll to bottom
		this.js_debug_console.scrollTo(0, this.js_debug_console.document.height);
		
		success = true;
	}
	else
	{
		// opening of console failed, display alert
		alert('Cannot display debugging console, please turn off pop-up blocking for this site or try reloading or restarting your browser.');
		success = false;
	}
			
	return success;
};

Js_Debug.prototype._capture_Error = function(err, file, line)
{
	js_inst.error('JavaScript Error: ' + err + ', File: ' + file + ', Line: ' + line);
};