// MixIn is supposed to be kinda like an interface for defining "mix-ins" in other languages.
// a MixIn is kinda like a canned capability that you can add to existing classes.
//
// In this case, our "classes" will be existing object references to HTML elements.
//
// more docs to come...


function MixIn(sMemberPrefix) {
	this.memberPrefix = sMemberPrefix;
	this.allowedTags = new Array();

	for (var i = 1; i < arguments.length; i++) {
		this.allowedTags = this.allowedTags.concat(arguments[i]);
	}	
}


MixIn.prototype.instances = new Object();


MixIn.prototype.apply = function(el) {
	var sCommand = "";

	if (this.tagAllowed(el.nodeName)) {
		var sIndexMemberName = this.memberPrefix + "_index";
		el[sIndexMemberName] = el.id || this.instances.length;
		this.instances[el[sIndexMemberName]] = el;

		for (member in this) {
			if (member.indexOf(this.memberPrefix + "_") == 0) {
				el[member] = this[member];
		}	}

		if (this[this.memberPrefix + "_init"]) {
			for (var i = 1; i < arguments.length; i++) {
				if (i != 1) sCommand += ", ";
				sCommand += "arguments[" + i + "]";
			}

			sCommand = "el." + this.memberPrefix + "_init(" + sCommand + ")";
			eval(sCommand);
		}		
	}
	else {
		return null;
	}
}

MixIn.prototype.tagAllowed = function(sTag) {
	sTag = sTag.toLowerCase();
	for (var i = 0; i < this.allowedTags.length; i++)
		if (this.allowedTags[i].toLowerCase() == sTag)
			return true;

	return false;
}

MixIn.SPECIAL		= new Array("br", "span", "bdo", "object", "img", "map");
MixIn.FONTSTYLE		= new Array("tt", "i", "b", "big", "small");
MixIn.PHRASE		= new Array("em", "strong", "dfn", "code", "q", "sub", "sup", "samp", "kbd", "var", "cite", "abbr", "acronym");
MixIn.INLINE_FORMS	= new Array("input", "select", "textarea", "label", "button");
MixIn.MISC			= new Array("ins", "del", "script", "noscript");
MixIn.INLINE		= new Array().concat("a", MixIn.MISC, MixIn.INLINE_FORMS, MixIn.PHRASE, MixIn.FONTSTYLE, MixIn.SPECIAL);

MixIn.HEADING		= new Array("h1", "h2", "h3", "h4", "h5", "h6");
MixIn.LISTS			= new Array("ul", "ol", "dl");
MixIn.BLOCKTEXT		= new Array("pre", "hr", "blockquote", "address");
MixIn.BLOCK			= new Array().concat("p", MixIn.HEADING, "div", MixIn.LISTS, MixIn.BLOCKTEXT, "form", "fieldset", "table");

MixIn.ALL			= new Array().concat(MixIn.INLINE, MixIn.BLOCK);
MixIn.ALLREF		= new Array(MixIn.SPECIAL, MixIn.FONTSTYLE, MixIn.PHRASE, MixIn.INLINE_FORMS, MixIn.MISC, MixIn.INLINE, MixIn.HEADING, MixIn.LISTS, MixIn.BLOCKTEXT, MixIn.BLOCK, MixIn.ALL);