/*
 * CaretSelector engine
 *   very tiny selector engine for use with CuFon
 *   And specifically IE which seem to fail on
 *   any selection other than tagname
 *   Code was based on Sizzle
 *
 *  Version 0.3 20101029 Extended selector to search for classes, multiple selections possible (comma seperated)
 *  Version 0.2 20100824 Extended selector to search for child elements
 *  Version 0.1
*/

(function(){

var CaretSelector = function(selector, context, results, seed) {

        function CaretSelector_getElementsByClassName(oElm, strTagName, strClassName){
                var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
                var arrReturnElements = new Array();
                strClassName = strClassName.replace(/\-/g, "\\-");
                var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
                var oElement;
                for(var i=0; i<arrElements.length; i++){
                        oElement = arrElements[i];
                        if(oRegExp.test(oElement.className)){
                                arrReturnElements.push(oElement);
                        }
                }
                return (arrReturnElements)
        }

	results = results || [];
	var origContext = context = context || document;

	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
		return [];
	}
	
	if ( !selector || typeof selector !== "string" ) {
		return results;
	}

        // Check for selector of form:
        //   h1#object_id
        //   h1.object_id
        //   p
        //   #object_id
        //   .object_id
        // Or the above followed by a tagname:
        //   h1#object_id span
        //   h1.object_id span
        //   p span
        //   #object_id span
        //   .object_id span
        var selectorList = selector.split(",");
        for(var s = 0; s < selectorList.length; s++) {
            var elmName = selectorList[s].match(/^(\w[a-zA-Z0-9]*)?((#|\.)([a-zA-Z0-9_]+))?(\s+([a-zA-Z0-9]+))?$/);
            if (elmName && elmName.length == 7) {
                if ((elmName[4] && elmName[4].length) ) {
                    if (elmName[3] && elmName[3] == "#") {
                        // specific ID requested - ...#object_id....
                        var targetObj = origContext.getElementById(elmName[4]);
                        if (targetObj) {
                            if (elmName[1] && elmName[1].length) {
                                // specific tag+ID requested - tag#object_id....
                                if (targetObj.tagName.toLowerCase() != elmName[1].toLowerCase()) {
                                    // tag+ID combination not found
                                    targetObj = null;
                                } else {
                                }
                            }
                        }
                        if (targetObj) {
                            if (elmName[6] && elmName[6].length) {
                                // Specific subtags requested - ..... tag
                                var elmList = targetObj.getElementsByTagName(elmName[6]);
                                for(var i=0; i < elmList.length; i++) { results.push(elmList[i]); }
                            } else {
                                // No subtag requested
                                results.push(targetObj);
                            }
                        }
                    } else if (elmName[1] && elmName[1].length > 0) {
                        // specific class requested - .*\.classname\..*
                        var elmList = CaretSelector_getElementsByClassName(document, elmName[1], elmName[4]);
                        for(var i=0; i < elmList.length; i++) {
                            if (elmName[6] && elmName[6].length) {
                                // Specific subtags requested - ..... tag
                                var subList = elmList[i].getElementsByTagName(elmName[6]);
                                for(var j=0; j < subList.length; j++) {
                                    results.push(subList[j]);
                                }
                            } else {
                                results.push(elmList[i]);
                            }
                        }
                    }
                } else if (!elmName[2] || elmName[2].length <= 0) {
                    // specific tag requested
                    var elmList = origContext.getElementsByTagName(elmName[1]);
                    for(var i=0; i < elmList.length; i++) {
                        if (elmName[6] && elmName[6].length) {
                            // Specific subtags requested - ..... tag
                            var subList = elmList[i].getElementsByTagName(elmName[5]);
                            for(var j=0; j < subList.length; j++) {
                                results.push(subList[j]);
                            }
                        } else {
                            results.push(elmList[i]);
                        }
                    }
                }
            }
        }
	return results;
};


CaretSelector.error = function( msg ) {
	throw "Syntax error, unrecognized expression: " + msg;
};


if ( document.querySelectorAll ) {
	(function(){
		var oldCaretSelector = CaretSelector, div = document.createElement("div");
		div.innerHTML = "<p class='TEST'></p>";

		// Safari can't handle uppercase or unicode characters when
		// in quirks mode.
		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
			return;
		}
	
		CaretSelector = function(query, context, extra, seed){
			context = context || document;

			return oldCaretSelector(query, context, extra, seed);
		};

		for ( var prop in oldCaretSelector ) {
			CaretSelector[ prop ] = oldCaretSelector[ prop ];
		}

		div = null; // release memory in IE
	})();
}

// EXPOSE

window.CaretSelector = CaretSelector;

})();

