(function ($) {

    var SUBMIT_POSITIONS_URL = "/pictures/update_positions";
    var DELETE_PHOTO_URL = "/pictures/delete";
    var COVER_PHOTO_URL = "/pictures/make_main";
    var CHANGE_ACCESS_URL = "/pictures/change_access";
    var COPY_PHOTO_URL = "/pictures/copy";

    var NAME = "picsaPhoto";

    /**
     * Кеш фоток для внутренних нужд
     */
    var cache = (function () {
        var cacheEle;

        function init () {
            cacheEle = $("<div></div>").appendTo("body").css({
                'position': 'absolute',
                'width': 0,
                'height': 0,
                top: -1000,
                'overflow': 'hidden'
            });
        }

        return {
            store: function (item) {
                if (!cacheEle) {
                    init();
                }
                $(cacheEle).append(item.layer);
            }
        };
    })();


    var hoverTimer = new Timer();

    var timer = new Timer(), stack = [];

    /**
     * Элемент галереи
     *
     * @param data      {Object}    данные о картинке
     * @param markup    {Node}      существующая разметка
     * @param isOwner   {Boolean}   владелец
     *
     * @field id        идентификатор
     * @field title     название картинки
     * @field width     ширина картинки
     * @field height    высота картинки
     * @field top       Y координата на холсте (без учета масштаба)
     * @field left      X координата на холсте (без учета масштаба)
     * @field links     коллекция ссылок
     * @field layer     слой элемента
     *
     * @method remove   удаляет элемент из галерии (делигирует исполнение подписчикам)
     *
     * @event remove    просит удалить себя из галереи
     * @event loaded    сообщает, что картинка загружена
     */
    PICSA.Photo = function (data, markup, isOwner, allowCover) {
        Observable(this);
        this._init(data, markup, isOwner, allowCover);
    };

    $.extend(PICSA.Photo.prototype, {
        _init: function (data, markup, isOwner, allowCover) {
            var me = this, ele;

            me.isOwner = isOwner;
            me.allowCover = allowCover;
            $.extend(me, data);

            ele = markup || $('<div class="picsa-photo photo"><div unselectable="on" class="image-layer unselectable">'+
                                  '<a href="'+ me.links.page +'"><img alt="" /></a>'+
                              '</div></div>');
            me.layer = $(ele).data(NAME, me);

            if (!markup) {
                // новая картинка. нужно подождать пока она загрузится
                cache.store(me);
                $("img", me.layer).load(function () {
                    // оповещаем подписчиков о том, что картинка загрузилась
                    // и ее можно поместить на холст
                    me.notify("loaded");
                }).attr("src", data.image);
            } else {
                // картинка уже существует
                me.notify("loaded");
            }

            $(me.layer).hover(function () {
                hoverTimer.later(200, function () {
                    me.showInfo();
                });
            }, function () {
                me.hideInfo();
            });
        },
        /**
         * Стэк измененных позиций картинок
         */
        //stack: stack,
        /**
         * Сохранение измененных позиций картинок
         * stack - общая переменная для всех объектов PICSA.Photo
         */
        submitPositions: function(){
            var data = stack, out = {};
            stack = [];

            if(data.length > 0){
                $.each(data, function () {
                    out[this.id] = {'t': this.t, 'l': this.l};
                });
                $.post(SUBMIT_POSITIONS_URL, {'positions' : JSON.stringify(out)}, function () {}, "json");
            }
        },
        /*
         * Запись измененной позиции картинки в стэк
         **/
        commitPosition: function() {
            var item = this;

            stack.push({'id': item.id, 't': item.top, 'l': item.left});
            timer.later(2000, function() {
                item.submitPositions();
            });
        },
        /**
         * Масштабируем картинку
         * @param scale
         * @param preventSubmit
         */
        setScale: function (scale, preventSubmit) {
            var w = parseInt(this.width * scale, 10),
                h = parseInt(this.height * scale, 10);

            this.layer.css({"width": w, "height": h});
            this.setPosition(scale, preventSubmit);
            $("img", this.layer).css({"width": w, "height": h});
        },

        /**
         * Перемещаем картинку
         * @param scale
         * @param preventSubmit
         */
        setPosition: function (scale, preventSubmit) {
            this.layer.css({"top": parseInt(this.top * scale, 10), "left": parseInt(this.left * scale, 10)});
            if (this.isOwner && !preventSubmit) {
                this.commitPosition();
            }
        },

        showInfo: function () {
            var me = this;

            if (me.layer.hasClass('picsa-photo-active') || me.layer.hasClass('dragging') ||
                me.layer.height() < 27 || me.layer.width() < 27) {
                return;
            }

            me.hideInfo();

            me.layer.addClass("picsa-photo-active")
                .append('<h6><em></em>' +
                    '<div class="photo-menu hidden"><ul>' +
                        '<li class="code">Коды для отображения' +
                        '<dl>' +
                        '<dt>Показать друзьям</dt>' +
                        '<dd><input type="text" class="text" value="' + me.links.page + '" /></dd>' +
                        '<dt>Для форума</dt>' +
                        '<dd><input type="text" class="text" value="' + me.links.board + '" /></dd>' +
                        '<dt>Для блога</dt>' +
                        '<dd><input type="text" class="text" value="' + me.links.blog + '" /></dd>' +
                        '<dt>Прямая ссылка</dt>' +
                        '<dd><input type="text" class="text" value="' + me.links.direct + '" /></dd>' +
                        '</dl>' +
                        '</li>' +
                        (me.isOwner ? 
                        (me.allowCover ? '<li class="cover">Сделать обложкой</li>' : '') +
                        '<li class="edit">Доступ' +
                        '<dl><dt>Разрешить просмотр </dt>' +
                        '<dd><input type="radio" class="radio" value="0" name="access" id="access_0" ' +
                            (me.access==0 ? 'checked="checked"/>' : '/>') +
                        '<label for="access_0">Только мне</label></dd>' +
                        //'<dd><input type="radio" class="radio" value="1" name="access" id="access_1" ' +
                        //    (me.access==1 ? 'checked="checked"/>' : '/>') +
                        //'<label for="access_1">Только друзьям</label></dd>' +
                        '<dd><input type="radio" class="radio" value="2" name="access" id="access_2" ' +
                            (me.access==2 ? 'checked="checked"/>' : '/>') +
                        '<label for="access_2">Всем</label></dd>' +
                        '</dl></li>' +
                        '<li class="destroy">Удалить</li>' : 
                        '<li class="copy">Сделать своей</li>') +
                    '</ul></div>' +
                '</h6>');

            if(me.layer.find('h6').offset().left > $(window).width()-250){
                me.layer.find('h6').css({'left':0});
                me.layer.find('em').css({'left':0});
                me.layer.find('.photo-menu').css({'left':'-170px'});
                me.layer.find('.photo-menu dl').css({'left':'-200px'});
            }

            $('div.photo-menu input', me.layer).click(function(event){
                if($(this).attr('type')=='text'){
                    $(this).select();
                }
                event.stopPropagation();
            });
            $('div.photo-menu', me.layer).click(function(event){
                event.stopPropagation();
            });

            $('div.photo-menu', me.layer).each(function () {
                var menu = $(this);

                $('h6', me.layer).hover(function () {
                    menu.removeClass('hidden');
                }, function () {
                    menu.addClass('hidden');
                });

                $('li', menu).hover(function () {
                    $(this).siblings('.active').removeClass('active').end().addClass('active');
                }, function () {
                    $(this).removeClass('active');
                });

                $('li.destroy', menu).click(function () {
                    me.remove();
                    me.destroy();
                    return false;
                });

                $('li.cover', menu).click(function () {
                    me.make_cover();
                    me.layer.removeClass("picsa-photo-active");
                    me.layer.find('h6').remove();
                    return false;
                });

                $('li.edit input.radio', menu).bind('click', function(){
                    var value = $(this).val();
                    $.post(CHANGE_ACCESS_URL, {'id' : me.id, 'access' : value}, function () {
                        me.access = value;
                    }, "json");
                    return true;
                });

                $('li.copy', menu).click(function(){
                    $(this).unbind('click');
                    location.href = COPY_PHOTO_URL + '?id='+me.id;
                });
            });

            // вытаскиваем картинку на передний план
            me.layer.appendTo(me.layer.parent());
        },

        hideInfo: function () {
            hoverTimer.cancel();
            $("h6", this.layer).remove();
            $(this.layer).removeClass("picsa-photo-active");
        },

        showDragMark: function(){
            if (this.layer.height() < 80 || this.layer.width() < 80) {
                return;
            }
            this.hideDragMark();

            $('<em></em>').addClass('drag').appendTo(this.layer);
        },

        hideDragMark: function(){
            $(this.layer).find('.drag').remove();
        },

        /**
         * Удаляет элемент
         * Фактически только оповещаем подписчиков, что нужно удалить
         */
        remove: function () {
            this.notify("remove");
        },

        /**
         *  Удаляет фото
         */
        destroy: function () {
            var me = this;
            $.post(DELETE_PHOTO_URL, {'id' : me.id}, function () {}, "json");
        },

        /*
         *  Делает фото обложкой альбома,
         **/
        make_cover: function() {
            var me = this;
            $.post(COVER_PHOTO_URL, {'id' : me.id}, function (resp) {
                if(resp.success){
                    me.notify('cover', {'id': me.id, 'album_id': resp.album_id, 'src': me.image});
                }
            }, "json");
        }
    });


    /**
     * Вспомогательный плагин для получения сущности по DOMNode
     */
    $.fn.picsaPhoto = function () {
        return this.eq(0).data(NAME);
    };

})(jQuery);
