Source: element_prototype_and_array_prototype.js

var S = require('springbokjs-utils');
var elements = require('./elements');
var Element = require('./element');
var ElementsArray = require('./elements_array');

/**
 * Prefer use of {@link ElementsArray#getAttribute} and {@link ElementsArray#setAttribute}
 * <pre><code>
 * .attr(values)
 * .attr(name, value)
 * </code></pre>

 * @name ElementsArray#attr
 * @method
 */

/**
 * Prefer use of {@link ElementsArray#getProperty} and {@link ElementsArray#setProperty}
 * <pre><code>
 * .prop(properties)
 * .prop(name, value)
 * </code></pre>
 *
 * @name ElementsArray#prop
 * @method
 */

/**
 * Prefer use of {@link ElementsArray#getStyle} and {@link ElementsArray#setStyle}
 * <pre><code>
 * .style(properties)
 * .style(name, value)
 * </code></pre>
 *
 * @name ElementsArray#style
 * @method
 */


/**
 * Prefer use of {@link Element#getAttribute} and {@link Element#setAttribute}
 * <pre><code>
 * .attr(values)
 * .attr(name, value)
 * .attr(name)
 * </code></pre>
 *
 * @name Element#attr
 * @method
 */

/**
 * Prefer use of {@link Element#getProperty} and {@link Element#setProperty}
 * <pre><code>
 * .prop(properties)
 * .prop(name, value)
 * .prop(name)
 * </code></pre>
 *
 * @name Element#prop
 * @method
 */

/**
 * Prefer use of {@link Element#getStyle} and {@link Element#setStyle}
 * <pre><code>
 * .style(properties)
 * .style(name, value)
 * .style(name)
 * </code></pre>
 *
 * @name Element#style
 * @method
 *
 *
 */


var _methodCalledToMethodSuffix = {
    attr: 'Attribute',
    prop: 'Property',
    style: 'Style'
};
'attr prop style'.split(' ').forEach(function(mName) {
    var mEltSuffix = _methodCalledToMethodSuffix[mName];
    Element.prototype[mName] = function(name, value) {
        if (arguments.length === 1) {
            if (S.isObject(name)) {
                var elt = this[0], fn = elements['set' + mEltSuffix];
                S.object.forEach(name, function(name, value){
                    fn.call(null, elt, name, value);
                });
                return this;
            }
            return elements['get' + mEltSuffix].call(null, this[0], name);
        }
        elements['set' + mEltSuffix].call(null, this[0], name, value);
        return this;
    };
    ElementsArray.prototype[mName] = function(name, value){
        /*#if DEV*/
        if (value === undefined) {
            throw new Error('Cannot get ' + mName +'  from an list of elements');
        }
        /*#/if*/
        this._each(function(e) {
            elements['set' + mEltSuffix].call(null, e, name, value);
        });
        return this;
    };
});



/* ---- no args, return this ---- */


/**
 * Remove the element from the DOM
 *
 * @name Element#remove
 * @method
 *
 */


/**
 * Remove the elements from the DOM

 * @name ElementsArray#remove
 * @method
 */


/**
 * Remove the children's element
 *
 * @name Element#empty
 * @method
 *
 */

/**
 * Remove the children's elements

 * @name ElementsArray#empty
 * @method
 */

/**
 * Show the element (remove the class .hidden)
 *
 * @name Element#show
 * @method
 *
 */

/**
 * Show the elements (remove the class .hidden)
 *
 * @name ElementsArray#show
 * @method
 */

/**
 * Hide the element (add the class .hidden)
 *
 * @name Element#hide
 * @method
 *
 */

/**
 * Hide the elements (add the class .hidden)
 *
 * @name ElementsArray#hide
 * @method
 */

/**
 * Toggle an element's visibility using the hidden class
 *
 * @name Element#toggle
 * @method
 *
 */

/**
 * Toggle an element's visibility using the hidden class
 *
 * @name ElementsArray#toggle
 * @method
 */

/**
 * Stop any animations for the element
 *
 * @name Element#stop
 * @method
 *
 */

/**
 * Stop any animations for the elements
 *
 * @name ElementsArray#stop
 * @method
 */


'remove empty show hide toggle stop'.split(' ').forEach(function(mName) {
    Element.prototype[mName] = function() {
        elements[mName].call(null, this[0]);
        return this;
    };
    ElementsArray.prototype[mName] = function() {
        this._each(function(e) {
            elements[mName].call(null, e);
        });
        return this;
    };
    //Elt.Array.prototype[mName]=new Function('var args=arguments;
    //this.forEach(function(e){ e.'+mName+'.apply(e,args) }); };');
});

/* ---- one element/string arg, return this ---- */

var toNodeElement = function(elementOrString) {
    return elementOrString.nodeType ? elementOrString
                 : (typeof elementOrString === 'string' ? elements.parse(elementOrString) : elementOrString[0]);
};

'append prepend before after insertBefore insertAfter appendTo prependTo'.split(' ').forEach(function(mName) {
    Element.prototype[mName] = function(elementOrString) {
        elements[mName].call(null, this[0], toNodeElement(elementOrString));
        return this;
    };
});


/* ---- args, return this ---- */

('setAttributes setAttribute removeAttribute setProperty setClass setId addClass removeClass toggleClass'
    + ' setValue setStyle'
    + ' text html appendText prependText'
    + ' fadeTo fadeIn fadeOut slideDown slideUp'
    + ' on off fire').split(' ').forEach(function(mName) {
    Element.prototype[mName] = function() {
        elements[mName].bind(null, this[0]).apply(null, arguments);
        return this;
    };
    ElementsArray.prototype[mName] = function() {
        this._each(function(e){
            elements[mName].bind(null, e).apply(null, arguments);
        });
        return this;
    };
});