//
// Broswer detection/version info
//
var browser = new Object();

browser.userAgent = navigator.userAgent;
browser.isIE = false;
browser.isMozilla = false;
browser.version = -1;

var i = -1;
if( ( i = browser.userAgent.indexOf( "MSIE" ) ) >= 0 ) {
	browser.isIE = true;
	browser.version = parseFloat( browser.userAgent.substr( i + "MSIE".length ) );
} else if( ( i = browser.userAgent.indexOf( "Netscape6/" ) ) >= 0 ) {
	browser.isMozilla = true;
	browser.version = parseFloat( browser.userAgent.substr( i + "Netscape6/".length ) );
} else if( ( i = browser.userAgent.indexOf( "Gecko" ) ) >= 0 ) {
	// Other "Gecko" browsers == to Moz 6.1.
	browser.isMozilla = true;
	browser.version = 6.1;
}

//
// Mouse Stuff
//
function ozUIMouse() {

	var coords = { x:0, y:0 };

	if( browser.isMozilla ) {
		document.captureEvents( Event.MOUSEMOVE );
		document.captureEvents( Event.MOUSEDOWN );
		document.captureEvents( Event.MOUSEUP );
	}

	document.onmousemove = function ( e ) {
		if( browser.isIE )
			this.setCoords(
				window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft, 
				window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop
			);
		if( browser.isMozilla )
			setCoords( e.clientX + window.scrollX, e.clientY + window.scrollY );
		onMove( e );
	};

	document.onmousedown = function ( e ) {
		onDown( e );
	};

	document.onmouseup = function ( e ) {
		onUp( e );
	};

	this.setCoords = function ( x, y ) {
		if( x < 0 ) x = 0;
		if( y < 0 ) y = 0;
		coords = { x:x, y:y };
	};

	this.getCoords = function () {
		return coords;
	};

	this.getX = function () {
		return coords.x;
	};

	this.getY = function () {
		return coords.y;
	};

	this.onMove = function ( e ) {};
	this.watch( "onMove", function ( prop, oldVal, newVal ) {
		onMove = newVal;
	} );

	this.onDown = function ( e ) {};
	this.watch( "onDown", function ( prop, oldVal, newVal ) {
		onDown = newVal;
	} );

	this.onUp = function ( e ) {};
	this.watch( "onUp", function ( prop, oldVal, newVal ) {
		onUp = newVal;
	} );

}

//var mouse = new ozUIMouse();

function getClientProps() {
	if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		return {
			width:document.documentElement.clientWidth,
			height:document.documentElement.clientHeight
		};
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		return {
			width:document.body.clientWidth,
			height:document.body.clientHeight
		};
	} else if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		return {
			width:window.innerWidth,
			height:window.innerHeight
		};
	}
	return null;
}



/*
Standard DOM event names:
onload        onunload
onclick       ondblclick        
onmousedown   onmouseup      onmouseover     onmousemove       onmouseout
onfocus       onblur
onkeypress    onkeydown      onkeyup
onsubmit      onreset        onselect        onchange
*/

