(function () {

     var GAP = 18;
     
     /**
     * Кеш размеров кнопок
     */
    var states = [];
    var sizes = [];
    /**
     * Панель инструментов
     *
     * @param root
     * @param cfg
     *
     * @event   align
     * @event   zoom    в параметре фактор (0.2 … 1.8)
     * @event   stick   в параметре true / false
     * @event   remove
     *
     */
    PICSA.Toolbar = function (root, cfg) {
        Observable(this);
        this._init(root, cfg);
    };

    $.extend(PICSA.Toolbar.prototype, {
        _init: function (root, cfg) {
            var me = this;
            me.root = root;
            me.buttons = [];

            me.btn_root = $('<div class="buttons clearfix"></div>').appendTo(root);
            $.each(cfg.buttons, function(){
                var item = new PICSA.Button(me.btn_root, this);

                states.push(item.state=='full' ? 1 : 0);  // full - 1, compact - 0
                sizes.push(item.sizes());

                if(item.has_menu){
                    item.layer.append('<div class="menu"><div class="menu-w"></div><div class="menu-cap"><em class="l png"></em><em class="r png"></em></div></div>');
                }
                switch(item.cls){
                    case 'upload':
                        me.upload_button = item;
                        me.uploader = new PICSA.Uploader(item.layer.find('.menu-w'), PICSA.uploadUrl);

                        item.attachObserver("menu-mouseover", function(){
                            if(!item.isMenu() && !item.isDown() && item.menu_hover){
                                item.showMenu();
                            }
                        });
                        item.attachObserver('mouseup', function(){
                            if(item.isMenu()){
                                item.hideMenu();
                            }
                        });
                        break;
                    case 'albums':
                        item.layer.find('.menu').append('<div id="albums"></div>');
                        me.album_button = item;
                        me.album_panel = new PICSA.AlbumPanel("#albums", PICSA.AlbumCfg);

                        item.attachObserver("btn-mouseover", function(){
                            if(!item.isMenu() && item.btn_hover){
                                item.showMenu();
                            }
                        });
                        item.attachObserver("click", function(){
                            location.href = "/albums";
                        });
                        
                        break;
                    case 'expos':
                        item.attachObserver("click", function(){
                            location.href = "/expos";
                        });

                        break;
                    case 'stream':
                        item.attachObserver("click", function(){
                            location.href = "/pictures/live";
                        });
                        break;
                    case 'arrange':
                        item.attachObserver("mouseup", function(){                           
                            me.notify("arrange");
                        });

                        break;
                    case 'stick':
                        me.stick = item;
                        item.attachObserver("click", function(){
                            if(!item.isPressed()){
                                item.press();
                            }else{
                                item.release();
                            }
                            me.notify("stick", item.isPressed());
                            return false;
                        });
                        break;
                    case 'scale':
                        me.scaleSlider = item;
                        me.slider = new PICSA.Slider(item.layer.find('.menu-w'));
                        
                        me.slider.attachObserver("zoom", function (data) {
                            item.setValue(data);
                            me.notify("zoom", data);
                        });
                        item.attachObserver("btn-mouseover", function(){
                            if(!item.isMenu()){
                                item.showMenu();
                            }
                        });
                        item.attachObserver("click", function(){
                            me.notify("zoom", 1.0);
                            me.scaleSlider.setValue(1.0);
                            me.slider.setValue(1.0);
                            return false;
                        });
                        break;
                    case 'access':
                        me.accessPanel = new PICSA.AccessPanel(item.layer.find('.menu-w'));
                        item.attachObserver("btn-mouseover", function(){
                            if(!item.isMenu()){
                                item.showMenu();
                            }
                        });
                        break;
                    default:
                        break;
                }

                item.attachObserver("click", function (data) {
                    this.notify(data); // посылаем уведомление дальше
                    return false;
                });

                me.buttons.push(item);
            });

            me.redraw();

            $(window).resize( function () {
                me.redraw();
            });
        },
        redraw: function(){
            var me = this;
            var delta=0, eps=0, limit=0, j=0;
            var found = false;

            var width = $(me.btn_root).width() - 175;
            var current_width = GAP*(me.buttons.length-1);

            $.each(me.buttons, function(i, btn){
                current_width += (states[i]==1 ? sizes[i].fwidth : sizes[i].cwidth);
                // коррекция позиций элементов
                if(i==0){
                    btn.setPosition(0);
                }else{
                    var prev = me.buttons[i-1];
                    var prev_width = states[i-1]==1 ? sizes[i-1].fwidth : sizes[i-1].cwidth;

                    btn.setPosition(prev.left + prev_width + GAP);
                }
            });

            delta = width - current_width;

            if(delta < 0){  //сжимаемся
                delta -= me.resizeSpaces(delta);

                for(limit = 0; delta < 0 && limit <= 10; limit ++){
                    $.each(me.buttons, function(i, btn){
                        if (btn.type != 'space' && states[i]==1 && btn.weight <= limit){
                            states[i] = 0;
                            eps = sizes[i].fwidth - sizes[i].cwidth;
                            for(j=i+1; j < me.buttons.length; j++){
                                me.buttons[j].left -= eps;
                            }
                            delta += eps;
                        }
                    });
                }
                if (delta > 0){  // корректировка после сжатия кнопок
                    delta -= me.resizeSpaces(delta);
                }
                $.each(me.buttons, function(i, btn){  //отображаем изменения
                    btn.setPosition(btn.left);
                    btn.show(states[i]==1 ? 'full' : 'compact');
                });
            } else if(delta > 0){   //расширяемся
                found =  false;     //нет кнопки для расширения
                for(limit = 10; delta > 0 && !found && limit>=0; limit --){
                    $.each(me.buttons, function(i, btn){
                        if (btn.type != 'space' && states[i]==0 && btn.weight >= limit){
                            eps = sizes[i].fwidth - sizes[i].cwidth;
                            if(eps <= delta){  //расширяем
                                states[i] = 1;
                                for(j=i+1; j < me.buttons.length; j++){
                                    me.buttons[j].left += eps;
                                }
                                delta -= eps;
                            }else{
                                found = true;  //пока не расширяем ничего
                            }
                        }
                    });
                }
                if(!found){
                    delta -= me.resizeSpaces(delta);
                }
                $.each(me.buttons, function(i, btn){
                    btn.setPosition(btn.left);
                    btn.show(states[i]==1 ? 'full' : 'compact');
                });
            }
        },
        resizeSpaces: function(delta){
            var me = this;
            var spaces = [];
            var indexes = [];
            var total_width = 0, eps = 0;
            var n = 0, j = 0;
            
            $.each(me.buttons, function(i, btn){
                if (this.type=='space'){
                    spaces.push(btn);
                    indexes.push(i);
                    total_width += btn.size;
                }
            });

            n = spaces.length;
            eps = delta > 0 ? delta : Math.max(-total_width, delta);
            
            $.each(spaces, function(i, btn){
                btn.setSize(btn.size + eps/n);
                sizes[indexes[i]].fwidth += eps/n;

                for(j = indexes[i] + 1; j < me.buttons.length; j++){
                    me.buttons[j].left += eps/n;
                }
            });
            return eps;
        }
    });

})();
