
function Template(id)
{
    this.paths = {};
    
    this.templateElt = document.getElementById(id);
    if (this.templateElt)
    {
        // Rip the template out of the document and cleanse it of inpurities
        this.templateElt.parentNode.removeChild(this.templateElt);
        this.templateElt.removeAttribute("id");
        //this.__removeTextNodes(this.templateElt);
        
        this.__buildPaths(this.templateElt, [-1]);
    }
}

Template.prototype = 
{
    templateElt: null,
    paths: null,
    
    ////////////////////////////////////////////////////////////////////////////////////////////////
    
    createTemplate: function()
    {
        return this.templateElt.cloneNode(true);
    },
    
    getInsertionChild: function(element, insertionId)
    {
        if (!(insertionId in this.paths))
            return null;
        
        var path = this.paths[insertionId];
        
        var child = element;
        for (var i = 0; child && i < path.length; ++i)
            child = child.childNodes[path[i]];
        
        return child;
    },
    
    setAttribute: function(element, id, attr, value)
    {
        var elt = this.getInsertionChild(element, id);
        elt.setAttribute(attr, value);
    },  
    
    setTextValue: function(element, id, value)
    {
        var elt = this.getInsertionChild(element, id);
        elt.appendChild(document.createTextNode(value));
    },  
    
    setHTMLValue: function(element, id, value)
    {
        var elt = this.getInsertionChild(element, id);
        elt.innerHTML = value;
    },  
    
    ////////////////////////////////////////////////////////////////////////////////////////////////
    
    __buildPaths: function(element, path)
    {
        var child = element.firstChild;
        while (child)
        {
            path[path.length-1] += 1;
          
            if (child.nodeType == 1)
            {
                if (child.getAttribute("insertionid"))
                {
                    var templId = child.getAttribute("insertionid");
                    child.removeAttribute("insertionid");
                    this.paths[templId] = path.slice(0, path.length);
                }
        
                path.push(-1);
                this.__buildPaths(child, path);
                path.pop();
            }
                
            child = child.nextSibling;
        }
    },
    
    __removeTextNodes: function(element)
    {
        var child = element.firstChild;
        while (child)
        {
            var nextChild = child.nextSibling;
            if (child.nodeType == 3)
                element.removeChild(child);
            else
                this.__removeTextNodes(child);
          
            child = nextChild;
        }
    }
    
};
