(function ($) {
    $.fn.portfolioSetter = function (options) {
        var defaults = {
            itemsPerPage: 8,
            pageWidth: 1001,
            pageHeight: 430,
            itemMargin: 30,
            showCategories: true,
            allText: 'ALL',
            easing: 'easeOutExpo',
            animationSpeed: 800,
            navButtonWidth: 21,
            wavyAnimation: false,
            xmlSource: 'portfolio.xml',
            pageWrapperClass: 'page_wrapper',
            navigationId: 'portfolio_pagination',
            categoriesId: 'portfolio_categories',
            itemClass: 'portfolio_item'
        };
        var options = $.extend(defaults, options);
        options.pageHolder = $(this);
        var categories = [],
            items = [],
            pageWrappers = [],
            imagesLoaded = 0,
            counter = 0,
            ie = false,
            categoryHolder;
        var root = $('<div />').css({
            width: (options.pageWidth * 2),
            height: options.pageHeight,
            float: 'left'
        });
        $(this).css({
            width: options.pageWidth,
            height: 'auto',
            overflow: 'hidden'
        }).append(root);
        var parentId = $(this).attr('id');
        init();

        function init() {
            root.parent().append('<div class="loading"></div>');
            loadItems()
        }
        function loadItems() {
            $.ajax({
                type: 'GET',
                url: options.xmlSource,
                dataType: 'xml',
                success: function (xml) {
                    if ($(xml).find('show_categories:first').text() === 'off') {
                        options.showCategories = false
                    }
                    if (options.showCategories) {
                        $(xml).find('categories').eq(0).find('category').each(function (i) {
                            var current = $(this);
                            var category = {
                                id: current.attr('id'),
                                name: current.text()
                            };
                            categories.push(category)
                        })
                    }
                    $(xml).find('item').each(function (i) {
                        var current = $(this);
                        var thum = current.find('thumbnail:first').text();
                        var prev = current.find('preview:first').text();
                        var cat = current.find('category:first').text().split(',');
                        var desc = current.find('description:first').text();
                        var item = {
                            thumbnail: thum,
                            preview: prev,
                            category: cat,
                            description: desc,
                            obj: $('<div class="' + options.itemClass + '"><a rel="lightbox[' + parentId + ']" class="single_image" href="' + prev + '" title="' + desc + '"><img src="' + thum + '" /></a></div>')
                        };
                        items.push(item)
                    });
                    setSetter()
                }
            })
        }
        function setSetter() {
            if ($.browser.msie) {
                ie = true
            }
            root.siblings('.loading').remove();
            root.after('<div id="' + options.navigationId + '"><ul></ul></div>');
            if (options.showCategories) {
                displayCategories()
            }
            loadImages()
        }
        function displayCategories() {
            categoryHolder = $('<div id="' + options.categoriesId + '"></div>');
            categoryHolder.append('<div id="portfolio_categories_left"></div><ul></ul><div id="portfolio_categories_right"></div>');
            root.before(categoryHolder);
            var catUl = categoryHolder.find('ul');
            var allLink = $('<li>' + options.allText + '</li>');
            catUl.append(allLink);
            showSelectedCat(allLink);
            allLink.bind({
                'click': function () {
                    displayItems();
                    showSelectedCat($(this))
                },
                'mouseover': function () {
                    $(this).css({
                        cursor: 'pointer'
                    })
                }
            });
            var catNumber = categories.length;
            for (var i = 0; i < catNumber; i++)(function (i) {
                var category = $('<li>' + categories[i].name + '</li>');
                catUl.append(category);
                category.bind({
                    'click': function () {
                        displayItems(categories[i].id);
                        showSelectedCat($(this))
                    },
                    'mouseover': function () {
                        $(this).css({
                            cursor: 'pointer'
                        })
                    }
                })
            })(i)
        }
        function showSelectedCat(selected) {
            var prevSelected = categoryHolder.find('ul li.selected');
            if (prevSelected[0]) {
                var prevHtml = prevSelected.find('div.port_cat').html();
                prevSelected.html(prevHtml);
                prevSelected.removeClass('selected')
            }
            var html = selected.html();
            selected.html('<div class="port_cat_active"><div class="port_cat_l"></div><div class="port_cat">' + html + '</div><div class="port_cat_r"></div> </div>');
            selected.addClass('selected')
        }
        function loadImages() {
            var imageCount = items.length;
            for (var i in items) {
                if (items.hasOwnProperty(i)) {
                    var img = new Image();
                    $(img).load(function () {
                        imagesLoaded++;
                        if (imagesLoaded === imageCount) {
                            displayItems()
                        }
                    }).attr('src', items[i].thumbnail)
                }
            }
        }
        function displayItems() {
            var filterCat = arguments.length === 0 ? false : true;
            root.html('');
            root.width(200);
            pageWrappers = [];
            root.animate({
                marginLeft: 0
            });
            var length = items.length;
            counter = 0;
            var catId = arguments[0];
            for (var i = 0; i < length; i++)(function (i, filterCat, catId) {
                if (!filterCat || (filterCat && items[i].category.contains(catId))) {
                    if (counter % options.itemsPerPage === 0) {
                        root.width(root.width() + options.pageWidth + 20);
                        var wrapper = $('<div class="' + options.pageWrapperClass + '"></div>').css({
                            float: 'left',
                            width: options.pageWidth + options.itemMargin,
                            height: options.pageHeight
                        });
                        pageWrappers.push(wrapper);
                        root.append(wrapper)
                    }
                    if (ie) {
                        var obj = $('<div class="' + options.itemClass + '" ><a rel="lightbox[' + parentId + ']" class="single_image" href="' + items[i].preview + '" title="' + items[i].description + '"><img src="' + items[i].thumbnail + '" /></a></div>');
                        pageWrappers[pageWrappers.length - 1].append(obj.css({
                            display: 'none'
                        }));
                        items[i].obj = obj
                    } else {
                        pageWrappers[pageWrappers.length - 1].append(items[i].obj.css({
                            display: 'none'
                        }))
                    }
                    var timeout = counter >= options.itemsPerPage ? 0 : 100;
                    if (counter >= options.itemsPerPage || !options.wavyAnimation) {
                        items[i].obj.fadeIn().animate({
                            opacity: 1
                        }, 0)
                    } else {
                        setTimeout(function () {
                            items[i].obj.fadeIn().animate({
                                opacity: 1
                            }, 0)
                        }, counter * 100)
                    }
                    counter++
                }
            })(i, filterCat, catId);
            $('a[rel="lightbox[' + parentId + ']"]').prettyPhoto({
                'theme': 'dark_rounded'
            });
            showNavigation();
            setHoverFunctionality()
        }
        function showNavigation() {
            var navUl = root.siblings('#' + options.navigationId).find('ul');
            navUl.html('');
            var pageNumber = pageWrappers.length;
            if (pageNumber > 1) {
                for (var i = 0; i < pageNumber; i++)(function (i) {
                    var li = $('<li></li>');
                    navUl.append(li);
                    li.bind({
                        'click': function () {
                            var marginLeft = i * options.pageWidth + i * options.itemMargin - 2;
                            if ($.browser.msie && $.browser.version.substr(0, 1) < 7) {
                                marginLeft += i * options.itemMargin
                            }
                            root.animate({
                                marginLeft: [-marginLeft, options.easing]
                            }, options.animationSpeed);
                            navUl.find('li.selected').removeClass('selected');
                            $(this).addClass('selected')
                        },
                        'mouseover': function () {
                            $(this).css({
                                cursor: 'pointer'
                            })
                        }
                    })
                })(i);
                navUl.find('li:first').addClass('selected');
                var marginLeft = (options.pageWidth) / 2 - pageNumber * options.navButtonWidth / 2;
                navUl.css({
                    marginLeft: marginLeft
                })
            }
        }
        function setHoverFunctionality() {
            $('.portfolio_item').hover(function () {
                $(this).stop().animate({
                    opacity: 0.8
                }, 300)
            }, function () {
                $(this).stop().animate({
                    opacity: 1
                }, 300)
            })
        }
    }
}(jQuery));
Array.prototype.contains = function (value) {
    var length = this.length;
    for (var i = 0; i < length; i++) {
        if (this[i] === value) {
            return true
        }
    }
    return false
};
