// Defines
// extensions to protoype's Element

// Rename prototype's Element class for easy access
var EL = Element;

// Same as $, but fixes ie bugs, and fails silently when id not found
var el_extended = function() { return true; }
var _allels = new Object();
var _allelsid = 0;
var el = function() {
    var results = [], element;
	for (var i = 0; i < arguments.length; i++) {
        var elem = arguments[i];
        if (!elem) { continue; }
        if (!elem._extended) {
            elem = $(elem);
            if (!elem) continue;
            elem._extended = el_extended;
            elem._allelsid = _allelsid++;
            _allels[elem._allelsid] = elem;
        }
        results.push(elem);
    }
    if (!results.length) { return null; }
    return results.length < 2 ? results[0] : results;
};

var whenel = function(elname, func) {
    var timer = window.setInterval(function() {
        var elem = el(elname);
        if (elem) {
            window.clearInterval(timer);
            func(elem);
         }
    }, 10);
}

// Extend prototype's Element class
Object.extend(Element.Methods, {

	// Attaches a behavior object to the current element
	addBehavior: function (elem, behavior, args) {
        return GenericBehavior.addBehavior(elem, behavior, args);
	},

    tell: function(elem, method, args) {
        return elem[callback] ? elem[callback].call(elem, args) : null;
    },
    
    tellBehaviors: function(elem, method, args) {
        GenericBehavior.tellElementBehaviors(elem, method, args);
    },
    
    el: function(elem, id) {
        return typeof id != 'string' ? el(id) : Element.getChildById(elem,id);
    }
    
});


Object.extend(Element, Element.Methods);

Object.extend(Element, {

    getChildById: function(elem, id) {
        var children = getAllChildren(elem);
        for (var i = 0; i < children.length; i++) {
            if (children[i].id == id) {
                return el(children[i]);
            }
        }
        return null;
    },
    
    tellChildren: function(elem, method, args) {
        EL.eachChild(elem, function(child) {
           var childelem = el(child);
           childelem[method] ? childelem[method].call(childelem, args) : null;
        });
    },
    
    tellParents: function(elem, method, args) {
        var args = $A(arguments), elem=args.shift(), callback = args.shift();
        EL.eachParent(elem, function(child) {
           var childelem = el(child);
           childelem[method] ? childelem[method].call(childelem, args) : null;
        });
    },

    eachChild: function (elem, action) {
        var children = getAllChildren(elem);
        var result = $A(children).each(action);
        return result;
    },    

    eachParent: function(node, action, result) {
        try {
            var result = result || new Array();
            var parent = node.parentNode;
            if (!parent) { return result; }
            var theresult;
            try{
                theresult = action(parent);    
                if (theresult != null) { result.push(theresult); }
                arguments.callee(parent, action, result);
            }
            catch (e) {
                if (e.result != null) {
                    result.push(e.result);
                }
                throw e;
            }
        }
        finally { return result; }
    },
    
    allChildrenById: function(elem) {
        var children = elem.getAllChildren();
        var obj = new Object();
        for (var i = 0; i < children.length; i++) {
            var id = children[i].id;
            if (!id) { continue; }
            obj[id] = el(children[i]);
        }
        return obj;
    },
 
    // ie memory cleanup methods
    unel: function(elem) {
        return;
        if (!elem || !elem._extended) return;
        elem.behaviors = null;
        /*
        var attrs = elem.attributes, i, l, n;
        if (attrs) {
            l = attrs.length;
            for (i = 0; i < l; i += 1) {
                n = attrs[i].name;
                if (typeof elem[n] === 'function') {
                    elem[n] = null;
                }
            }
        }
        */
    },
    // call before leaving a page
    unelAll: function() {
        return;
        if (!document.all) { return; }
        var els = $H(_allels).values();
        var l = els.length;
        for (var i=0; i < l; i++) {
            this.unel(els[i]);
        }        
    },
    // call when changing innerHTML
    unelDeep: function(elem) {
        return;
        if (!document.all) { return; }
        var me = this;
        var all = getAllChildren(elem);
        var l = all.length;
        for (var i=0; i < l; i++) {
            var e = all[i];
            _allels[e._allelsid];
            me.unel(e);
        }
    }
});


Element.addMethods();

function elCSS(rule) {
    var elems = getElementsBySelector(rule);
    var els = elems.map(function(elem) { return el(elem) });
    return els;
}





