dom = kodiak.dom = {
	extend : function(subject, extensions) {
		for (var x in extensions)
			subject[x] = extensions[x];
		return (subject);
	},

	get : function(identifier) {
		var e = document.getElementById(identifier);
		return (e != null ? elements.extend(e) : null);
	},

	getByClass : function(tagName, className) {
		var x = [], y = Array.createFrom(document.getElementsByTagName(tagName));
		y.forEach(function() { if (this.className == className || this.className.contains(className)) x.push(this); });
		return x;
	},

	getByTag : function(tagName) {
		return Array.createFrom(document.getElementsByTagName(tagName));
	},

	build : function(buildGraph) {
		var domObject = null;

		var buildProperties = dom.getProperties(buildGraph);
		var subject, actual, list;

		var idx;

		for (var a = 0; a < buildProperties.length; a++) {
			idx = buildProperties[a];
			actual = buildGraph[idx];

			if (idx.search(/nodeName|tagName/) != -1) domObject = document.createElement(actual);
			else if (idx.search(/(attr)/) != -1) {
				list = dom.getProperties(buildGraph.attr);
				if (Array.isViable(list)) {
					list.forEach(function() {
						if (domObject[this] != undefined) domObject[this] = buildGraph.attr[this];
					});
				}
			}
		}

		return domObject;
	},

	getProperties : function(source) {
		var properties = [];
		for (var subject in source)
			if (source[subject] != null && typeof(source[subject]) != "function") properties.push(subject);

		return properties;
	},

	getParentElement : function(subject) {
		var src = (typeof(subject) == "string" ? $get(subject) : subject);
		return src.parentNode;
	},

	getPosition : function(subject) {
		var src = (typeof(subject) == "string" ? $get(subject) : subject);
		var point = { x : 0, y : 0 };
		if (src.offsetParent) {
			do {
				point.x += src.offsetLeft;
				point.y += src.offsetTop;
			} while (src = src.offsetParent);
		}

		return point;
	},

	appendScript	: function(scriptPath) {
		var s = "%3Cscript language=\"javascript\" type=\"text/javascript\" src=\"" + scriptPath + "\"%3E%3C/script%3E";
		document.write(decodeURIComponent(s));
	}
};

$get = kodiak.dom.get;
$class = kodiak.dom.getByClass;
$tag = kodiak.dom.getByTag;

events = kodiak.events = {
	attach 	: function(target, eventName, delegate) {
		var src = (typeof(target) == "string" ? $get(target) : target);

		if (ie) src.attachEvent(events.fix(eventName), delegate);
		else src.addEventListener(events.fix(eventName), delegate, false);
	},

	remove 	: function(target, delegate) {
		var src = (typeof(target) == "string" ? $get(target) : target);
		if (ie) src.dettachEvent(events.fix(eventName), delegate);
		else src.removeEventListener(events.fix(eventName), delegate, false);
	},

	fix		: function(eventName) {
		if (ie) return ((eventName.search(/^on/i) == -1 ? "on" : "") + eventName);
		else return ((eventName.search(/^on/i) == -1 ? eventName : eventName.replace(/^on/i, "")));
	}
};

comm = kodiak.communications = {
	build	: function(method, url, async) {
		var x = (ie ? new ActiveXObject("MSXML2.XMLHTTP") : new XMLHttpRequest());
		x.open(method, url, async);
		return x;
	},

	serialize : function(subject) {
		var pairs = [];

		for (x in subject) {
			pairs.push(x + " : " + subject[x]);
		}

		pairs = pairs.join(",");
		return (pairs);
	},

	deserialize : function(data) {
		if (typeof(data) !== "string") return null;

	}
};

elements = kodiak.elements = {
	attach	: function(eventName, delegate) {
		events.attach(this, eventName, delegate);
	},

	detach	: function(eventName, delegate) {
		events.remove(this, eventName, delegate);
	},

	setClass : function(names) {
		this.className = names;
		return (this);
	},

	appendClass : function(names) {
		if (!this.className.endsWith(" ")) this.className += " ";
		this.className += names;

		return (this);
	},

	removeClass : function(cname) {
		var names = this.className.split(" ");
		if (names.length == 1 && names[0] == cname) this.className = "";
		else {
			names.splice(names.indexOf(cname), 1);
			this.className = names.join(" ");
		}
	},

	setAttribute : function(attributeName, attributeValue) {
		this[attributeName] = attributeValue;
	},

	extend	: function(target) {
		var extensions = {
			attach : elements.attach,
			detach : elements.detach,
			setClass : elements.setClass,
			appendClass : elements.appendClass,
			removeClass : elements.removeClass,
			setAttribute : elements.setAttribute
		};

		if (typeof(kodiak.effects) != "undefined")
			target = effects.extend(target);

		return dom.extend(target, extensions);
	}
};