var eventHandler;

function InterfaceBuilder() {

    var root;                               // This holds the base tag DOM reference in HTML.
    var model;                              // This holds the HTML structure to attach to the root.
    this.document = document;               // Using a local reference for testing purposes.
	
	this.setUpRoot = function(domBluePrint) {
	    this.model = domBluePrint;
	    this.root = document.createElement("div");
        for (var child in this.model.view.root) {
            this.attacher(this.model.view.root, this.root, child);
        }
        
        return this.root;
	}
	   
    this.createElement = function(modelElement, inheritedNode) {
	    var theNewElement = document.createElement(modelElement.tag);
        if (inheritedNode) {
	        this.decorateElement(inheritedNode, theNewElement);
        }
	    this.decorateElement(modelElement, theNewElement);
	    return theNewElement;
	}
    
    this.decorateElement = function (modelElement, element) {
	    var styles = modelElement.style.properties;
	    for (var styleProperty in styles) {
	        element.style[styleProperty] = styles[styleProperty];
	    }
        for (var propertyName in modelElement.properties) {
	        element[propertyName] = modelElement.properties[propertyName];
	    }
	    
        for (var eventName in modelElement.events) {
            element[eventName] = eventHandler[modelElement.events[eventName]];
	    }
    }
	
    this.appendChildToParent = function(parent, child) {
        parent.appendChild(child);
    }

    this.createNode = function (modelNode, name, inheritedNode) {
        var theResult;
        if (modelNode.type == "element") {
            theResult = this.createElement(modelNode, inheritedNode);
        } else if (modelNode.type != "abstract") {
            theResult = this.createTextNode(modelNode);
        }
        
        if (name) {
            this[name] = theResult;
        }
        return theResult;
    }
    
    this.attacher = function (parentModel, parentDomNode, childName) {
        var childAttachmentModel = parentModel[childName];
        var childNodeModel = this.model.nodes[childName];
        var childDomNode = this.createNode(
            childNodeModel, 
            this.nameIfAny(childName, childNodeModel), 
            this.inheritedNodeIfAny(childNodeModel, this.model.nodes)
        );
        this.appendChildToParent(parentDomNode, childDomNode);
        for (var grandChildName in parentModel[childName]) {
            this.attacher(childAttachmentModel, childDomNode, grandChildName);
        }
    }
   
    this.createTextNode = function (modelNode) {
        var newNode = document.createTextNode(modelNode.text);
        return newNode;
    }

    this.nameIfAny = function (name, node) {
        if ("noReference" in node) {
            return null;
        } else {
            return name;
        }
    }
    
    this.inheritedNodeIfAny = function(modelNode, modelNodes) {
        if (modelNode.inherit in modelNodes) {
            return modelNodes[modelNode.inherit];
        } else {
            return null;
        }
    }
}


