if (typeof console == 'undefined') {
	var console = {
		log: function() {
		}
	};
}

function get( id ) {
  if ( typeof(id) == "object" )
  	return id;
  else
	return document.getElementById( id );
}

function create( element, parent, className ) {
	var obj = document.createElement( element );
	if ( parent )
		parent.appendChild( obj );
	if ( className )
		obj.className = className;
	return obj;
}

// NOTE: This is needed because IE and Firefox differ on how to create an <INPUT TYPE="BUTTON"/>, radio, etc.
function createInput( type, parent, className ) {
	var obj;
	try {
		obj = document.createElement( "<input type=\"" + type + "\">" );
	}
	catch ( err ) {
		obj = document.createElement( "input" );
		obj.type = type;
	}
	if ( parent )
		parent.appendChild( obj );
	if ( className )
		obj.className = className;
	return obj;
}

function text( msg, parent ) {
	var obj = document.createTextNode( msg );
	if ( parent )
		parent.appendChild( obj );
	return obj;
}

function log( msg ) {
	var log = get("log");
	if ( log == undefined ) {
		var log = create( "div", document.body );
		log.id = "log";
		log.style.fontSize = "8pt";
		log.style.width = "80%";
		log.style.height = "300px";
		log.style.border = "1px solid silver";
		log.style.background = "#eee";
		log.style.overflow = "auto";
		log.style.marginTop = "10px";
		log.style.lineHeight = "1.2em";

		log.style.position = "absolute";
		log.style.bottom = "10px";
		log.style.marginBottom = "20px";
		
		log.style.color = "black";
		log.style.textAlign = "left";
		//log.style.lineSpacing = "1.2em";
		
	}
	
	//alert( typeof(msg) );
	
	if ( typeof(msg) == "string" ) {
		msg = msg.replace( / /, "&nbsp;" );
		msg = msg.replace( /\n/, "<br/>\n" );
	}
	
	log.innerHTML += msg + "<br/>";
}

/*
function htmlEscape( str ) {
	str = str.replace( /\&/g, "&amp;" );
	str = str.replace( /\</g, "&lt;" );
	str = str.replace( /\>/g, "&gt;" );
	//alert(str);
	return str;
}

function log( msg ) {
	var log = get("log");
	if ( log == undefined ) {
		var log = create( "div", document.body );
		log.id = "log";
		log.style.fontSize = "8pt";
		log.style.width = "80%";
		log.style.height = "200px";
		log.style.border = "1px solid silver";
		log.style.background = "#eee";
		log.style.overflow = "auto";
		log.style.marginTop = "10px";
	}
	
	log.innerHTML += htmlEscape(msg) + "<br/>";
}
*/

function clear( obj ) {
	while ( obj.childNodes.length ) {
		obj.removeChild( obj.childNodes[0] );
	}
}

function setText( txt, obj ) {
	clear( obj );
	text( txt, obj );
}

function removeNode( obj ) {
	obj = get(obj);
	obj.parentNode.removeChild(obj);
}

function center_vertical( obj ) {
	obj.style.top = "50%";
	obj.style.marginTop = -obj.offsetHeight/2 + "px";
}

// Returns closest integer to 0 (-1.1 -> -1 ... 1.1 -> 1)
function fix( num ) {
	if ( num < 0 )
		return Math.ceil(num);
	else
		return Math.floor(num);
}

// Returns a negative-sensitive min()
// NOTE: min must be a positive number!
//
// example:
//  magnitude_min( -12, 10 ) = -10
//  magnitude_min( -8, 10 ) = -8
//  magnitude_min( 12, 10 ) = 10
//  magnitude_min( 8, 10 ) = 8
//
function magnitude_min( num, min ) {
	//log("log, num = " + num );
	if ( num < 0 && num > -min ) {
		//log("-min");
		return -min;
	}
	else if ( num > 0 && num < min ) {
		//log("+min");
		return min;
	}
	else {
		//log("num");
		return num;
	}
}

function show_email() {
	//this.href = "mailto:j a m e s @ r o c k e t m  on  keys.com";
	//alert(this.href);
	return true;
}

function getStyle( el,styleProp ) {
	var x = document.getElementById(el);
	if (x.currentStyle)
		var y = x.currentStyle[styleProp];
	else if (window.getComputedStyle)
		var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
	return y;
}

function showBlock( obj ) {
	obj = get(obj);
	obj.style.display = "block";
}

function hideBlock( obj ) {
	obj = get(obj);
	obj.style.display = "none";
}

function toggleBlock( obj ) {
	if ( getStyle( obj, "display" ) == "block" )
		hideBlock( obj );
	else
		showBlock( obj );
}

///////////////////////////////////////////////////////////////////////////////

