// Copyright, 2007, Mats Mattsson

function tokenIHtml( id, str ) {
	return "<div class=\"token\" id=\""+id + "\">" + str + "</div>";
}


Node.prototype.iHtml = function( prefix, level ) {
	var str = pNodeHtml(prefix+"a", level);
	str += (this.op && (this.op.type == 0 || this.op.type == 2) ? this.op.iHtml(prefix + "o", level + 1) : "" );
	str += (this.e1 ? this.e1.iHtml(prefix + "1", level + 1) : "" );
	str += (this.op && (this.op.type == 1 || this.op.type == 3 || this.op.type == 4) ? this.op.iHtml(prefix + "o", level + 1) : "" );
	str += (this.e2 ? this.e2.iHtml(prefix + "2", level + 1) : "" );
	str += (this.s4 ? tokenIHtml( prefix + "4" , this.s4 ) : "" )
	str += (this.e3 ? this.e3.iHtml(prefix + "3", level + 1) : "" );
	return str;
}

Operator.prototype.iHtml = function( prefix, level ) {
	return tokenIHtml( prefix, this.name );
}

Token.prototype.iHtml = function( prefix, level ) {
	return tokenIHtml( prefix, this.name );
}
BadToken.prototype.iHtml = function( prefix, level ) {
	return "<div class=\"btoken\" id=\""+id + "\">" + str + "</div>";
}

FCall.prototype.iHtml = function( prefix, level ) {
	var str = pNodeHtml( prefix+"f", level );
	str += (this.name ? this.name.iHtml(prefix + "g", level + 1) : "" );
	str += tokenIHtml( prefix + "s" , this.start );
	str += (this.par ? this.par.iHtml(prefix + "h", level + 1) : "" );
	str += tokenIHtml( prefix + "e" , this.end );
	return str;
}

function ReorderInfo(width, level) {
	this.width = width;
	this.level = level;
}

function adjustNode( x, y, info, id, width, maxHeight ) {
	var e = document.getElementById(id);
	e.style.top = y+"px";
	e.style.left = 1+x+"px";
	e.style.width = width+1+"px";
	e.style.height = (maxHeight * 4)+"px";
	info.level = maxHeight + 1;
	info.width = width+3;
}					 

Node.prototype.adjust = function( x, y, info, prefix, level ) {
	var width = 3;
	var maxHeight = 0;
	
	if ( this.op && (this.op.type == 0 || this.op.type == 2 ) ) {
		this.op.adjust( x + width, y, info, prefix + "o", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	if ( this.e1 ) {
		this.e1.adjust( x + width, y, info, prefix + "1", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	if ( this.op && (this.op.type == 1 || this.op.type == 3 || this.op.type == 4) ) {
		this.op.adjust( x + width, y, info, prefix + "o", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	if ( this.e2 ) {
		this.e2.adjust( x + width, y, info, prefix + "2", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	if ( this.s4) {
		textAdjust(x + width, y, info, prefix + "4", 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	if ( this.e3 ) {
		this.e3.adjust( x + width, y, info, prefix + "3", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}		
	
	adjustNode( x, y, info, prefix+"a", width, maxHeight );
}

function textAdjust( x, y, info,  id, margin ) {
	var e = document.getElementById(id);
	e.style.top = y-e.offsetHeight+2+"px";
	e.style.left = margin+x+"px";
	info.level = 0;
	info.width = e.offsetWidth+2*margin;
}

Operator.prototype.adjust = function( x, y, info, prefix, level ) {
	textAdjust(x, y, info, prefix, 1);
}
Token.prototype.adjust = function( x, y, info, prefix, level ) {
	textAdjust(x, y, info, prefix, 1);
}

FCall.prototype.adjust = function( x, y, info, prefix, level ) {
	var width = 3;
	var maxHeight = 0;
	
	if ( this.name ) {
		this.name.adjust( x + width, y, info, prefix + "g", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	textAdjust(x + width, y, info, prefix+"s", 0);
	width += info.width;
	if ( info.level > maxHeight ) {maxHeight = info.level;}

	if ( this.par ) {
		this.par.adjust( x + width, y, info, prefix + "h", level + 1);
		width += info.width;
		if ( info.level > maxHeight ) {maxHeight = info.level;}
	}
	textAdjust(x + width, y, info, prefix+"e", 0);
	width += info.width;
	if ( info.level > maxHeight ) {maxHeight = info.level;}
				
	adjustNode( x, y, info, prefix+"f", width, maxHeight );
}


function displayPrecedence( divID, precObject ) {
	var e = document.getElementById(divID);
	if ( e && precObject ) {
		e.innerHTML = precObject.iHtml(divID+"tid",0);
		var info = new ReorderInfo(0, 0);
		precObject.adjust( e.offsetLeft, e.offsetTop, info, divID+"tid", 0);
		e.style.height = info.level * 4 + "px";
	} else if ( e ) {
		e.innerHTML = "";
	}
}

function displayPrecedenceForString( divID, str ) {
	var n = parseExpression( str );
	displayPrecedence( divID, n ? n : null);
}

