/*
 *
 * FBox JavaScript Library v0.9
 *
 * @author Alex Malshev
 * @tester Andrey Akulov
 * @copyright Flexites Ltd. (http://flexites.org/)
 * @license GPL
 * @requires jQuery (http://jquery.com/)
 *
 */

(function(undef) {

    var userAgent = navigator.userAgent.toLowerCase();

    // Тест на лоховской браузер (IE, ага)
    var IE = /msie/.test(userAgent) && !/opera/.test(userAgent);
    var OLD_IE = /MSIE (5\.5|6).+Win/.test(navigator.userAgent);

    /** @type {Object} ограничения по умолчанию */
    var DEFAULT_CONSTRAINTS = {
        minWidth : 300,
        minHeight : 300,
        maxWidth : 640,
        maxHeight : 480,
        offsetTop : 20,
        offsetLeft : 0
    };

    /** @type {Number} длительность вывода картинки */
    var IMAGE_FADE_DURATION = 300;

    /** @type {Number} значение прозрачности неактивного изображения превьюшки*/
    var INACTIVE_IMAGE_FADE_RATION = .65;

    /** @type {Number} длительность fade-эффекта превьюшки */
    var INACTIVE_IMAGE_FADE_DURATION = 200;

    /** @type {Number} длительность анимации прокрутки превьюшек */
    var LIST_SCROLL_DURATION = 300;

    /** @type {Number} длительность анимации изменения размеров окна */
    var RESIZE_ANIMATION_DURATION = 300;

    /** @type {Number} ширина колонки с превьюшками */
    var IMAGES_LIST_WIDTH = 100;

    /** @type {Number} прозрачность подложки */
    var OVERLAY_OPACITY = .3

    /**
     * Класс галереи
     * @class FBox
     * @param {Object} params Параметры конструктора
     */
    var FBox = function(params) {
        this.params = params || {};
        this.setup();
    }

    FBox.prototype = {
        /**
         * Настройка
         */
        setup: function() {
            // Контейнер, в котором отрисуем
            this.layout = this.params.layout || document.documentElement;
            this.$layout = $(this.layout);

            if (this.params.imageFadeDuration === undef)
                this.params.imageFadeDuration = IMAGE_FADE_DURATION;

            // Отступы от краев
            if (!this.params.padding)
                this.params.padding = 10;

            // Ограничения по ширине и высоте
            if (!this.params.constraints)
                this.params.constraints = {};
            for (var k in DEFAULT_CONSTRAINTS) {
                if (!this.params.constraints[k])
                    this.params.constraints[k] = DEFAULT_CONSTRAINTS[k];
            }
            // Ну его нафиг анимацию и плюшки, если у нас диплодок
            if (OLD_IE) {
                this.params.imagesList = false;
                this.params.animation = false;
            }

            // Боковой список изображений
            if (this.params.imagesList) {
                if (this.params.inactiveImageFadeRatio === undef)
                    this.params.inactiveImageFadeRatio = INACTIVE_IMAGE_FADE_RATION;

                if (this.params.inactiveImageFadeDuration === undef)
                    this.params.inactiveImageFadeDuration = INACTIVE_IMAGE_FADE_DURATION;

                if (this.params.imagesListWidth === undef)
                    this.params.imagesListWidth = IMAGES_LIST_WIDTH;
            }

        },

        /**
         * Отрисовка окна галереи
         */
        show: function() {
            var self = this;

            var to = (this.layout == document.documentElement)
                ? document.body
                : this.layout;

            if (this.params.showOverlay) {
                this.overlayD = $el('div')
                    .addClass('fb-overlay')
                    .css({ opacity : this.params.overlayOpacity || OVERLAY_OPACITY  })
                    .appendTo(to);

                if (this.params.overlayClickClose)
                    window.setTimeout(function() { self.overlayD.click(function() { self.hide() }) }, 800);

                if (OLD_IE)
                    this.overlayD.css({ position: 'absolute', height: this.layout.scrollHeight });

            }
            this.wrapD = $el('div')
                .addClass('fb-wrap')
                .appendTo(to);

            var cLeft = this.params.padding;

            if ((!this.width) || (!this.height)) {
                this.width = this.params.constraints.minWidth + 2 * this.params.padding;
                this.height = this.params.constraints.minHeight + 2 * this.params.padding;
                if (this.params.imagesList)
                    this.width += this.params.imagesListWidth + this.params.padding;
            }
            if (this.params.imagesList)
                cLeft += this.params.imagesListWidth + this.params.padding;


            this.outerD = $el('div')
                .addClass('fb-outer')
                .hide()
                .appendTo(this.wrapD);

            if (OLD_IE)
                this.outerD.css({ position: 'absolute' });

            this.outerD.css(this._cssCenter());

            // Фон и углы
            var _bg = $el('ins')
                .addClass('fb-bg')
                .html('<ins class="znw"></ins><ins class="zne"></ins><ins class="zsw"></ins><ins class="zse"></ins>')
                .appendTo(this.outerD);

            // Внутреннее убранство
            this.innerD = $el('div')
                .addClass('fb-inner')
                .appendTo(this.outerD);

            // Кнопочка закрыть
            var _close = $el('div')
                .addClass('fb-close')
                .click(function() { self.hide() })
                .appendTo(this.outerD);

            // Контент
            this.contentD = $el('div')
                .addClass('fb-content')
                .css({
                    left : cLeft,
                    top : this.params.padding,
                    right : this.params.padding,
                    bottom : this.params.padding
                })
                .appendTo(this.innerD);
            // Иконка загрзки
            this.loaderD = $el('div')
                .addClass('fb-loader')
                .hide()
                .appendTo(this.contentD);

            if (this.params.contentOverflow)
                this.contentD.css({ overflow: this.params.contentOverflow });

            // Превьюшки
            if (this.params.imagesList) {
                this.listWD = $el('div')
                    .addClass('fb-list')
                    .css({
                        left : this.params.padding,
                        top : this.params.padding,
                        width : this.params.imagesListWidth,
                        bottom : this.params.padding
                    }).appendTo(this.innerD);
            }

            if (this.loaded) {
                // Если контент загружен — то восстановим
                this.restoreContent();
            } else {
                // Если нет — то загрузим
                this.loadContent();
            }

            if (this.params.animation) {
                this.outerD.fadeIn(300);
            } else {
                this.outerD.show();
            }

            // Настроим события окна
            this._bindWindowEvents();

        },

        /**
         * Скрыть окно
         */
        hide: function() {
            var self = this;
            function _hide() {
                if (self.overlayD) {
                    self.overlayD.remove();
                    self.overlayD = null;
                }
                self.wrapD.remove();
                self.wrapD = null;
            }
            this._unbindWindowEvents();
            this.saveState();
            if (this.params.animation) {
                this.outerD.animate({ opacity: 0 }, 300, null, function() {
                    _hide();
                });
            } else {
                _hide();
            }
        },

        saveState: function() {
            // dummy
        },

        /**
         * Восстановить предыдущее состояние
         */
        restoreContent: function() {
            // На самом деле просто отрисуем и все
            this.drawContent();
        },

        /**
         * Загрузить контент
         */
        loadContent: function() {
            this.data = {};
            if (this.params.data) {
                // Если сразу заданы данные
                this.data = this.params.data;
            } else if (this.params.ajax) {
                // Если ajax - то выполняем запрос
                this.loadAjax(this.params.ajax);
            } else if (this.params.image) {
                // Если просто картника — то грузим ее
                this.data.image = {
                    src: this.params.image.src,
                    comment: this.params.image.comment
                };
                this.data.type = 'image';
            } else if (this.params.html) {
                // А можно просто кусок html передать
                this.data.type = 'html';
                this.data.html = this.params.html;
            }
            // Если не ajax, то отрисуем контент
            if (!this.params.ajax) {
                this.loaded = true;
                this.drawContent();
            }
        },

        /**
         * Отрисовка содержимого
         */
        drawContent: function() {
            this.currentImage = null;
            switch (this.data.type) {
                case 'image': // Изображение
                    this.loadImage(this.data.image);
                    break;

                case 'gallery': // Галерея
                    this.drawGallery(this.data.gallery);
                    break;

                case 'html': // HTML
                    this.contentD.html(this.data.html);
                    break;
            }
        },

        /**
         * Загрузка единичного изображения
         * @param {Object} image хэш-изображения
         */
        loadImage: function(image) {
            if (this.currentImage != image) {
                this._loaderShow();
                // Если галлерея, то опредлеим индекс картинки
                if (this.data.type == 'gallery') {
                    for (var i=0; i<this.data.gallery.length; i++) {
                        if (this.data.gallery[i] == image) {
                            this.imageIndex = i;
                            break;
                        }
                    }
                }
                // Грузим и рисуем
                var self = this;
                var img = new Image();
                img.onload = function() {
                    self.currentImage = image;
                    self.drawImage(this, image.comment, image._li);
                }
                img.src = image.src;
            }
        },

        /**
         * Заугрзить предыдущее фото
         */
        loadPrevImage: function() {
            if ((this.data.type == 'gallery') && (this.imageIndex > 0)) {
                this.loadImage(this.data.gallery[this.imageIndex - 1]);
            }
        },

        /**
         * Загрузить следующее фото
         */
        loadNextImage: function() {
            if ((this.data.type == 'gallery') && (this.imageIndex+1 < this.data.gallery.length)) {
                this.loadImage(this.data.gallery[this.imageIndex + 1]);
            }
        },

        /**
         * Вывести изображение
         * @param {Object} image
         * @param {String} comment
         * @param {Object} [listItem] элемент списка превьюшек
         */
        drawImage: function(image, comment, listItem) {
            // Прячем загрузчик
            this._loaderHide();

            // Меняем размер окна под картинку
            this._resizeContentArea(image.width, image.height);

            var oldD = this.currentD;

            // Помести картинку по-центру окошка
            var left = Math.floor((this._cwidth - image.width) / 2);
            var top = Math.floor((this._cheight - image.height) / 2);

            this.currentD = $el('div')
                .hide()
                .css({
                    position : 'absolute',
                    width : image.width,
                    height : image.height,
                    left : left,
                    top : top
                })
                .append(image)
                .appendTo(this.contentD);

            // Ежели есть комментарий у картнки, то и его надобно отобразить
            if (comment) {
                var bottom = (top < 0) ? -top-1: 0;
                this.currentD.append(
                    $el('div')
                    .addClass('fb-comment')
                    .css({ bottom: bottom })
                    .html('<p>'+comment+'</p>')
                    .append($el('ins').css('opacity', .6)
                    )
                );
            }
            if (this.params.animation) {
                if (oldD)
                    oldD.fadeOut(this.params.imageFadeDuration * 1.2, _$remove);
                this.currentD.fadeIn(this.params.imageFadeDuration);
            } else {
                if (oldD)
                    oldD.remove();
                this.currentD.show();
            }

            // Выделим нужную превьюшку
            if ((this.params.imagesList) && (listItem)) {
                this.listD.find('li.active')
                    .css('opacity', this.params.inactiveImageFadeRatio)
                    .removeClass('active');

                $(listItem)
                    .addClass('active')
                    .css('opacity', 1);

                // И прокрутим превьюшечки
                this._listScrollTo(listItem);
            }

            // Проверим навигационные кнопочки
            if (this.params.navigationButtons)
                this._checkNavigationButtons();
        },
        /**
         * Отрисовать галерею
         */
        drawGallery: function() {
            var self = this;

            // Проверим текущий индекс картинки (мало ли)
            if ((!this.imageIndex) || (this.imageIndex < 0)) {
                this.setImageIndex(0);
            } else if (this.imageIndex > this.data.gallery.length - 1) {
                this.setImageIndex(this.data.gallery.length - 1);
            }

            // Отрисовка првеьюшек
            if (this.params.imagesList) {
                var fadeValue = this.params.inactiveImageFadeRatio;
                var fadeDuration = this.params.inactiveImageFadeDuration;

                // закэшируем функции
                var overF, outF;
                if (this.params.animation) {
                    overF = function() { $(this).animate({ opacity: 1 }, fadeDuration) };
                    outF = function() { if (this.className != 'active') $(this).animate({ opacity: fadeValue }, fadeDuration) };
                } else {
                    overF = function() { $(this).css({ opacity: 1 }) };
                    outF = function() { if (this.className != 'active') $(this).css({ opacity: fadeValue }) };
                }


                this.listD = $el('ul')
                    .bind("mousewheel", function(e) { self._listMouseWheel(e); return false; })
                    .bind("DOMMouseScroll", function(e) { self._listMouseWheel(e); return false; })
                    .appendTo(this.listWD);


                for (var i = 0; i < this.data.gallery.length; i++) {
                    var li = document.createElement('li');
                    li._imageObject = this.data.gallery[i];
                    this.data.gallery[i]._li = li;
                    this.listD.append(
                        $(li)
                        .css('opacity', fadeValue)
                        .append(
                            $el('img')
                            .attr({
                                src : this.data.gallery[i].thumbnail,
                                title : this.data.gallery[i].comment
                            })
                        )
                    );
                }

                this.listD.find('li')
                    .hover(overF, outF)
                    .click(function() { self.loadImage(this._imageObject); });

                // кнопочки
                this.btnUD = $el('div')
                .addClass('fb-btn-up')
                    .mousedown(function() { self._listStartScroll(-1); return false; })
                    .mouseup(function() { self._listStopScroll() })
                    .appendTo(this.listWD);
                this.btnDD = $el('div')
                    .addClass('fb-btn-down')
                    .mousedown(function() { self._listStartScroll(1); return false; })
                    .mouseup(function() { self._listStopScroll() })
                    .appendTo(this.listWD);
            }
            // Отрисуем стрелочки влево-вправо, для навигации
            if (this.params.navigationButtons) {
                this.btnLD = $el('div')
                    .hide()
                    .addClass('fb-nav-prev')
                    .click(function() { self.loadPrevImage() })
                    .html('<ins></ins>')
                    .appendTo(this.contentD);
                this.btnRD = $el('div')
                    .hide()
                    .addClass('fb-nav-next')
                    .click(function() { self.loadNextImage() })
                    .html('<ins></ins>')
                    .appendTo(this.contentD);

                var btns = this.btnLD.add(this.btnRD);

                if (this.params.navigationButtonsAlwaysVisible) {
                    btns.find('ins').show();
                } else {
                    btns.hover(function() { $(this.getElementsByTagName('ins')[0]).show() }, function() { $(this.getElementsByTagName('ins')[0]).hide() });
                }
            }

            // Грузим текущую фотку
            this.loadImage(this.data.gallery[this.imageIndex]);
        },
        /**
         * Загрузить контент ajax-ом
         */
        loadAjax: function(params) {
            var self = this;
            var action = params.url;
            delete params.url;
            this._loaderShow();
            jQuery.post(action, params, function(data) { self._parseAjaxResponse(data); }, 'json');
        },
        /**
         * Установить текущий индекс картинки
         */
        setImageIndex: function(idx) {
            var self = this;
            this.imageIndex = parseInt(idx);
         },
        /**
         * Показать иконку загрузки
         */
        _loaderShow: function() {
            this.loaderD.show();

            if (this.params.useLoaderAnimation) {
                var anim_length = this.params.loaderParams.animationLength || 400;
                var anim_step = this.params.loaderParams.animationStep || 50;
                var anim_time = this.params.loaderParams.animationTime || 50;
                var l = this.loaderD.get(0);
                var p = 0;
                if (this._loaderTimer)
                    window.clearInterval(this._loaderTimer);
                this._loaderTimer = window.setInterval(function() {
                    p += anim_step;
                    if (p == anim_length)
                        p = 0;
                    l.style.backgroundPosition = '0 -'+p+'px';
                }, anim_time)
            }

        },
        /**
         * Спрятать иконку загрузки
         */
        _loaderHide: function() {
            if (this._loaderTimer) window.clearInterval(this._loaderTimer);
            this.loaderD.hide();
        },
        /**
         * Разбирает ajax-ответ
         */
        _parseAjaxResponse: function(data) {
            this._loaderHide();
            delete this.params.ajax;
            this.params.data = data;
            this.loadContent();
        },
        /**
         * Проверить активность навигационных кнопок
         */
        _checkNavigationButtons: function() {
            if (this.imageIndex > 0) {
                this.btnLD.show();
            } else {
                this.btnLD.hide();
            }
            if (this.imageIndex < this.data.gallery.length - 1) {
                this.btnRD.show();
            } else {
                this.btnRD.hide();
            }
        },
        /**
         * Прокрутить превьюшки до нужного элемента
         * @param {Object} item
         */
        _listScrollTo: function(item) {
            // Крутим, так, чтобы превьюшка посередине оказалась
            var top = item.offsetTop - ((this.listD.height() - item.clientHeight) / 2);
            if (this.params.animation) {
                this.listD.animate({ scrollTop: top }, LIST_SCROLL_DURATION);
            } else {
                this.listD.scrollTop(top);
            }
            // Проверим кнопочки заодно
            this._listCheckScrollBtns();
        },
        /**
         * Хэндлер прокрутки колесом превьюшек
         */
        _listMouseWheel: function(e) {
            var delta = e.detail ? e.detail : -e.wheelDelta;
            delta /= Math.abs(delta);
            this._listStartScroll(delta * 1.5, true);
        },
        /**
         * Инициализация прокрутки превьюшек
         * @param {Number} k сколько крутить
         * @param {Boolean} wheel колесом крутили?
         */
        _listStartScroll: function(k, wheel) {
            var self = this;
            if (this.listScrollTimer)
                window.clearInterval(this.listScrollTimer);
            this.listScrollTimer = window.setInterval(function() { self._listScroll(k) }, 10);

            if (wheel) {
                if (this._listStopTimer)
                    window.clearInterval(this._listStopTimer);
                this._listStopTimer = window.setTimeout(function() { self._listStopScroll() }, 250);
            }
        },
        /**
         * Остановить прокрутку превьюшек
         */
        _listStopScroll: function() {
            if (this.listScrollTimer) window.clearInterval(this.listScrollTimer);
        },
        _listScroll: function(k) {
            this.listD.scrollTop(this.listD.scrollTop() + k * 5);
            this._listCheckScrollBtns();
        },
        _listCheckScrollBtns: function() {
            if (!IE) {
                var list = this.listD.get(0);
                this.btnUD.css({ opacity: (list.scrollTop > 0) ? 1 : .3 });
                this.btnDD.css({ opacity: (list.scrollTop < list.scrollHeight - list.clientHeight) ? 1 : .3 });
            }
        },

        /**
         * Изменить размер окна под контент
         * @param {Number} width ширина
         * @param {Number} height высота
         */
        _resizeContentArea: function(width, height) {
            // Проверим, вписывабтся ли размеры в ограничения
            if (width < this.params.constraints.minWidth)
                width = this.params.constraints.minWidth;
            else if (width > this.params.constraints.maxWidth)
                width = this.params.constraints.maxWidth;

            if (height < this.params.constraints.minHeight)
                height = this.params.constraints.minHeight;
            else if (height > this.params.constraints.maxHeight)
                height = this.params.constraints.maxHeight;

            // Сохраним размеры контент-места
            this._cwidth = width;
            this._cheight = height;

            // Добавим отступы
            width += 2 * this.params.padding;
            height += 2 * this.params.padding;

            // И ширину превьшек, если есть
            if (this.params.imagesList)
                width += this.params.imagesListWidth + this.params.padding

            // Если размер сменился — перестраиваем все богатсво партии
            if ((this.width != width) || (this.height != height)) {
                this.width = width;
                this.height = height;
                var c = this._cssCenter();
                if (this.params.animation) {
                    this.outerD.animate(c, RESIZE_ANIMATION_DURATION, 'swing');
                } else {
                    this.outerD.css(c);
                }
                if (OLD_IE)
                    this.__IESizeFix();
            }

        },
        /**
         * Функция возвращает хэш CSS чтобы расположить окно по центру
         * @return {Object}
         */
        _cssCenter: function() {
            var r = {
                width : this.width,
                height : this.height
            };
            r.top = (this.layout.clientHeight - this.height) / 2;
            if (r.top < this.params.constraints.offsetTop)
                r.top = this.params.constraints.offsetTop;


            r.left = (this.layout.clientWidth - this.width) / 2;
            if (r.left < this.params.constraints.offsetLeft)
                r.left = this.params.constraints.offsetLeft;

            if (OLD_IE) {
                r.top += this.layout.scrollTop;
                r.left += this.layout.scrollLeft;
            }

            return r;
        },
        /**
         * Настроить события окна на изменение размера
         */
        _bindWindowEvents: function() {
            var self = this;
            this._windowOnScrollResize = function() {
                self.outerD.css(self._cssCenter());
            }
            $(window).bind('resize', this._windowOnScrollResize);
            if (OLD_IE) // а для осла еще и на прокрутку
                $(window).bind('scroll', this._windowOnScrollResize);
        },
        _unbindWindowEvents: function() {
            $(window).unbind('resize', this._windowOnScrollResize);
            if (OLD_IE) // а для осла еще и на прокрутку
                $(window).unbind('scroll', this._windowOnScrollResize);
        },
        __IESizeFix: function() {
            var self = this;
            this.contentD.css({
                width: this._cwidth,
                height: this._cheight
            });
        }
    }

    // Глобальная переменная
    window.FBox = FBox;

    // Маленкьие утилитки :)
    function $el(tagName) {
        return $(document.createElement(tagName));
    }
    function _$remove() {
        return $(this).remove();
    }


    /**
     * Плагин для jQuery галереи
     * вешается на элементы A
     */
    jQuery.fn.extend({
        FBox: function(params) {
            var $j = this;

            var pics = new Array();
            var gallery = new FBox(params);

            $j.each(function(i) {
                var p = {
                    src : this.href,
                    comment : this.title
                };
                var img = this.getElementsByTagName('img')[0];
                if (img) {
                    p.thumbnail = img.src;
                    if (img.title)
                        p.comment = img.title;
                }
                pics.push(p);
            }).click(function() {
                gallery.setImageIndex($j.index(this));
                gallery.show();
                return false;
            })
            gallery.params.data = {
                type : 'gallery',
                gallery : pics
            };
        }
    });

})();

