function styleMathBlock( e )
{
	e.style.display = "block";
	e.style.position = "absolute";
	e.style.padding = 0;
	e.style.margin = 0;
	e.offsetPLeft = 0;
	e.offsetPRight = 0;
	e.offsetPTop = 0;
}

function cssPixels( rhs )
{
	if ( isNaN(rhs) ) throw "ERROR!  Not a valid number.";
	return parseFloat(rhs) + "px";
}

function formatEquations() {
	var e = document.getElementsByTagName("div");
	var lp;
	var border = 0;

	// fix equations
	for ( lp=0; lp < e.length; ++lp ) {
		var elem = e[lp];
		if ( elem.className == "equation" ) {
			// an equation block should have two child nodes
			if ( elem.childNodes.length!=2 ) throw "ERROR!";
			var caption = elem.childNodes[0];
			var data = elem.childNodes[1];

			// change the top node
			elem.style.border = border + "px solid #c0c0c0";
			// changes to the actual math node
			data.style.position = "relative";
			formatMathRow( data );

			caption.style.position = "relative";
			caption.style.top = cssPixels((elem.offsetHeight-2*border-caption.offsetHeight)*0.5);
		}
	}
}

function formatMathRow( top )
{
	var lp;
	var maxheight = 0;
	var posx = 0;
	var spacerelem = null;

	for ( lp=0; lp<top.childNodes.length; ++lp ) {
		var elem = top.childNodes[lp];
		styleMathBlock( elem );
		eval( "format_" + elem.className + "(elem)" );

		if ( elem.offsetHeight>maxheight ) maxheight = elem.offsetHeight;
		posx = posx + elem.offsetWidth + elem.offsetPLeft + elem.offsetPRight;
	}

	if ( top.style.display=="block" ) {
		top.style.width = posx + "px";
		top.style.height = maxheight + "px";
		posx = 0;
	}
	else {
		var spacerelem = document.createElement("div");
		top.appendChild( spacerelem );
		posx = -posx*0.5;
	}

	for ( lp=0; lp<top.childNodes.length; ++lp ) {
		var elem = top.childNodes[lp];
		if ( elem == spacerelem ) continue;
		elem.style.left = cssPixels(posx + elem.offsetPLeft);
		elem.style.top = cssPixels( (maxheight-elem.offsetHeight)*0.5+elem.offsetPTop );
		posx = posx + elem.offsetPLeft + elem.offsetWidth + elem.offsetPRight;
	}
	
	if ( spacerelem ) {
		spacerelem.style.display = "block";
		spacerelem.style.width = "10px";
		spacerelem.style.height = "0px";
		spacerelem.style.overflow = "hidden";
		// handle bug in IE
		if ( spacerelem.offsetTop>0 ) {
			var delta = maxheight - spacerelem.offsetTop;
			if ( delta>0 ) spacerelem.style.height = cssPixels( delta );
		}
		else {
			var delta = maxheight - top.offsetHeight;
			if ( delta>0 ) spacerelem.style.height = cssPixels( delta+1 );
		}
	}
}

function format_math_id( elem )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	elem.offsetPLeft = 1;
	elem.offsetPRight = 1;
	elem.offsetPTop = 0;
}

function format_math_num( elem )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	elem.offsetPLeft = 1;
	elem.offsetPRight = 1;
	elem.offsetPTop = 0;
}

function format_math_op( elem )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	elem.offsetPLeft = 3;
	elem.offsetPRight = 3;
	elem.offsetPTop = 0;
}

function format_math_func( elem )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	elem.offsetPLeft = 1;
	elem.offsetPRight = 1;
	elem.offsetPTop = 0;
}

function format_math_bracket( top )
{
	// add padding
	top.offsetPLeft = 1;
	top.offsetPRight = 1;
	top.offsetPTop = 0;
	
	if ( top.childNodes.length!=3 ) throw "ERROR!";

	styleMathBlock( top.childNodes[0] );
		top.childNodes[0].offsetPLeft = 0;
		top.childNodes[0].offsetPRight = 2;
	styleMathBlock( top.childNodes[1] );
		formatMathRow( top.childNodes[1] );
		top.childNodes[1].offsetPLeft = 0;
		top.childNodes[1].offsetPRight = 0;
	styleMathBlock( top.childNodes[2] );
		top.childNodes[2].offsetPLeft = 2;
		top.childNodes[2].offsetPRight = 0;

	// format the brackets
	var h = top.childNodes[1].offsetHeight;
	top.childNodes[0].style.fontSize = cssPixels(h);
	top.childNodes[2].style.fontSize = cssPixels(h);
	
	var posx = 0;
	var maxheight = 0;
	var lp;
	for ( lp=0; lp<3; ++lp ) {
		var elem = top.childNodes[lp];
		posx = posx + elem.offsetWidth + elem.offsetPLeft + elem.offsetPRight;
		if ( elem.offsetHeight>maxheight ) maxheight = elem.offsetHeight;
	}

	top.style.width = cssPixels( posx );
	top.style.height = cssPixels( maxheight );	
	posx = 0;

	var elem = top.childNodes[0];
	elem.style.left = 0;
	elem.style.top = cssPixels( -elem.offsetHeight*0.05 );
	posx = posx + elem.offsetPLeft + elem.offsetWidth + elem.offsetPRight;
	if ( isNaN(posx) ) throw "ERROR!";

	elem = top.childNodes[1];
	elem.style.left = cssPixels(posx + elem.offsetPLeft);
	elem.style.top = cssPixels((maxheight-elem.offsetHeight)*0.5+1);
	posx = posx + elem.offsetPLeft + elem.offsetWidth + elem.offsetPRight;
	if ( isNaN(posx) ) throw "ERROR!";

	elem = top.childNodes[2];
	elem.style.left = cssPixels(posx + elem.offsetPLeft);
	elem.style.top = cssPixels( -elem.offsetHeight*0.05 );
}