function ozUIButton( i ) {

	var id = i;
	try {
		var element = document.getElementById( id );
		element.className = "ozUI_Button";
	} catch( e ) {
		alert( e );
	}

	this.click = function () {};
	this.watch( "click", function ( property, oldval, newval ) {
		if( element ) {
			click = newval;
			element.onclick = click;
		}
	} );

	this.doubleClick = function () {};
	this.watch( "doubleClick", function ( property, oldval, newval ) {
		if( element ) {
			doubleClick = newval;
			element.ondblclick = doubleClick;
		}
	} );

	this.mouseDown = function () {};
	this.watch( "mouseDown", function ( property, oldval, newval ) {
		if( element ) {
			mouseDown = newval;
			element.onmousedown = mouseDown;
		}
	} );

	this.mouseUp = function () {};
	this.watch( "mouseUp", function ( property, oldval, newval ) {
		if( element ) {
			mouseUp = newval;
			element.onmouseup = mouseUp;
		}
	} );

	this.mouseOver = function () {};
	this.watch( "mouseOver", function ( property, oldval, newval ) {
		if( element ) {
			mouseOver = newval;
			element.onmouseover = mouseOver;
		}
	} );

	this.mouseMove = function () {};
	this.watch( "mouseMove", function ( property, oldval, newval ) {
		if( element ) {
			mouseMove = newval;
			element.onmousemove = mouseMove;
		}
	} );

	this.mouseOut = function () {};
	this.watch( "mouseOut", function ( property, oldval, newval ) {
		if( element ) {
			mouseOut = newval;
			element.onmouseout = mouseOut;
		}
	} );

	this.setLabel = function ( l ) {
		try {
			element.innerHTML = l;
		} catch( e ) {
			alert( e );
		}
	};

	/*var gatherButtons = function () {
		var els = document.getElementsByTagName( "cjui_button" );
		for( var i = 0; i < els.length; i++ ) {
			//alert( "Found button (Label:'" + els[i].getAttribute( "label" ) + "', ID:'" + els[i].id + "')" );
			var btn = document.createElement( "div" );
			var cjNode = document.getElementById( els[i].id );
			btn.id = cjNode.id;
			btn.innerHTML = cjNode.getAttribute( "label" );
			btn.className = "CJUI_Button";
			try {
				document.body.appendChild( btn );
				document.body.removeChild( cjNode );
			} catch( e ) {
				alert( e );
			}
		}
	}*/

}



//
// ozTable
//

