// Defines
// extensions to protoype's Element

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

function el(element) {
    if (arguments.length > 1) {
        for (var i = 0, elements = [], length = arguments.length; i < length; i++)
            elements.push(el(arguments[i]));
        return elements;
    }
    element = $(element);
    if (!element) return;
    // ie fix
    element.addBehavior = 
        Element.extend.cache.findOrStore(GenericElement.addBehavior);    
    return element;
}
    

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

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

// Extend prototype's Element class
var GenericElement = new Object();

Object.extend(GenericElement, {

    // 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[method] ? elem[method].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);
    },

    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;
    }
});

Element.addMethods(GenericElement);







