
function selectNode(node, id){
    var j;
    for(j=0; j<node.childNodes.length; j++){
        var childNode = node.childNodes[j];
        if(childNode.nodeName==id)
            return childNode;
    }
    return null;
}

function selectNodeValue(node, id){
    var child = selectNode(node, id);
    if(child == null || child.firstChild == null)
        return null;
    return child.firstChild.nodeValue;
}

function evaluate(text, maps){
    var finalText = unescape(text);
    finalText = evaluateWithHasDirectives(finalText, maps, "[{", "}]", "[/{", "}]");
    finalText = evaluateWithExpressions(finalText, maps, "${", "}");
    return finalText;
}

function evaluateWithExpressions(text, maps, pre, post){
    var newText = text;
    var startExpr = newText.indexOf(pre);
    while(startExpr >= 0 && startExpr < newText.length){
        var endExpr = newText.indexOf(post, startExpr);

        var expression = newText.substring(startExpr+pre.length, endExpr);
        
        var value = evaluateExpression(expression, maps);

        newText = newText.replace(pre + expression + post, value);

        startExpr = newText.indexOf(pre, startExpr);
    }

    return newText;
}

function evaluateWithHasDirectives(text, maps, pre, prePost, postPre, post){
    var newText = text;
    var startExpr = newText.indexOf(pre);
    while(startExpr >= 0 && startExpr < newText.length){
        var endExpr = newText.indexOf(prePost, startExpr);

        var expression = newText.substring(startExpr+pre.length, endExpr);
        var negate = false;
        if(expression.substring(0,1) == "!"){
            negate = true;
            expression = expression.substring(1);
        }
        
        var value = evaluateExpression(expression, maps);
        
        var endExpression = postPre + expression + post;
        var endHas = newText.indexOf(endExpression, endExpr);

	if((value != null  && "" != value) ^ negate){
        	newText = newText.substring(0, startExpr) + newText.substring(endExpr+prePost.length, endHas) + newText.substring(endHas + endExpression.length);
        }
        else {
        	newText = newText.substring(0, startExpr) + newText.substring(endHas + endExpression.length);
        }

        startExpr = newText.indexOf(pre, startExpr);
    }

    return newText;
}

function evaluateExpression(expression, maps){
        var value = maps;
        var lastIndex = 0;
        var dotIndex = expression.indexOf('.');
        while(dotIndex >= 0){
            value = value[expression.substring(lastIndex, dotIndex)];
            lastIndex = dotIndex+1;
            dotIndex = expression.indexOf('.', lastIndex);
        }
        value = value[expression.substring(lastIndex)];
	return value;
}

function formatDateShort(date){
	return (date.getMonth()<9 ? "0" : "") + (date.getMonth()+1) + "/" + (date.getDate()<10 ? "0" : "") + date.getDate() + "/" + date.getFullYear();
}

function formatDateLong(date){
	var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
	var prefixes = new Array('st','nd','rd','th');
	var d = date.getDate();
	return d + ((d < 10 || d >= 20) && d%10 >= 1 && d%10 <= 3 ? prefixes[(d%10)-1] : prefixes[3]) + " " + months[date.getMonth()] + ", " + date.getFullYear();
}
