//- bemto
//- Copyright(c) 2012 Roman Komarov <kizu@kizu.ru>
//- MIT Licensed

//- Settings
- var bemto_settings_prefix = ''
- var bemto_settings_element = '__'
- var bemto_settings_modifier = '_'
- var bemto_settings_default_tag = 'div'

//- Tag mixin, used for tweaking what tag we are throwing and do we need to wrap anything here
mixin bemto_tag(tag)
    //- rewriting tag name on different contexts
    - var newTag = tag || bemto_settings_default_tag;
    - var contextIndex = bemto_chain_contexts.length;

    //- Checks for contexts if no tag given
    if !tag
        if bemto_chain_contexts[contextIndex-1] === 'inline'
            - newTag = 'span';
        else if bemto_chain_contexts[contextIndex-1] === 'list'
            - newTag = 'li';
        else if bemto_chain_contexts[contextIndex-1] === 'optionlist'
            - newTag = 'option';

    //- Attributes context checks
    if attributes.href
        - newTag = 'a';
    if attributes.for
        - newTag = 'label';
    if attributes.type
        - newTag = 'input';
    else if attributes.src
        - newTag = 'img';

    //- Contextual wrappers
    if bemto_chain_contexts[contextIndex-1] === 'list' && newTag !== 'li'
        | <li>
    else if bemto_chain_contexts[contextIndex-1] !== 'list' && bemto_chain_contexts[contextIndex-1] !== 'pseudo-list' && newTag === 'li'
        | <ul>
        - bemto_chain_contexts[bemto_chain_contexts.length] = 'pseudo-list';
    else if bemto_chain_contexts[contextIndex-1] === 'pseudo-list' && newTag !== 'li'
        | </ul>
        - bemto_chain_contexts = bemto_chain_contexts.splice(0,bemto_chain_contexts.length-1);

    //- Setting context
    if ['a','abbr','acronym','b','br','code','em','font','i','img','ins','kbd','map','samp','small','span','strong','sub','sup','label','p','h1','h2','h3','h4','h5','h6'].indexOf(newTag) !== -1
        - bemto_chain_contexts[bemto_chain_contexts.length] = 'inline';
    else if ['ul','ol'].indexOf(newTag) !== -1
        - bemto_chain_contexts[bemto_chain_contexts.length] = 'list';
    else if ['select','datalist'].indexOf(newTag) !== -1
        - bemto_chain_contexts[bemto_chain_contexts.length] = 'optionlist';
    else
        - bemto_chain_contexts[bemto_chain_contexts.length] = 'block';

    //- Not using interpolation because of Jade wontfixed bugs
    case newTag
        when 'a': a&attributes(attributes): block
        when 'abbr': abbr&attributes(attributes): block
        when 'address': address&attributes(attributes): block
        when 'article': article&attributes(attributes): block
        when 'aside': aside&attributes(attributes): block
        when 'b': b&attributes(attributes): block
        when 'blockquote': blockquote&attributes(attributes): block
        when 'body': body&attributes(attributes): block
        when 'button': button&attributes(attributes): block
        when 'caption': caption&attributes(attributes): block
        when 'cite': cite&attributes(attributes): block
        when 'code': code&attributes(attributes): block
        when 'dd': dd&attributes(attributes): block
        when 'datalist': datalist&attributes(attributes): block
        when 'del': del&attributes(attributes): block
        when 'dfn': dfn&attributes(attributes): block
        when 'dl': dl&attributes(attributes): block
        when 'dt': dt&attributes(attributes): block
        when 'em': em&attributes(attributes): block
        when 'fieldset': fieldset&attributes(attributes): block
        when 'figcaption': figcaption&attributes(attributes): block
        when 'figure': figure&attributes(attributes): block
        when 'footer': footer&attributes(attributes): block
        when 'form': form&attributes(attributes): block
        when 'h1': h1&attributes(attributes): block
        when 'h2': h2&attributes(attributes): block
        when 'h3': h3&attributes(attributes): block
        when 'h4': h4&attributes(attributes): block
        when 'h5': h5&attributes(attributes): block
        when 'h6': h6&attributes(attributes): block
        when 'header': header&attributes(attributes): block
        when 'i': i&attributes(attributes): block
        when 'ins': ins&attributes(attributes): block
        when 'kbd': kbd&attributes(attributes): block
        when 'label': label&attributes(attributes): block
        when 'legend': legend&attributes(attributes): block
        when 'li': li&attributes(attributes): block
        when 'main': main&attributes(attributes): block
        when 'mark': mark&attributes(attributes): block
        when 'nav': nav&attributes(attributes): block
        when 'ol': ol&attributes(attributes): block
        when 'option': option&attributes(attributes): block
        when 'p': p&attributes(attributes): block
        when 'picture': picture&attributes(attributes): block
        when 'pre': pre&attributes(attributes): block
        when 'q': q&attributes(attributes): block
        when 's': s&attributes(attributes): block
        when 'samp': samp&attributes(attributes): block
        when 'section': section&attributes(attributes): block
        when 'select': select&attributes(attributes): block
        when 'small': small&attributes(attributes): block
        when 'span': span&attributes(attributes): block
        when 'strong': strong&attributes(attributes): block
        when 'sub': sub&attributes(attributes): block
        when 'sup': sup&attributes(attributes): block
        when 'svg': svg&attributes(attributes): block
        when 'table': table&attributes(attributes): block
        when 'tbody': tbody&attributes(attributes): block
        when 'td': td&attributes(attributes): block
        when 'textarea': textarea&attributes(attributes): block
        when 'tfoot': tfoot&attributes(attributes): block
        when 'th': th&attributes(attributes): block
        when 'thead': thead&attributes(attributes): block
        when 'tr': tr&attributes(attributes): block
        when 'u ': u&attributes(attributes): block
        when 'ul': ul&attributes(attributes): block
        when 'var': var&attributes(attributes): block
        when 'hr': hr&attributes(attributes)
        when 'br': br&attributes(attributes)
        when 'wbr': br&attributes(attributes)
        when 'source': source&attributes(attributes)
        when 'img'
            //- If there is no title we don't need it to show even if there is some alt
            if attributes.alt && !attributes.title
                - attributes.title = ''
            //- If we have title, we must have it in alt if it's not set
            if attributes.title && !attributes.alt
                - attributes.alt = attributes.title
            if !attributes.alt
                - attributes.alt = ''
            img&attributes(attributes)
        when 'input'
            if !attributes.type
                - attributes.type = "text"
            input&attributes(attributes)
        //when 'html'
        //doctype html
        //    html&attributes(attributes): block
        default: div&attributes(attributes): block
    //- Use interpolation here for non-tweaked tags when #659 and #660 are fixed
    //-default: #{newTag}&attributes(attributes): block

    //- Closing all the wrapper tails
    if bemto_chain_contexts[contextIndex-1] === 'list' && newTag != 'li'
        | </li>

