/**
 * @author axsy
 */
(function($){
	
    $.fn.uiSelector = function(options){
        var uiSelector = {
            element: $('<div class="selector" />').appendTo(this.empty()),
            _isDroppedDown: false,
            current: null
        };
        
		/**
         * Public methods
         */
        uiSelector.reset = function() {
			this.containerElement.css('height', 0);
			this._isDroppedDown = false;
		}
        
		/**
		 * Private methods
		 */
        uiSelector._init = function(){
            this._createTemplate();
            this._setup();
            this._adjustCSS();
            this._addEventsListeners();
        };
        
        uiSelector._createTemplate = function(){
        	var currentElement = this.currentElement = $('<span />').appendTo(this.element);
        	var containerElement = this.containerElement = $('<div class="container" />').appendTo(this.element);
        	var droppableElement = this.droppableElement = $('<div class="droppable" />').appendTo(containerElement).wrapAll('<div />');
        	
        	var list = this.listElement = $('<ul />').appendTo(droppableElement);
            if (opts.constantValue) {
            	this.currentElement.text(opts.constantValue);
            }
            
            return this.element;
        };
        
        uiSelector._setup = function(){
        	for (listItem in opts.listItems) {
                var value = opts.listItems[listItem].value;
                var item = $('<li />').attr('id', opts.name + '_' + listItem);

               	var url = opts.urlKey.replace(/%slug%/, opts.listItems[listItem].slug);
               	item.append($('<a />').attr('href', url).text(value));

                item.appendTo(this.listElement);
                if (opts.listItems[listItem].selected && !opts.constantValue) {
                    item.addClass('current');
                    this.currentElement.text(value);
                    this.current = listItem;
                }
            }
        	$('a', this.droppableElement).click(function(event){
        		event.preventDefault();
        	});
        };
                
        uiSelector._adjustCSS = function(){
        	this.element.css({
        		width: opts.sizes[0] + 'px',
        		height: opts.sizes[1] + 'px'
        	});
        	this.currentElement.css('line-height', opts.sizes[1] + 'px');
        	
        	// based on hacks
        	var isIE6 = jQuery.browser.msie && parseInt(jQuery.browser.version) == 6;
        	var droppableWidth = isIE6 ? opts.sizes[0] : opts.sizes[0]  - 2;
        	this.droppableElement.css('width', droppableWidth + 'px');
        	
            var itemsCount = this._calculateItemsCount();
            var droppableHeight = this._droppableHeight = (itemsCount >= opts.listRows ? opts.listRows : itemsCount) * opts.sizes[2];
            // based on hacks
            if (isIE6) {
            	droppableHeight += 1;
            }
            this.droppableElement.css('height', droppableHeight + 'px');
            
            // startup
            this.containerElement.css('height', 0);
        };
        
        uiSelector._addEventsListeners = function(){
            var uiSelector = this;
            
            // hover
            this.element.hover(function(){
                uiSelector.element.addClass('iehover');
            }, function(){
            	uiSelector.element.removeClass('iehover');
            });
            
            t = null;
            $('li', this.element).hover(function(event){
                t = $(event.target); 
            	if(t.is('li'))
            		t.addClass('iehover');
            }, function(event){
            		t.removeClass('iehover');
            });

            // slide click
            this.element.click(function(e){
                uiSelector._dropToggle();
                e.preventDefault();
            });
            
            // change click
            this.listElement.click(function(e){
                uiSelector._chooseNew($(e.target));
				e.preventDefault();
            });
        };
        
        uiSelector._dropToggle = function(){
            if (this._isDroppedDown) 
                this._dropUp();
            else 
                this._dropDown();
        };
        
        uiSelector._dropDown = function(){
            var uiSelector = this;
            this.containerElement.animate({
                height: this._droppableHeight
            }, opts.animationSpeed, function(){
                uiSelector._isDroppedDown = true;
            });
        };
        
        uiSelector._dropUp = function(callback){
            var uiSelector = this;
            this.containerElement.animate({
                height: 0
            }, opts.animationSpeed, function(){
                uiSelector._isDroppedDown = false;
                if(typeof callback == 'function')
                  callback();
            });
        };
        
        uiSelector._chooseNew = function(item){
        	var uiSelector = this;
            if (item.is('a')) {
            	item = item.parent();
            }
            this.selected = item.attr('id').slice(opts.name.length + 1);
            if (!opts.constantValue) {
            	this.currentElement.text(item.text());
            }
			$('.current', this.listElement).removeClass('current');
            item.addClass('current');
            this._dropUp(function(){
                uiSelector._invokeCallback(opts.callbacks.change, uiSelector, uiSelector.selected);
            });
        };
        
        uiSelector._calculateItemsCount = function(){
            var count = 0;
            $.each(opts.listItems, function() {
            	count++;
            });
            return count;
        };
		
        uiSelector._invokeCallback = function(callback, uiSelect, parameterOne){
            if (callback) {
                callback(uiSelect, parameterOne);
            }
        };
        
        var opts = $.extend({}, $.fn.selector.defaults, options);
        
        uiSelector._init();
        return uiSelector;
    };
    
    $.fn.uiSelector.defaults = {
        name: '',
        animationSpeed: 'fast',
        listRows: 5,
        listItems: {}
    };
})(jQuery);

