function Cagi_Category(options) {
    
    var Cagi_Category =  {

        options: {
            url: '/ajax/category-list/',
            inputId: '#category',
            categoryBlockId: '#categoryBlock',
            hiddenInputId: '#category_id',
            eraseButton: '.erase-category',
            categoryId: 0,
            positionTop: 0,
            positionLeft: 0
        },

        categoryTree: {},

        blockTemplate: '#categoryBlockTemplate',

        buildData: [],

        header: '',

        init: function(options) {
            for (var k in options) {
                this.options[k] = options[k];
            }

            var block = $(this.blockTemplate).clone();
            block.attr('id', this.options.categoryBlockId.substr(1));
            block.appendTo("#container");

            this.prepareCategoryTree();

            this.buildData = this.categoryTree;
            this.bindEvents();

            // initial builing
            if (this.options.categoryId != 0) {
                this.initialBuild();
            }
        },

        initialBuild: function() {
            var id = this.options.categoryId;
            var category = Cagi_Category.getCategory(id);
            if (category.root_id == 0) {
                Cagi_Category.buildData = Cagi_Category.categoryTree;
                Cagi_Category.build();
            } else {
                Cagi_Category.header = category.name;
                Cagi_Category.buildData = Cagi_Category.categoryTree[category.root_id].child;
            }
        },

        getCategory: function(id) {
            for (c in this.categoryTree) {
                if (this.categoryTree[c].id == id) {
                    return this.categoryTree[c];
                }
                if (this.categoryTree[c].child.length === undefined) {
                    for (k in this.categoryTree[c].child) {
                        if (this.categoryTree[c].child[k].id == id) {
                            return this.categoryTree[c].child[k];
                        }
                    }
                }
            }
        },

        prepareCategoryTree: function() {
            if (Cagi_Registry.get('categories') === undefined) {
                $.ajax({
                    url: Cagi_Category.options.url,
                    async: false,
                    dataType: 'json',
                    success: function(response) {
                        Cagi_Category.categoryTree = response;
                        Cagi_Category.buildData = response;
                        // cache results
                        Cagi_Registry.set('categories', response);
                    }
                });
            } else {
                Cagi_Category.categoryTree = Cagi_Registry.get('categories');
                Cagi_Category.buildData = Cagi_Registry.get('categories');
            }
        },

        bindEvents: function() {
            $(this.options.inputId).focus(function(){
                Cagi_Category.build();

                var top = $(this).offset().top + 32; // 32 = height of input
                $(Cagi_Category.options.categoryBlockId).css('top', top + 'px');

                if (Cagi_Category.options.positionTop != 0) {
                    $(Cagi_Category.options.categoryBlockId).css('top', Cagi_Category.options.positionTop + 'px');
                }
                if (Cagi_Category.options.positionLeft != 0) {
                    $(Cagi_Category.options.categoryBlockId).css('left', Cagi_Category.options.positionLeft + 'px');
                }

                Cagi_Category.hideEraseButton();
                $(Cagi_Category.options.categoryBlockId).show();
            });

            $(Cagi_Category.options.categoryBlockId + " li a").live('click', Cagi_Category.select);

            $("#backLink").live('click', function(e){
                e.preventDefault();
                Cagi_Category.buildData = Cagi_Category.categoryTree;
                Cagi_Category.header = '';
                Cagi_Category.build();
            });

            $(Cagi_Category.options.eraseButton).click(function(){
                $(Cagi_Category.options.inputId).val('');
                $(Cagi_Category.options.hiddenInputId).val('');
                $(Cagi_Category.options.categoryBlockId + ' ul li a.active').removeClass('active');
                Cagi_Category.buildData = Cagi_Category.categoryTree;
                Cagi_Category.header = '';
                Cagi_Category.options.categoryId = 0;

                Cagi_Category.hideEraseButton();
            });
        },

        select: function(e) {
            e.preventDefault();

            if ($(this).hasClass("active")) {
                $(Cagi_Category.options.categoryBlockId).hide();
                return;
            }

            $(Cagi_Category.options.categoryBlockId + ' ul li a').removeClass("active");
            $(this).addClass("active");

            // get new active category
            var id = $(this).attr('rel');
            var category = Cagi_Category.getCategory(id);
            if (category.root_id == 0) {
                if (category.child.length === undefined) {
                    Cagi_Category.buildData = Cagi_Category.categoryTree[id].child;
                    Cagi_Category.header = category.name;
                    Cagi_Category.build();
                } else {
                    $(Cagi_Category.options.inputId).val(category.name);
                    $(Cagi_Category.options.hiddenInputId).val(id);
                    $(Cagi_Category.options.categoryBlockId).hide();

                    Cagi_Category.options.categoryId = category.id;
                }
            } else {
                var rootCategory = Cagi_Category.getCategory(category.root_id);
                var rootCategoryName = rootCategory.name;
                $(Cagi_Category.options.inputId).val(rootCategory.name + ' / ' + category.name);
                $(Cagi_Category.options.hiddenInputId).val(id);

                Cagi_Category.options.categoryId = category.id;
                $(Cagi_Category.options.categoryBlockId).hide();
            }
            Cagi_Category.showEraseButton();
        },

        showEraseButton: function() {
            $(Cagi_Category.options.inputId).parent().removeClass("for-custom-select");
            $(Cagi_Category.options.inputId).parent().addClass("for-custom-input");
        },

        hideEraseButton: function() {
            $(Cagi_Category.options.inputId).parent().removeClass("for-custom-input");
            $(Cagi_Category.options.inputId).parent().addClass("for-custom-select");
        },

        build: function() {
            $(this.options.categoryBlockId + " ul").html('');
            var html = '';

            var header = $(".categoryHeader", $(this.options.categoryBlockId));
            if (Cagi_Category.header != '') {
                header.children("h3").text(Cagi_Category.header);
                header.show();
            } else {
                header.hide();
            }


            for (k in Cagi_Category.buildData) {
                var name = Cagi_Category.buildData[k].name;
                var id = Cagi_Category.buildData[k].id;
                html += '<li>' +
                        '<a href="#" rel="' + id + '">' +
                        '<img width="70" height="70" alt="" src="/images/categories/' + id + '.png"/><span>' + name + '</span>' +
                        '</a>'
                        '</li>';
            }
            $(this.options.categoryBlockId + " ul").html(html);

            $(this.options.categoryBlockId + " ul li a[rel='" + this.options.categoryId + "']").addClass("active");
        }

    }
    
    Cagi_Category.init(options);
    return Cagi_Category;
}