/*
 * CHANGELOG
 *
 * v0.9
 * - новая верстка блоков
 * - данные для ajax-запроса теперь должны быть в формате json params.data
 * - оптимизации
 *
 */

/*
 * TODO
 * - модель событий
 */

/*
 Пример:
    new FBox({
        animation: true,
        imagesList: false,
        imagesListWidth: 80,
        showOverlay: true,
        overlayClickClose : true,
        useLoaderAnim: true,
        loaderParams: {
            animatioLength: 400,
            animationStep: 50,
            animationTime: 100
        },
        navigationButtons: true,
        navigationButtonsHover: true,
        constraints: {
            minWidth: 470,
            minHeight: 465,
            maxWidth: 750,
            maxHeight: 465
        },
        data: {
            type: 'gallery',
            gallery: pictures
        }
    })
    Параметры:
        animation - показывать/не показывать анимацию появления галереи (true/false)
        imageFadeDuration - время анимации картинки
        imagesList - показывать/не показывать превью картинок в области галереи (true/false),
        imagesListWidth - ширина области превьюшек (integer),
        showOverlay - показывать/не показывать затемнение под галереей/картинкой (true/false)
        overlayClickClose - скрывать окно при нажатии на свободное пространство
        useLoaderAnim - использовать внутреннюю анимацию для загрузчика (true/false)
        loaderParams - параметры анимации
            animatioLength - длина анимации (высота файла с картинкой загрузчика), должна быть кратна шагу анимации (integer) По умолчанию: 400
            animationStep - шаг анимации (минимальная высота кадра анимации) (integer) По умолчанию: 50
            animationTime - временной шаг анимации (integer) По умолчанию: 50
        navigationButtons - показывать/не показывать навигационные кнопки в галерее (true/false)
        navigationButtonsAlwayVisibleHover - зафиксировать кнопки навигации
        constraints - кое-какие-размеры
            minWidth - минимальная ширина области галереи (integer)
            minHeight - минимальная высота области галереи (integer)
            maxWidth - максимальная ширина области галереи (integer)
            maxHeight - максимальная высота области галереи (integer)
        data - тип данных для галереи     // если используется ajax (см. ниже), указывать не нужно
            type - тип данных (галерея, картинка, HTML-код) ('gallery'/'image'/'html')
            Если указан тип 'gallery',то обязательны параметры:
                gallery - массив хешей вида:
                      src - url изображения
                      thumbnail - url превьюшки //не обязателен, если imagesList указано false
                      comment - комментарий
            Если указан тип 'image', то обязательны параметры:
                image - хеш вида:
                      src - url изображения
                      comment - комментарий
            Если указан тип 'html', то обязательны параметры:
                html - html-код
        ajax - использование AJAX для получения источника данных.(хеш параметров запроса)
            url - адрес, на который нужно отправлять запрос
            ... - произвольные параметры запроса
            Ответ должен содержать JSON структуру params.data
        Алтернативные возможности инициализации без указания data (краткая запись. Параметры подставляются ВМЕСТО data):
        image: {
            src: link.href,
            comment: link.title
        } - тоже самое, что и data с типом 'image'
        html: {
            html
        } - тоже самое, что и data с типом 'html'
    Есть вариант инициализации, как плагина к jQuery:
        $("a").FBox({ параметры }) - используется если, необходимо сделать галерею, по готовым превьюшкам.
        Инициализируеся на конструкциях вида: <a href=""> ... </a>.

*/

