(function($) {
	// remover quando versao do jquery for atualizada para 1.3.2
	$.extend(
		  $.expr[ ":" ], 
		  { reallyvisible : function (a) { return !($(a).is(':hidden') || $(a).parents(':hidden').length); }}
	);
	
	$.saj = $.saj || {};
	$.saj.registrarSelect = function(selectedOptionValue, options) {
		options = $.extend({}, defaultOptions, options||{});
		
		var sajSelect = selectedOptionValue.next('table.sajSelect');
		var sajSelectOptions = sajSelect.next('ul.sajSelectOptions');
		
		var context = {
			sajSelect: sajSelect,
			selectedOptionValue: selectedOptionValue,
			selectedOptionLabel: $('input:text', sajSelect),
			sajSelectOptions: sajSelectOptions,
			sajSelectOptionsList: sajSelectOptions.children('li'),
			sajSelectedOption: null,
			dimensionCalculado: false
		};
		bindEvents(context, options);
		syncSelectedOption(context, options);
		adjustSajSelectOptionsDimension(context, options.optionsMostrados);
		context.dimensionCalculado = false;
		context.sajSelectOptions.hide();
	};
	
	//funcao callBack
	$.saj.callBackSajSelectClick = function(selectedOptionValue, event){};
	
	var onLeaveRegistrado = false;

	var defaultOptions = {
		direction: 'ltr',
		optionsMostrados: 5
	};

	var bindEvents = function (context, options) {
		var data = {context: context, options: options};
		data.context.sajSelect.bind('click', data, onLabelClick);
		data.context.sajSelectOptionsList.bind('click', data, onSelectClick);
		if(!onLeaveRegistrado) {
			$('html').bind('click', hideSajSelectOptions);
			$(window).resize(hideSajSelectOptions);
			onLeaveRegistrado = true;
		}		
	}; 
	
	var adjustSajSelectOptionsDimension = function (context, optionsMostrados) {
		var sajSelect = context.sajSelect;
		var sajSelectOptions = context.sajSelectOptions;
		if(!context.dimensionCalculado && sajSelect.is(':reallyvisible')) {
			sajSelectOptions.css('width', getSajSelectOptionsWidth(context.sajSelect, sajSelectOptions));
			sajSelectOptions.css('height', getSajSelectOptionsHeight(context.sajSelectOptionsList, optionsMostrados));
			context.dimensionCalculado = true;
		}
	};
	
	var getSajSelectOptionsWidth = function (sajSelect, sajSelectOptions) {
		if(sajSelect.width() >= sajSelectOptions.width()) {
			// soma do padding-left/right do sajSelect
			return sajSelect.width(); 
		} else {
			return sajSelectOptions.width();
		}
	};
	
	var getSajSelectOptionsHeight = function (sajSelectOptionsList, optionsMostrados) {
		// numero de options limitado pelo maximo de options mostrados
		var multiplicadorHeight = Math.min(optionsMostrados, sajSelectOptionsList.size());
		// height eh o numero de itens * (height do primeiro item + soma padding-top/bottom do primeiro item)  
		return multiplicadorHeight * getItemHeight(sajSelectOptionsList);
	};
	
	var getItemHeight = function (item) {
		// soma do padding-top/bottom do item
		var itemPadding = parseInt(item.css('padding-top')) + parseInt(item.css('padding-bottom'));
		// height eh o numero de itens * (height do primeiro item + soma padding-top/bottom do primeiro item)  
		return item.height() + itemPadding;
	};


	var syncSelectedOption = function(context, options) {
		var selectedOption = context.sajSelectOptionsList.filter('li.selectedOption');
		if(selectedOption.size() > 0) {
			selectedOption = selectedOption[0];
		} else {
			selectedOption = context.sajSelectOptionsList[0];
		}
		// define os nao selectionados como sajSelectedOption para que sejam 'deselecionados' em updateSelectedOption
		context.sajSelectedOption = context.sajSelectOptionsList.not(selectedOption);
		updateSelectedOption(context, $(selectedOption));
	};
	
	var onLabelClick = function(event) {
		var context = event.data.context;
		var options = event.data.options;
		if(!showSajSelectOptions(context, options)) {
			context.sajSelectOptions.hide();
		}
		event.stopPropagation();
	};
	
	var adjustSajSelectOptionsPosition = function (context, direction) {
		var left = context.sajSelect.position().left;
		if(direction === 'rtl') {
			left += context.sajSelect.width() - context.sajSelectOptions.width();
		}
		// msie considera offset default do browser de 2 no calculo do left por javascript
		if($.browser.msie) {
			left -= 2;
		}
		context.sajSelectOptions.css('left', left);
		// ajusta scroll para o item selecionado
		context.sajSelectOptions.scrollTop(0);
		context.sajSelectOptions.scrollTop(context.sajSelectedOption.position().top);
	};

	var showSajSelectOptions = function(context, options) {
		var show = context.sajSelectOptions.is(':hidden');
		if(show) {
			hideSajSelectOptions();
			context.sajSelectOptions.show();
			adjustSajSelectOptionsDimension(context, options.optionsMostrados);
			adjustSajSelectOptionsPosition(context, options.direction);
		}
		return show;
	};

	var hideSajSelectOptions = function() {
		$('ul.sajSelectOptions').hide();
	};	
	
	var onSelectClick = function(event) {
		var context = event.data.context;
		updateSelectedOption(context, $(this));
		$.saj.callBackSajSelectClick(context.selectedOptionValue, event);
	};
	
	var updateSelectedOption = function(context, selectedItem) {
		if(selectedItem.size() > 0) {
			var previousSelectedItem = context.sajSelectedOption;
			var selectedItemValue = $('span:first-child', selectedItem).html();
			if(previousSelectedItem != selectedItemValue) {
				context.selectedOptionValue.val(selectedItemValue);
				context.selectedOptionLabel.val($('span:last-child', selectedItem).html());
				previousSelectedItem.removeClass('selectedOption');
				context.sajSelectedOption = selectedItem.addClass('selectedOption');
			}
		}
	};
})(jQuery);
