

var entAjax = {};

entAjax.initComponents = function()
{
	var g = "g";
	// Iterate over all pre-defined elements
	for (var tag in entAjax.elements)
	{
		// Get the all the <G:*> elements in the DOM
		var components = entAjax.Html.getElementsByTagNameNS(tag, g);
		for (var i=0; i<components.length; i++)
		{
			// A custom element is only initialized if it is a root node
			if (entAjax.isRootNode(components[i]))
			{
				// Call the defined method that handles such as component
				entAjax.elements[tag].method(components[i]);
			}
		}
	}
}
window.onload = entAjax.initComponents;

entAjax.createGMap = function(declaration) {
	var container = document.createElement('div');
	declaration.insertAdjacentElement("afterEnd", container);

	entAjax.parseStyle(entAjax.elements["map"].styles, declaration, container);

	var gmap = new GMap2(container);

	entAjax.forAttributes(declaration, function(attr) {
		container.setAttribute(attr.nodeName, attr.nodeValue);
		if (entAjax.elements[attr.nodeName] != null)
			entAjax.elements[attr.nodeName].method(gmap, attr);
	});

	entAjax.forChildren(declaration, function(elem) {
		entAjax.elements[entAjax.formatName(elem.nodeName.toLowerCase())].method(gmap, elem);
	});
}

entAjax.createSmallMapControl = function(gmap, declaration)
{
	if (declaration.nodeValue == "true")
		gmap.addControl(new GSmallMapControl());
}

entAjax.createMapTypeControl = function(gmap, declaration)
{
	if (declaration.nodeValue == "true")
		gmap.addControl(new GMapTypeControl());
}

entAjax.createPolyline = function(gmap, declaration)
{
	var points = [];
	entAjax.forChildren(declaration, function(elem)
		{
		points.push(new GLatLng(elem.getAttribute("lat"), elem.getAttribute("lng")));
		});
	var polyline = new GPolyline(points, declaration.getAttribute("color"), declaration.getAttribute("size"));
	gmap.addOverlay(polyline);
}

entAjax.centerMap = function(gmap, declaration)
{
	var child = entAjax.Html.getFirstChild(declaration);
	gmap.setCenter(new GLatLng(child.getAttribute("lat"), child.getAttribute("lng")), parseInt(declaration.getAttribute("zoom")));
}

entAjax.elements = {
		"map":{"method":entAjax.createGMap,"styles":["width","height"]},
		"smallmapcontrol":{"method":entAjax.createSmallMapControl},
		"maptypecontrol":{"method":entAjax.createMapTypeControl},
		"polyline":{"method":entAjax.createPolyline},
		"center":{"method":entAjax.centerMap}};

window.onload = entAjax.initComponents;







/********************/
// HELPER FUNCTIONs //
/********************/


entAjax.Browser = {};
entAjax.Browser.IE = true;
entAjax.Browser.MOZ = false;
if (document.implementation.createDocument)
{
	entAjax.Browser.IE = false;
	entAjax.Browser.MOZ = true;
}

if (entAjax.Browser.MOZ)
{
	/**
	 * @private
	 * @ignore
	 */
	HTMLElement.prototype.insertAdjacentElement = function(pos,node)
	{
		switch (pos)
		{
			case "beforeBegin":
				this.parentNode.insertBefore(node,this)
				break;
			case "afterBegin":
				this.insertBefore(node,this.firstChild);
				break;
			case "beforeEnd":
				this.appendChild(node);
				break;
			case "afterEnd":
				if (this.nextSibling)
					this.parentNode.insertBefore(node,this.nextSibling);
				else
					this.parentNode.appendChild(node);
				break;
		}
	}

	/**
	 * @private
	 * @ignore
	 */
	HTMLElement.prototype.insertAdjacentHTML = function(pos,s)
	{
		var r = this.ownerDocument.createRange();
		r.setStartBefore(this);
		var node = r.createContextualFragment(s);
		this.insertAdjacentElement(pos,node)
	}
}

entAjax.Html = {};
entAjax.Html.getElementsByTagNameNS = function(tag, ns, context)
{
	context = context || document;

    // Format the qualified element name - browser dependant
    var qname = ns + ":" + tag;
    if (entAjax.Browser.IE) qname = tag;

    // Get the all the elements in the DOM
    var elems = context.getElementsByTagName(qname);
    
    if (entAjax.Browser.IE) 
    {
	    realElems = [];
	    for (var i=0; i<elems.length; i++)
	    {
		    if (elems[i].scopeName == ns)
			    realElems.push(elems[i]);
	    }
	    elems = realElems;
    }

    return elems;
}
entAjax.Html.getFirstChild = function(node)
{
	var firstChild = null;
	for (var i=0; i<node.childNodes.length; i++)
	{
		if (node.childNodes[i].nodeType == 1)
		{
			firstChild = node.childNodes[i];
			break;
		}
	}
	return firstChild;
}


entAjax.parseStyle = function(styles, declaration, container)
{
	for (var i=0; i<styles.length; i++)
	{
		container.style[styles[i]] = declaration.getAttribute(styles[i]);
	}
}

entAjax.forAttributes = function(node, func)
{
	for (var i=0; i<node.attributes.length; i++)
	{
		func.call(this, node.attributes[i]);
	}
}

entAjax.forChildren = function(node, func)
{
	for (var i=0; i<node.childNodes.length; i++)
	{
		if (node.childNodes[i].nodeType == 1)
			func.call(this, node.childNodes[i]);
	}
}

entAjax.isRootNode = function(node)
{
	node = node.parentNode;
	if (node == null || node == document)
		return true;

	if (node.scopeName == "g" || node.tagName.toLowerCase().indexOf("g:") == 0)
	{
		return false;
	}
	else
	{
		return entAjax.isRootNode(node);
	}
}

entAjax.formatName = function(name)
{
	if (name.indexOf("g:") == 0)
	{
		return name.substr(2, name.length-2);
	}
}