function format_math_frac( top )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	//top.style.border = "1px solid blue";
	top.offsetPLeft = 1;
	top.offsetPRight = 1;
	top.offsetPTop = 0;
	if ( top.childNodes.length!=3 ) throw "ERROR!";

	var n = top.childNodes[0];
	var l = top.childNodes[1];
	var d = top.childNodes[2];

	l.style.display="none";

	styleMathBlock( n );
	formatMathRow( n );
	styleMathBlock( d );
	formatMathRow( d );

	var width = (n.offsetWidth>d.offsetWidth) ? n.offsetWidth : d.offsetWidth;
	if ( isNaN(width) ) throw "ERROR!";
	var height = n.offsetHeight + d.offsetHeight;
	if ( isNaN(height) ) throw "ERROR!";

	top.style.width = cssPixels( width );
	top.style.height = cssPixels( height-1 );	

	n.style.left = cssPixels( (width-n.offsetWidth)*0.5 );
	n.style.top = "0px";
	d.style.left = cssPixels( (width-d.offsetWidth)*0.5 );
	d.style.top = (n.offsetHeight-1) + "px";

	if (n.offsetWidth>d.offsetWidth)
		n.style.borderBottom = "1px solid black";
	else
		d.style.borderTop = "1px solid black";
}

function format_math_sub( top )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	//top.style.border = "1px solid blue";
	top.offsetPLeft = 0;
	top.offsetPRight = 1;
	top.offsetPTop = 1;

	var p = top.previousSibling;
	if ( !p ) throw "ERROR!  <sub> does not have a previous sibling";
	top.offsetPTop = p.offsetHeight - top.offsetHeight;
}

function format_math_sup( top )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	//top.style.border = "1px solid blue";
	top.offsetPLeft = 0;
	top.offsetPRight = 1;
	top.offsetPTop = -1;

	var p = top.previousSibling;
	if ( !p ) throw "ERROR!  <sup> does not have a previous sibling";
	top.offsetPTop = -p.offsetHeight + top.offsetHeight;
}

function format_math_sum( top )
{
	// there is nothing to do to calculate the size of this element
	// add padding
	//top.style.border = "1px solid blue";
	top.offsetPLeft = 0;
	top.offsetPRight = 0;
	top.offsetPTop = 0;
	if ( top.childNodes.length!=4 ) throw "ERROR!  <math_sum> does not have four children.";
	var deltaH = 2;

	var s = top.childNodes[0];
	var b = top.childNodes[1];
	var t = top.childNodes[2];
	var r = top.childNodes[3];

	styleMathBlock( s );
		s.offsetPLeft = 1;
		s.offsetPRight = 1;
	styleMathBlock( b );
		formatMathRow( b );
	styleMathBlock( t );
		formatMathRow( t );
	styleMathBlock( r );
		r.offsetPRight = 1;
		formatMathRow( r );

	s.style.fontSize = cssPixels( r.offsetHeight+2 );

	var width = s.offsetPLeft + s.offsetWidth + s.offsetPRight +
		r.offsetPLeft + r.offsetWidth + r.offsetPRight;
	var height = s.offsetHeight + b.offsetHeight + t.offsetHeight - 2*deltaH;

	top.style.width = cssPixels( width );
	top.style.height = cssPixels( height );

	var maxwidth = s.offsetWidth;
	if ( b.offsetWidth>maxwidth ) maxwidth = b.offsetWidth;
	if ( t.offsetWidth>maxwidth ) maxwidth = t.offsetWidth;

	t.style.top = 0;
	t.style.left = cssPixels( (maxwidth-t.offsetWidth)*0.5 );
	s.style.top = cssPixels( t.offsetHeight - deltaH );
	s.style.left = cssPixels( (maxwidth-s.offsetWidth)*0.5 );
	b.style.top = cssPixels( t.offsetHeight + s.offsetHeight - 2*deltaH );
	b.style.left = cssPixels( (maxwidth-b.offsetWidth)*0.5 );

	r.style.left = cssPixels( maxwidth );
	r.style.top = cssPixels( t.offsetHeight + (s.offsetHeight-r.offsetHeight)*0.5 );
}



