(function() {
    var Y = NB.Lib;

    var CLASS_NAME = "image-gallery";
    var PREV_ITEM_CLASS_NAME = "image-gallery-prev";
    var NEXT_ITEM_CLASS_NAME = "image-gallery-next";
    var ITEM_CLASS_NAME = "image-gallery-item";
    var ITEM_ACTIVE_CLASS_NAME = "image-gallery-item-active";
    var ITEM_IMG_CLASS_NAME = "image-gallery-item-img";
    var ITEMS_CLASS_NAME = "image-gallery-items";
    var ITEMS_WRAP_CLASS_NAME = "image-gallery-items-wrap";
    var PREV_ITEM_DISABLED_CLASS_NAME = "image-gallery-prev-disabled";
    var NEXT_ITEM_DISABLED_CLASS_NAME = "image-gallery-next-disabled";
    
    NB.MarsPress.ImageGallery = function() {
        NB.MarsPress.ImageGallery.superclass.constructor.apply(this, arguments);

        this._images = [];
        this._element = null;
        this._prevEl = null;
        this._nextEl = null;
        this._itemsEl = null;
        this._itemsWrapEl = null;
        this._animation = new Y.Anim({
            duration : 1,
            easing : Y.Easing.easeOut
        });

        this.publish("select", {
            emitFacade : true
        });
        
        this.publish("imageClick", {
            emitFacade : true
        });
    };

    NB.MarsPress.ImageGallery.NAME = "imageGallery";
    NB.MarsPress.ImageGallery.ATTRS = {
        selectedIndex : {
            value : 0,
            setter : function(index) {
                if(this._images.length == 0)
                {
                    return index;
                }

                var childNodes = this._itemsWrapEl.get("children");
                var current = this.get("selectedIndex");
                childNodes.item(current).removeClass(ITEM_ACTIVE_CLASS_NAME);
                childNodes.item(index).addClass(ITEM_ACTIVE_CLASS_NAME);

                // Checking if item is visible
                var offset = this.get("offset");
                var visibleItemsCount = this.get("visibleItemsCount");
                var diff = 0;
                if(index < offset)
                {
                    diff = index - offset;
                    this.scroll(diff);
                }
                else if(index > offset + visibleItemsCount - 1)
                {
                    diff = index - offset - visibleItemsCount + 1;
                    this.scroll(diff);
                }


                this._updateButtons(index);

                this.fire("select", {selectedIndex : index});

                return index;
            }
        },
        images : {
            value : [],
            setter : function(value) {
                if(!(value instanceof Array))
                {
                    return null;
                }

                this._images = value;

                if(this._element !== null && value.length > 0)
                {
                    this.renderItems();

                }

                return value;
            }
        },
        offset: {
            value : 0
        },
        thumbWidth : {
            value: 59
        },
        thumbHeight : {
            value: 59
        },
        visibleItemsCount : {
            value :  3
        }

    };
    
    Y.extend(NB.MarsPress.ImageGallery, Y.Base, {
        _getHtml : function() {
            var html = [
                '<div class="' + CLASS_NAME + ' unselectable">',
                    '<a href="#previous" class="' + PREV_ITEM_CLASS_NAME +  '"></a>',
                    '<a href="#next" class="' + NEXT_ITEM_CLASS_NAME + '"></a>',
                    '<div class="' + ITEMS_CLASS_NAME + '">',
                       '<div class="' + ITEMS_WRAP_CLASS_NAME + '"',

                       '</div>',
                    '</div>',
                '</div>'
            ].join("");

            return html;
        },
        _getItemsHtml : function() {
            var html = [];

            var images = this._images;

            var imax = Math.max(this.get("visibleItemsCount"), images.length);
            var hasImage = false;

            var thumbWidth = this.get("thumbWidth");
            var thumbHeight = this.get("thumbHeight");

            var selectedIndex = this.get("selectedIndex");

            for(var i = 0; i < imax; i++)
            {
                hasImage = (i < images.length);
                var className = ITEM_CLASS_NAME;

                if(i == selectedIndex)
                {
                    className += " " + ITEM_ACTIVE_CLASS_NAME;
                }

                html.push('<div class="' + className  + '">');

                if(hasImage)
                {
                    html.push('<img src="' + images[i].thumbnail.gallery.src + '" class="' + ITEM_IMG_CLASS_NAME + '" width="' + thumbWidth + '" height="' + thumbHeight + '" />');
                }

                html.push('</div>');
            }
            return html.join("");
        },
        _getItemOffset : function(index) {
            return - this._itemsWrapEl.get("children").item(index).get("offsetLeft");

        },
        _onClick : function(e) {

            var selectedIndex = this.get("selectedIndex");
            
            if(e.target.hasClass(PREV_ITEM_CLASS_NAME))
            {
                e.halt();
                if(!e.target.hasClass(PREV_ITEM_DISABLED_CLASS_NAME))
                {
                    this.set("selectedIndex", selectedIndex - 1);
                }
            }
            else if(e.target.hasClass(NEXT_ITEM_CLASS_NAME))
            {
                e.halt();
                if(!e.target.hasClass(NEXT_ITEM_DISABLED_CLASS_NAME))
                {
                    this.set("selectedIndex", selectedIndex + 1);
                }
            }
            else if(e.target.hasClass(ITEM_IMG_CLASS_NAME))
            {
                var node = e.target.get("parentNode");
                this.set("selectedIndex", this._itemsWrapEl.get("childNodes").indexOf(node));
                var selIndex = this.get("selectedIndex");
                this.fire("imageClick", {
                    selectedIndex : selIndex,
                    image : this.get("images")[selIndex]
                });
            }
        },
        _setItemsStyle : function() {
            var childNodes = this._itemsWrapEl.get("children");
            childNodes.each(function(childNode) {
                childNode.setStyle("width", this.get("thumbWidth") + "px");
                childNode.setStyle("height", this.get("thumbHeight") + "px");
            }, this);

            // putting all items in a one line
            this._itemsWrapEl.setStyle("width", "10000px");

            var lastIndex = childNodes.size() - 1;
            var last = childNodes.item(lastIndex);
            var marginRight = parseInt(last.getStyle("marginRight").replace("px", ""), 10);
            var lastItemX = last.get("offsetLeft");
            var lastItemWidth = last.get("offsetWidth");
            var totalWidth = lastItemX + lastItemWidth + marginRight;

            // resizing wrapper element to correct width
            this._itemsWrapEl.setStyle("width", totalWidth + "px");
            this._itemsWrapEl.setStyle("left", "0px");


            this._updateButtons();
        },
        _updateButtons : function(selectedIndex) {
            var images = this._images;

            var selectedIndex = typeof selectedIndex != "undefined" ? selectedIndex : this.get("selectedIndex");

            this._prevEl.addClass(PREV_ITEM_DISABLED_CLASS_NAME);
            this._nextEl.addClass(NEXT_ITEM_DISABLED_CLASS_NAME);

            if(selectedIndex > 0)
            {
                this._prevEl.removeClass(PREV_ITEM_DISABLED_CLASS_NAME);
            }

            if(selectedIndex < images.length - 1)
            {
                this._nextEl.removeClass(NEXT_ITEM_DISABLED_CLASS_NAME);
            }
        },
        render : function(parent) {
            parent = Y.get(parent);

            var element = Y.DOM.create(this._getHtml());
            parent.append(element);

            element = Y.get(element);
            this._element = element;
            this._prevEl = element.one("." + PREV_ITEM_CLASS_NAME);
            this._nextEl = element.one("." + NEXT_ITEM_CLASS_NAME);
            this._itemsEl = element.one("." + ITEMS_CLASS_NAME);
            this._itemsWrapEl = element.one("." + ITEMS_WRAP_CLASS_NAME);


            this._animation.set("node", this._itemsWrapEl);

            element.on("click", this._onClick, this);

            this.renderItems();

        },
        renderItems : function() {
             this._itemsWrapEl.setContent(this._getItemsHtml());
             this._setItemsStyle();

             this.set("offset", 0);
        },
        scroll : function(dir) {
            var offset = this.get("offset") + dir;

            if(this._animation && this._animation.get("running"))
            {
                this._animation.stop(false);
                this._itemsWrapEl.setStyle("left", this._getItemOffset(this.get("offset")));
            }

            this._animation.set("to", {
                left : this._getItemOffset(offset)
            });

            this._animation.run();

            this.set("offset", offset);
            this._updateButtons();
        }
    });
    
    
})();
