/**
 * jQuery plugin for basic BEM manipulations.
 * 
 * @author Max Shirshin
 * @version 2.1.3
 * 
 */
(function($, undefined) {

    var getElemClasses = function(domEl) {
        if (domEl.classList) {
            return $.makeArray(domEl.classList);
        } else {
            return $.trim(domEl.className).split(/\s+/);
        }
    };

    $.bem = {
        generateBlock: function(tag, blockName, modifiers) {
            if (blockName === undefined) {
                blockName = tag;
                tag = 'div';
            } else if (Array.isArray(blockName)) {
                modifiers = blockName;
                blockName = tag;
                tag = 'div';
            }
            
            var $block = $('<' + tag + '/>').addClass(blockName);
            
            if (Array.isArray(modifiers)) {
                for (var i = 0; i < modifiers.length; i++) {
                    $block.addClass(blockName + '_' + modifiers[i]);
                }
            }
            return $block;
        },
        
        generateElement: function(tag, blockName, elementName, modifiers) {
            if (elementName === undefined) {
                elementName = blockName;
                blockName = tag;
                tag = 'div';
            } else if (Array.isArray(elementName)) {
                modifiers = elementName;
                elementName = blockName;
                blockName = tag;
                tag = 'div';
            }
            
            var elementClassName = blockName + '__' + elementName;
            var $element = $('<' + tag + '/>').addClass(elementClassName);
            
            if (Array.isArray(modifiers)) {
                for (var i = 0; i < modifiers.length; i++) {
                    $element.addClass(elementClassName + '_' + modifiers[i]);
                }
            }
            return $element;
        }
    };
    
    $.extend($.fn, {
        getMod: function(block, elem, modName) {
            if (modName === undefined) {
                modName = elem;
                elem = undefined;
            }
            
            if (this.length) {
                var classPattern = block + (elem !== undefined ? '__' + elem : '') + '_' + modName,
                    modVal = false;
                
                $.each(getElemClasses(this.get(0)), function(i, c) {
                    if (c === classPattern) {
                        modVal = true;
                        return false;
                    } else if (c.indexOf(classPattern) === 0 && c.substr(classPattern.length, 1) === '_') {
                        modVal = c.substr(classPattern.length + 1);
                        return false;
                    }
                });
                
                return modVal;
                
            } else return undefined;
        },
        
        setMod: function(block, elem, modName, modVal) {
            if (modVal === undefined) {
                modVal = modName;
                modName = elem;
                elem = undefined;
            }
            
            return this.each(function() {
                var $this = $(this),
                    classPattern = block + (elem !== undefined ? '__' + elem : '') + '_' + modName;
                
                if (modVal === false) {
                    $.each(getElemClasses(this), function(i, c) {
                        if (c.indexOf(classPattern) === 0) {
                            var afterPattern = c.substr(classPattern.length, 1);
                            if (afterPattern === undefined || afterPattern === '_') {
                                $this.removeClass(c);
                            }
                        }
                    });
                } else if (modVal === true) {
                    $this.addClass(classPattern);
                } else {
                    $.each(getElemClasses(this), function(i, c) {
                        if (c.indexOf(classPattern) === 0 && c.substr(classPattern.length, 1) === '_') {
                            $this.removeClass(c);
                        }
                    });
                    
                    $this.addClass(classPattern + '_' + modVal);
                }
            });
        },

        hasMod: function(block, elem, modName) {
            return !! this.getMod(block, elem, modName);
        }
    });
    
})(jQuery);