/**
 * @name titleAligner
 * @version 1.0
 * @description Requires jQuery, version 1.4 or higher
 * @author Marek Pepke, pepkin88@gmail.com
 */
/*jslint white: true, onevar: true, undef: true, newcap: true, nomen: true,
    regexp: true, plusplus: true, bitwise: true, browser: true, maxerr: 50,
    maxlen: 80, indent: 4 */
/*global jQuery */
jQuery(function ($) {
    var titles = {}, baseOffset = 0, init, initBaseOffset, scroll;
    initBaseOffset = function () {
        if ($('.titleAligner_baseOffset').offset()) {
            baseOffset = Math.round($('.titleAligner_baseOffset').offset().top);
        }
        scroll(true);
    };
    init = function () {
        initBaseOffset();
        $('.titleAligner_title').each(function () {
            var elem = $(this), id;
            id = elem.attr('class').match(/titleAligner_id_(\d+)/)[1];
            titles[id] = {};
            titles[id].elem = elem;
            titles[id].posState = elem.css('position');
            titles[id].posShift = elem.offsetParent().offset().top;
            titles[id].first = -baseOffset;
            titles[id].last = Infinity;
            $('.titleAligner_forId_' + id).each(function (i) {
                if ($(this).hasClass('titleAligner_first')) {
                    titles[id].first = $(this).offset().top - baseOffset;
                }
                if ($(this).hasClass('titleAligner_last')) {
                    titles[id].last = $(this).offset().top - baseOffset;
                }
            });
        });
    };
    scroll = function (e) {
        var scroll = $(document).scrollTop() + baseOffset;
        $.each(titles, function (id, item) {
            var newState = 'absolute', newPos;
            if (scroll <= item.first + baseOffset) {
                newPos = item.first + baseOffset;
            } else if (scroll >= item.last + baseOffset) {
                newPos = item.last + baseOffset;
            } else {
                newState = 'fixed';
                newPos = baseOffset;
            }
            if ((item.posState === 'absolute' && newState === 'fixed') ||
                    (item.posState === 'fixed' && newState === 'absolute') ||
                    e === true) {
                item.posState = newState;
                item.elem.css('position', newState);
                // When "position" changes from "absolute" to "fixed"
                // "offset()" causes bad position.
                // In that case setting position directly by "css()"
                // with subtracting value of margin.
                if (newState === 'fixed') {
                    item.elem.css({ top: newPos - item.elem.outerHeight(true) +
                            item.elem.innerHeight() });
                } else {
                    item.elem.offset({ top: newPos });
                }
            }
        });
    };
    // Causing to trigger scroll event.
    if (!ifMobileBrowser) {
        setTimeout(function () {
            var scrollTop = document.body.scrollTop;
            // Webkit issue - elements sometimes aren't drawn instantly after DOM ready.
            // Must initialize a little bit later.
            init();
            $(window).resize(initBaseOffset);
            $(window).scroll(scroll);
            $(document).scrollTop(scrollTop - 1);
            $(document).scrollTop(scrollTop);
        }, 100);
    }
});
