/**
 * JQuery Plugin to create a fancy HTML based dropdown.
 */
(function($) {

    // Global variables for this plugin:
    var isInitialized = false;
    var currentSelectbox = null;
    var currentSlider = null;
    var lastMouseY = -1;
    var currentId = 0;
    var _dropdownData = {};

    /**
     * Utility Functionality
     */
    
    // Generates a unique ID for this plugin
    var generateId = function() {
        return 'fd-generated-id-'+(currentId++);
    };

    // Stores arbitrary data for a dropdown
    var storeData = function(id,key,data) {
    	if (_dropdownData[id] == undefined 
    		|| _dropdownData[id] == null) {
    		_dropdownData[id] = {};
    		_dropdownData[id][key] = {};
    	}
    	
    	_dropdownData[id][key] = data;
    	//alert(_dropdownData[id][key]);
    };
    
    // Retrieves arbitrary data for a dropdown
    var retrieveData = function(id,key) {
    	return _dropdownData[id][key];
    };
    
    // Checks if the specified coordinates are inside the bounding box
    // of the provided element
    var areCoordinatesInside = function(x,y,element) {
        var top = $(element).offset().top;
        var left = $(element).offset().left;
        var width = $(element).width();
        var height = $(element).height();
        return x > left && x < (left + width) &&
               y > top && y < (top + height);
    };    
    
    /**
     * Core Functionality
     */    
    
    // Returns the empty HTML for the dropdown
    var templateFactory = function(id) {
        return $("" +
    "<div class=\"fd-dropdown-container\" id=\""+id+"\">" +
        "<div class=\"fd-dropdown\">" +
            "<div class=\"fd-label-container\">" +
                "<div class=\"fd-label\">Label</div>" +
            "</div>" +
            "<div class=\"fd-btn-container\">" +
                "<div class=\"fd-btn\">&nbsp;</div>" +
            "</div>" +
            "<div class=\"fd-dropout-container\">" +
                "<div class=\"fd-dropout\">" +
                    "<div class=\"fd-options-container\">" +
                        "<div class=\"fd-options\">" +
                         	// This is where the options will be
                        "</div>" +
                    "</div>" +
                    "<div class=\"fd-scrollbar-container\">" +
                        "<div class=\"fd-scrollbar\">" +
                            "<div class=\"fd-scrollhandle\"></div>" +
                        "</div>" +
                    "</div>" +
                "</div>" +
            "</div>" +
        "</div>" +
        "<input type=\"hidden\" class=\"fd-peer\"/><div style=\"clear:both;font-size:1px;height:1px;line-height:1px\">&nbsp;</div>" + 
    "</div>");
    };

    var setupScrollbars = function(dropdown) {
    	var config = retrieveData(dropdown.attr('id'),'config');
    	var maxHeight = config.maxHeight;
    	// If the dropout container is higher then wanted
        if ($(".fd-dropout-container",dropdown).height() > maxHeight) {
        	var contentHeight = $(".fd-options-container",dropdown).height();
        	
        	// Shrink the container	and show the scrollbar
        	$(".fd-dropout-container",dropdown).css('height',maxHeight + "px");
        	$(".fd-scrollbar-container",dropdown).show();
        	$(".fd-scrollbar-container",dropdown).css('height',maxHeight + "px");
        	dropdown.addClass('fd-has-scrollbar');
        	
        	// Adjust the scroll handle
            var scrollbarHeight = maxHeight;
        	var scrollhandleHeight = Math.floor(maxHeight/contentHeight * maxHeight);
        	if (scrollhandleHeight < config.minHandleHeight) {
        		scrollhandleHeight = config.minHandleHeight;
        	}
            $(".fd-scrollhandle",dropdown).css('height',scrollhandleHeight+'px');
        }    	
    }
	
	var setupScrollbars2 = function(dropdown) {
    	var config = retrieveData(dropdown.attr('id'),'config');
		var maxHeight = config.maxHeight;
		var contentHeight = $(".fd-options-container",dropdown).height();
		//$.getScript('/_art/js/scroll.js', function() {
		
		 if ($(".fd-options-container",dropdown).height() > maxHeight) {
		  
		  $(".fd-options-container",dropdown).css('height',maxHeight + "px");
		  
		  fleXenv.initByClass("fd-options-container");
		  //alert(dropdown.attr('id'));
		  //$('.fd-dropout').fleXcroll.updateScrollBars();
		  fleXenv.updateScrollBars();
		 }
		//});
		
    	
    }
    
    // Global Dropdown click handler
    var onDropdownClickHandler = function(e) {
        if (!e.isPropagationStopped()) {
        	var dropdownShouldOpen = true;
        	if (currentSelectbox != null) {
        		var currentDropout = $('.fd-dropout-container',currentSelectbox);
        		if (!areCoordinatesInside(e.pageX,e.pageY,currentDropout)) {
        			// If the click coordinates are not inside the dropout
        			// they must be in the label
        			if ($(this).attr('id') == currentSelectbox.attr('id')) {
        				// Prevent dropdown from opening again
        				dropdownShouldOpen = false;
        			}
        		}	
        		currentDropout.hide();
                currentSelectbox.removeClass('fd-dropdown-container-active');
                currentSelectbox = null;
        	}
        	if (dropdownShouldOpen) {
	            $(".fd-dropout-container",this).show();
	            $(".fd-dropout-container",this).position({
	              my: "left top",
	              at: "left bottom",
	              offset: '0 -1',
	              of: "#" + $(this).attr('id') // This is the dropdown container
	            });
	            currentSelectbox = $(this);
	            currentSelectbox.addClass('fd-dropdown-container-active');
				$(this).focus();
        	}
        	e.stopPropagation();
        }
    };

    // Global document click handler
    var onDocumentClickHandler = function(e) {
        if (currentSelectbox != null) {
            var currentDropout = $('.fd-dropout-container',currentSelectbox);
            // If the click was outside the current dropdown, close it
            if (!(areCoordinatesInside(e.pageX,e.pageY,currentSelectbox) ||
                  areCoordinatesInside(e.pageX,e.pageY,currentDropout))) {
                currentDropout.hide();
                currentSelectbox.removeClass('fd-dropdown-container-active');
                currentSelectbox = null;
            } else {
                // If the click was INSIDE the dropout or dropdown

            }
        }
    }

    // Global document mousedown handler
    var onDocumentMouseDownHandler = function(e) {
        if (currentSelectbox != null) {
            currentSlider = $(".fd-scrollhandle",currentSelectbox);
            $(currentSlider).css('cursor','pointer');
            if (!areCoordinatesInside(e.pageX,e.pageY,currentSlider)) {
                // Reset slider to null if click was not in bounding box
            	$(currentSlider).css('cursor','');
                currentSlider = null;
            }            
        }
    }

    // Global document mouseup handler
    var onDocumentMouseUpHandler = function(e) {
        if (currentSelectbox != null && currentSlider != null) {
            // Stop the scrolling on mouse release
        	$(currentSlider).css('cursor','');
            currentSlider = null;
        }
    }

    // Global document mousemove handler
    var onDocumentMouseMoveHandler = function(e) {
        if (currentSelectbox != null && currentSlider != null) {
            if (lastMouseY != -1) {
              var moveOffset = e.pageY - lastMouseY;
              var lastTop = currentSlider.position().top;
              var nextTop = lastTop + moveOffset;
              var viewportHeight = $('.fd-dropout-container',currentSelectbox).height();
              var sliderHeight = currentSlider.height();
              var contentHeight = $('.fd-options-container',currentSelectbox).height();
              var isViewportAtBottom = lastTop + sliderHeight >= viewportHeight;
              var isViewportAtTop = lastTop <= 0;
              if (isViewportAtTop && nextTop < lastTop) { 
            	  // Prevent scrolling through the roof
            	  nextTop = 0;            	  
              }
              if (isViewportAtBottom && nextTop > lastTop) { 
            	  // Prevent scroling through the bottom
            	  nextTop = viewportHeight-currentSlider.height();            	  
              }
              currentSlider.css('top',nextTop+'px');
              
              var scrollingPosition = nextTop/(viewportHeight-sliderHeight);
              var contentTop = -1*((contentHeight-viewportHeight)*scrollingPosition); 
              $(".fd-options-container",currentSelectbox).css('top',contentTop + 'px');
              //$('#debug').html(scrollingPosition + "/" + contentTop);
            }
            lastMouseY = e.pageY;
        }
    }

    // Global on click handler for options
    var onOptionClickHandler = function(e) {
    	if (currentSelectbox != null) {
	        var currentDropout = $('.fd-dropout-container',currentSelectbox);
	        var currentPeer = $('.fd-peer',currentSelectbox);
	        var currentLabel = $('.fd-label',currentSelectbox);
	        var values = retrieveData(currentSelectbox.attr('id'),'values');
	        var value = values[$(this).parent().prevAll(".fd-option-container").size()]
	        currentLabel.html($(this).html());
	        currentPeer.val(value);
			currentPeer.trigger('change2');
	       
	        $(this).parent().siblings(".fd-option-container-active").each(function(){
	        	$(this).removeClass('fd-option-container-active')
	        });;
	        $(this).parent().addClass('fd-option-container-active');
	        currentSelectbox.removeClass('fd-dropdown-container-active');
	        markSelection(currentSelectbox);
	        currentSelectbox = null;
	        currentDropout.hide();
	        collectAllValues();
	        e.stopPropagation();
    	}
    }
    
   

    var markSelection = function(currentSelectbox) {
    	var currentPeer = $('.fd-peer',currentSelectbox);
    	currentSelectbox.removeClass('fd-has-selection');
    	if (currentPeer.val() != '') {
    		currentSelectbox.addClass('fd-has-selection');
    	}
    }
    
    // Transforms a dropdown into a fancydropdown
    jQuery.fn.fancydropdown = function(options) {
        var config = jQuery.extend({
            // Default options:
            'selectCallback': null,
            'maxHeight': '200',
            'minHandleHeight': 55
        }).extend(options);
        this.each(function() {
        var dropdownId = generateId();
        var template = templateFactory(dropdownId);

        // Set the currently selected label
        var currentLabel = $("option:selected",this).html();
        $(".fd-label",template).html(currentLabel);

        // Set the peer value and name
        $("input.fd-peer",template).val($(this).val());
        $("input.fd-peer",template).attr('name',$(this).attr('name'));

        // Populate the options
        var values = Array();
        $('option',this).each(function() {
             $(".fd-options",template).append('<div class="fd-option-container">\n\
                    <div class="fd-option">'+$(this).html()+'</div>\n\
              </div');
              values.push($(this).attr('value'));
        });

        if (!isInitialized) {
            // Lazy initialization of global stuff
            $(document).click(onDocumentClickHandler);
            $(document).mousemove(onDocumentMouseMoveHandler);
            $(document).mousedown(onDocumentMouseDownHandler);
            $(document).mouseup(onDocumentMouseUpHandler);
            isInitialized = true;
        }

        // Insert into DOM
        $(this).replaceWith(template);

        storeData(dropdownId, 'config', config);
        storeData(dropdownId, 'values', values)

        //setupScrollbars($('#'+dropdownId));
		setupScrollbars2($('#'+dropdownId));
        
        $('.fd-dropout-container',$('#'+dropdownId)).hide();
        
        // Re-Register all event handlers
        $('#'+dropdownId).click(onDropdownClickHandler);
        $('#'+dropdownId+' .fd-option').click(onOptionClickHandler);
        $('#'+dropdownId+' input').change(function() {
        	currentSelectbox = $(this).closest('.fd-dropdown-container');
        	$('.fd-option:first',currentSelectbox).click();
        });

        // Hover status for options
        $('.fd-option').hover(function(e) {
        	if (!$(this).hasClass("fd-option-hover")) {
            	$(this).addClass("fd-option-hover");
        	}
        }, function() {
        	if ($(this).hasClass("fd-option-hover")) {
        		$(this).removeClass("fd-option-hover");
        	}
        });
        
        markSelection($('#'+dropdownId));
    	});	
    };

})(jQuery);