function ozUITable( i ) {

	this.clear = function () {
		while( tbl.rows.length ) tbl.deleteRow( tbl.rows.length - 1 );
	};

	// make a table based on an array (must be two-dimensional, of course )
	this.createFromArray = function ( a ) {
		this.clear();
		if( a ) {
			if( a.isTwoDimensional() ) {
				for( var r = 0; r < a.length; r++ ) {
					tbl.insertRow( r );
					for( c = 0; c < a[r].length; c++ ) {
						tbl.rows[r].insertCell( c );
						tbl.rows[r].cells[c].innerHTML = a[r][c];
					}
				}
			} else {
				throw id + ".createFromArray(): Array passed is not two-dimensional.";
			}
		} else {
			throw id + ".createFromArray(): 2nd parameter must be an Array.";
		}
	};

	this.getRowCount = function () {
		return tbl.rows.length;
	};

	this.getCellCount = function ( row ) {
		if( row < tbl.rows.length )
			return tbl.rows[row].cells.length;
		else
			throw id + ".getCellCount(): Row " + row + " out of range for table.";
	};

	this.getMaxCellCount = function () {
		var m = 0;
		for( var r = 0; r < this.getRowCount(); r++ )
			m = Math.max( m, this.getCellCount( r ) );
		return m;
	};

	// 1st parameter (required): insert before row number
	// 2nd parameter (optional): how many to insert
	this.insertRows = function ( rowNum, n ) {
		if( !isNumber( arguments[0] ) )
			throw id + ".insertRows(): Parameter 1 must be numeric.";
		if( rowNum > this.getRowCount() || rowNum < 0 )
			throw id + ".insertRows(): Row value (" + rowNum + ") is out of range (0 to " + this.getRowCount() + ") in table.";
		if( isNumber( arguments[1] ) ) {
			// if second parameter is a number, just insert X rows
			var cellCount = this.getMaxCellCount();
			for( var r = 0; r < arguments[1]; r++ ) {
				tbl.insertRow( rowNum );
				for( var c = 0; c < cellCount; c++ ) {
					tbl.rows[rowNum].insertCell( c );
				}
			}
		} else if( isArray( arguments[1] ) && arguments[1].length ) {
			// if second parameter is an array and has elements, add array as rows
			var a = arguments[1];
			for( var r = 0; r < a.length; r++ ) {
				tbl.insertRow( rowNum );
				if( isArray( a[r] ) ) {
					// this element is an array, so add its elements as cells
					for( var c = 0; c < a[r].length; c++ ) {
						tbl.rows[rowNum].insertCell( c );
						tbl.rows[rowNum].cells[c].innerHTML = a[r][c];
					}
				} else {
					// this element is not an array
					tbl.rows[rowNum].insertCell( 0 );
					tbl.rows[rowNum].cells[0].innerHTML = a[r];
				}
				rowNum++;
			}
		} else {
			throw id + ".insertRows(): Parameter 2 must be a number or an array (with elements, of course).";
		}
	};

	// Parameters
	// rowCount or array of row data
	this.appendRows = function ( c ) {
		if( isNumber( c ) || isArray( c ) ) {
			this.insertRows( this.getRowCount(), c );
			return;
		}
		throw id + ".appendRows(): First parameter must be a number or an array.";
	};

	// r is the row number to add cells to
	// c is either a number or an array of cells to add to row r
	// 3rd parameter (optional) pad cells with this if it's there
	this.addCells = function ( r, c ) {
		if( r < tbl.rows.length ) {
			if( isNumber( c ) ) {
				for( var i = 0; i < c; i++ ) {
					tbl.rows[r].insertCell( i );
					if( arguments.length == 3 && arguments[2].toString().length )
						this.setCellContent( r, i, arguments[2].toString() );
				}
			} else if( isArray( c ) ) {
				for( var i = 0; i < c.length; i++ ) {
					tbl.rows[r].insertCell( i );
					if( arguments.length == 3 && arguments[2].toString().length )
						this.setCellContent( r, i, arguments[2][i] );
				}
			} else {
				throw id + ".addCells(): Parameter 2 was not a number or an array.";
			}
		} else {
			throw id + ".addCells(): Row value (" + r + ") out of range (only " + this.getRowCount() + " rows in table).";
		}
	};

	this.setCellContent = function ( r, c, t ) {
		var n = this.getRowCount();
		if( r >= n )
			throw id + ".setCellContent(): There " + ( n > 1 ? "are" : "is" ) + " only " + n + " row" + ( n > 1 ? "s" : "" ) + " in table.";
		n = this.getCellCount( r );
		if( c >= n )
			throw id + ".setCellContent(): There " + ( n > 1 ? "are" : "is" ) + " only " + n + " cell" + ( n > 1 ? "s" : "" ) + " in that row of table.";
		var cell = tbl.rows[r].cells[c];
		if( cell )
			cell.innerHTML = t;
		else
			throw( id + ".setCellContent(): No such cell in table." );
	};

	this.getCellObject = function ( r, c ) {
		var n = this.getRowCount();
		if( r >= n )
			throw id + ".getCellObject(): There " + ( n > 1 ? "are" : "is" ) + " only " + n + " row" + ( n > 1 ? "s" : "" ) + " in table.";
		n = this.getCellCount( r );
		if( c >= n )
			throw id + ".getCellObject(): There " + ( n > 1 ? "are" : "is" ) + " only " + n + " cell" + ( n > 1 ? "s" : "" ) + " in that row of table.";
		var cell = tbl.rows[r].cells[c];
		if( cell )
			return cell;
		else
			throw( id + ".getCellObject(): No such cell in table." );
	};

	this.getRow = function ( r ) {
		var n = this.getRowCount();
		if( r < 0 || r > this.getRowCount() )
			throw id + ".getRow(): Requested row is out of range for this table.";
		return tbl.rows[r];
	};

	this.getColumn = function ( c ) {
		if( c >= 0 && c < this.getMaxCellCount() ) {
			var cols = new Array();
			for( var r = 0; r < tbl.rows.length; r++ ) {
				if( c < this.getCellCount( r ) ) {
					// if this row has enough cells, add the requested column's cell to the array
					cols.push( this.getCellObject( r, c ) );
				} else {
					// this row doesn't have enough cells, so add an empty array
					cols.push( null );
				}
			}
			return cols;
		} else {
			throw id + ".getColumn(): Requested cell is out of range for this table.";
		}
	};

	this.setProperty = function ( p, v ) {
		/* align, background, bgColor, border, borderColor, borderColorDark, 
		borderColorLight, caption, cellPadding, cellSpacing, cols, dataPageSize, 
		frame, height, rules, summary, tFoot, tHead, width */
		try {
			tbl[p] = v;
		} catch( e ) {
			alert( e );
		}
	};

	// init
	var id = i;
	try {
		var tbl = getElement( id );
	} catch( e ) {
		alert( e );
	}

}