function showComments( rantid ) {
	showBlock( "comments_" + rantid );
	hideBlock( "showCommentsLink_" + rantid );
}

function hideComments( rantid ) {
	hideBlock( "comments_" + rantid );
	showBlock( "showCommentsLink_" + rantid );
}

///////////////////////////////////////////////////////////////////////////////

function pad( str, len ) {
	str += "";
	while( str.length < len ) {
		str = "0" + str;
	}
	return str;
}

////////////////////////////////////////////////////////////////////////////////

function Callback( obj, func, params ) {
	this.obj = obj;
	this.func = func;
	if ( params )
		this.params = params;
	else
		this.params = new Array();
	
	//log( "Callback(), func: " + func + ", this.params.length: " + this.params.length + ", this.params: " + this.params );
}

Callback.prototype.call = function( additionalParams ) {
	if ( !additionalParams ) {
		//log( "make new additionalParams" );
		additionalParams = new Array();
	}
		
	var t = this.params.concat(additionalParams);
		
	//log( "Callback.call(), this.params: " + this.params.length + ", this.params: " + this.params );
	//log( "Callback.call(), additionalParams: " + additionalParams.length + ", additionalParams: " + additionalParams + ", additionalParams[0]: " + additionalParams[0] );
	//log( "Callback.call(), t: " + t.length + ", t: " + t );
	this.obj[this.func]( this.params.concat(additionalParams) );
}

////////////////////////////////////////////////////////////////////////////////

function verticalCenter( obj ) {
	obj = get(obj);
	var newTop = obj.parentNode.offsetHeight/2 - obj.offsetHeight/2;
	obj.style.marginTop = newTop + "px";
}

function setTimer( func, time, execute ) {
	//log( "setTimer()" );
	if ( execute == undefined )
		execute = false;

	var repeat = true;
	if ( execute ) {
		repeat = func();
	}

	//log( "repeat: " + repeat );

	if ( repeat == undefined || repeat ) {
		setTimeout( function() { setTimer(func, time, true); }, time );
	}
}

function getPos( obj ) {
	
	//log( "getPos( " + obj + ", " + obj.id + ", " + obj.className + " )" );
	
	var left = obj.offsetLeft;
	var top = obj.offsetTop;
	
	//log( "left: " + left );
	//log( "top: " + top );

	while( obj = obj.offsetParent ) {
		left += obj.offsetLeft - obj.scrollLeft;
		top += obj.offsetTop - obj.scrollTop;
		//if ( obj.offsetParent == null )
			//log( "offsetParent: " + obj.offsetParent );
		//else
			//log( "offsetParent: " + obj.offsetParent + ", " + obj.offsetParent.id + ", " + obj.offsetParent.className );
		//log( "left: " + left );
		//log( "top: " + top );
	}

	return [ left, top ];
}

// Returns percent from mid of child to mid of parent compared to parent width.
//   -.5 = middle of child is at left edge of parent
//   0 = child is in middle of parent
//   .5 = middle of child is at right edge of parent
function getChildPercentHoriz( parent, child ) {
	var parentPos = getPos( parent );
	var childPos = getPos( child );
	
	//log( "getChildPercentLeft()" );
	//log( "childPos[0]: " + childPos[0] );
	//log( "child.offsetWidth: " + child.offsetWidth );
	//log( "child.offsetWidth/2: " + child.offsetWidth/2 );
	//log( "childPos[0]+child.offsetWidth/2: " + (childPos[0]+child.offsetWidth/2) );
	//log( "parentPos[0]: " + parentPos[0] );
	//log( "parent.offsetWidth: " + parent.offsetWidth );
	//log( "parent.offsetWidth/2: " + parent.offsetWidth/2 );
	//log( "parentPos[0]+parent.offsetWidth/2: " + (parentPos[0]+parent.offsetWidth/2) );
	
	var percent = ( ( childPos[0] + child.offsetWidth/2 ) - ( parentPos[0] + parent.offsetWidth/2 ) ) / parent.offsetWidth;
	return percent;
}

function arraySearch( array, property, value ) {
	for ( var i=0; i<array.length; i++ ) {
		if ( array[i][property] == value )
			return i;
	}
	return null;
}

function cancelBubble( e ) {
	if ( !e )
		e = window.event;
	if (e.stopPropagation)
		e.stopPropagation();
	else
		e.cancelBubble = true;
}

function insertBefore( newNode, refNode ) {
	refNode.parentNode.insertBefore( newNode, refNode );
}

function insertAfter( newNode, refNode ) {
	if( refNode.nextSibling )
		return this.insertBefore( newNode, refNode.nextSibling );
	else
		return this.appendChild( newNode );
}