//- Some global variables
- var bemto_chain = [];
- var bemto_chain_contexts = ['block'];
//- Block
mixin b(tag, isElement)
    //- Rewriting the class for elements and modifiers
    if attributes.class
        - var bemto_classes = attributes.class;
        if bemto_classes instanceof Array
            - bemto_classes = bemto_classes.join(' ');
        - bemto_classes = bemto_classes.split(' ');
        - var bemto_block = bemto_classes[0].match(new RegExp('^(((?!' + bemto_settings_element + '|' + bemto_settings_modifier +').)+)'))[1]

        if !isElement
            - bemto_chain[bemto_chain.length] = bemto_block
            - bemto_classes[0] = bemto_classes[0]
        else
            - bemto_classes[0] = bemto_chain[bemto_chain.length-1] + bemto_settings_element + bemto_classes[0]

        - var current_block = (isElement ? bemto_chain[bemto_chain.length-1] + bemto_settings_element : '') + bemto_block

        //- Adding the block if there is only modifier
        - var has_modifier = false
        each klass in bemto_classes
            if klass.match(new RegExp('^' + current_block + '(?!' + bemto_settings_element + '[A-Za-z]' + ')' + bemto_settings_modifier + '[A-Za-z]'))
                - has_modifier = true
        if bemto_classes.indexOf(current_block) === -1 && has_modifier
            - bemto_classes[bemto_classes.length] = current_block

        each klass, i in bemto_classes
            if klass.match(new RegExp('^(?!' + bemto_settings_element + ')' + bemto_settings_modifier))
                //- Expanding the modifiers
                - bemto_classes[i] = current_block + klass
            else if klass.match(new RegExp('^' + bemto_settings_element))
                //- Expanding the mixed in elements
                if bemto_chain[bemto_chain.length-2]
                    - bemto_classes[i] = bemto_chain[bemto_chain.length-2] + klass
                else
                    - bemto_classes[i] = bemto_chain[bemto_chain.length-1] + klass

            //- Adding prefixes
            if bemto_classes[i].match(new RegExp('^' + current_block + '($|(?=' + bemto_settings_element + '|' + bemto_settings_modifier + '))'))
                - bemto_classes[i] = bemto_settings_prefix + bemto_classes[i]

        //- Write modified classes to attributes in the correct order
        - attributes.class = bemto_classes.sort().join(' ')

    +bemto_tag(tag)&attributes(attributes)
        block

    //- Closing actions (remove the current block from the chain)
    if !isElement
        - bemto_chain = bemto_chain.splice(0,bemto_chain.length-1);
    - bemto_chain_contexts = bemto_chain_contexts.splice(0,bemto_chain_contexts.length-1);

//- Element
mixin e(tag)
    +b(tag, true)&attributes(attributes): block