/*
// jQuery multiSelect
//
// Version 1.0.2 beta
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 10 May 2009
//
// Visit http://abeautifulsite.net/notebook.php?article=62 for more information
//
// Usage: $('#control_id').multiSelect( options, callback )
//
// Options:  selectAll          - whether or not to display the Select All option; true/false, default = true
//           selectAllText      - text to display for selecting/unselecting all options simultaneously
//           noneSelected       - text to display when there are no selected items in the list
//           oneOrMoreSelected  - text to display when there are one or more selected items in the list
//                                (note: you can use % as a placeholder for the number of items selected).
//                                Use * to show a comma separated list of all selected; default = '% selected'
//
// Dependencies:  jQuery 1.2.6 or higher (http://jquery.com/)
//
// Change Log:
//
//		1.0.1	- Updated to work with jQuery 1.2.6+ (no longer requires the dimensions plugin)
//				- Changed $(this).offset() to $(this).position(), per James' and Jono's suggestions
//
//		1.0.2	- Fixed issue where dropdown doesn't scroll up/down with keyboard shortcuts
//				- Changed '$' in setTimeout to use 'jQuery' to support jQuery.noConflict
//				- Renamed from jqueryMultiSelect.* to jquery.multiSelect.* per the standard recommended at
//				  http://docs.jquery.com/Plugins/Authoring (does not affect API methods)
//
// Licensing & Terms of Use
// 
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC. 
//	
*/
if(jQuery) (function($){
	
	$.extend($.fn, {	  
    multiSelect: function(o, callback) {
			// Default options
			if( !o ) var o = {};
			if( o.selectAll == undefined ) o.selectAll = true;
			if( o.selectAllText == undefined ) o.selectAllText = "Select All";
			if( o.noneSelected == undefined ) o.noneSelected = 'Select options';
			if( o.oneOrMoreSelected == undefined ) o.oneOrMoreSelected = '% selected';
			
			// Initialize each multiSelect
			$(this).each( function() {
				var select = $(this);
				var id = $(this).attr('id');
				var input_id = '#' + id + '_input';
				var img_id = '#' + id + '_img';
				var error_id = '#' + id + '_error';
				var div_id = '#' + id + '_div';
				var html = 
				  '<table id="' + id + '" class="multiSelectMain" cellpadding="0" cellspacing="0">' +
				    '<tr>' +
				      '<td>' +
				        '<table cellpadding="0" cellspacing="0" class="multiSelectTable">' +
				          '<tr>' +
				            '<td>' +
				              '<input id="' + id + '_input" type="text" readonly="readonly" class="multiSelect" value="" style="cursor: default;" />' +
				            '</td>' +
				            '<td align="right">' +
				              '<img id="' + id + '_img" class="multiSelectImage" src="../App_Themes/Glass/Other/dropdown.bmp" />' +
				            '</td>' +
				          '</tr>'+
				        '</table>' +
				       '</td>' +
				       '<td class="multiSelectError" align="left" style="display: none;" id="' + id + '_error">' +
				        '<img src="../App_Themes/Glass/Editors/edtError.png" alt="Select at least one option." title="Select at least one option." />' +
				       '</td>' +
				    '</tr>' +
				  '</table>';
				html += '<div id="' + id + '_div" class="multiSelectOptions" style="position: absolute; z-index: 99999; display: none;">';
				if( o.selectAll ) html += '<label class="selectAll"><input type="checkbox" class="selectAll" />' + o.selectAllText + '</label>';
				$(select).find('OPTION').each( function() {
					if( $(this).val() != '' ) {
						html += '<label><input type="checkbox" name="' + $(select).attr('name') + '" value="' + $(this).val() + '"';
						//if( $(this).attr('selected') ) html += ' checked="checked"';
						html += ' />' + $(this).html() + '</label>';
					}
				});
				html += '</div>';
				$(select).after(html);

				// Events
				$(img_id).mouseover(function(){
				  $(this).addClass('hover');
				  $(this).attr('src', '../App_Themes/Glass/Other/dropdownhover.bmp');
				}).mouseout(function (){
				  $(this).removeClass('hover');
				  $(this).attr('src', '../App_Themes/Glass/Other/dropdown.bmp');
				});
				$(img_id).click( function() {
				  // Show/hide on click
					if( $(input_id).hasClass('active') ) {
						$(input_id).multiSelectOptionsHide(div_id, error_id, 'Select options');
					} else {
						$(input_id).multiSelectOptionsShow(div_id, error_id, 'Select options');
					}
					return false;
				});
				
				$(input_id).mouseover( function() {
					$(this).addClass('hover');
				}).mouseout( function() {
					$(this).removeClass('hover');
				}).click( function() {
					// Show/hide on click
					if( $(this).hasClass('active') ) {
						$(this).multiSelectOptionsHide(div_id, error_id, 'Select options');
					} else {
						$(this).multiSelectOptionsShow(div_id, error_id, 'Select options');
					}
					return false;
				}).focus( function() {
					// So it can be styled with CSS
					$(this).addClass('focus');
				}).blur( function() {
					// So it can be styled with CSS
					$(this).removeClass('focus');
				});
				
				// Determine if Select All should be checked initially
				if( o.selectAll ) {
					var sa = true;
					$(div_id).find('INPUT:checkbox').not('.selectAll').each( function() {
						if( !$(this).attr('checked') ) sa = false;
					});
					if( sa ) {
					  $(div_id).find('INPUT.selectAll').attr('checked', true).parent().addClass('checked');
					}
				}
				
				// Handle Select All
				$(div_id).find('INPUT.selectAll').click( function() {
					if( $(this).attr('checked') == true ) 
					  $(this).parent().parent().find('INPUT:checkbox').attr('checked', true).parent().addClass('checked'); 
					else 
					  $(this).parent().parent().find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
				});
				
				// Handle checkboxes
				$(div_id).find('INPUT:checkbox').click( function() {
					$(this).parent().parent().multiSelectUpdateSelected(input_id, o);
					$(this).parent().parent().find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
					$(input_id).focus();
					if( !$(this).attr('checked') ) $(this).parent().parent().find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
					if( callback ) callback($(this));
				});
				
				// Initial display
				$(div_id).each( function() {
					$(this).multiSelectUpdateSelected(input_id, o);
					$(this).find('INPUT:checked').parent().addClass('checked');
				});
				
				// Handle hovers
				$(div_id).find('LABEL').mouseover( function() {
					$(this).parent().find('LABEL').removeClass('hover');
					$(this).addClass('hover');
				}).mouseout( function() {
					$(this).parent().find('LABEL').removeClass('hover');
				});
				
				// Keyboard
				$(input_id).keydown( function(e) {
					// Is dropdown visible?
					if( $(div_id).is(':visible') ) {
						// Dropdown is visible
						// Tab
						if( e.keyCode == 9 ) {
							$(this).addClass('focus').trigger('click'); // esc, left, right - hide
							$(this).focus().next(':input').focus();
							return true;
						}
						
						// ESC, Left, Right
						if( e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39 ) {
							// Hide dropdown
							$(this).addClass('focus').trigger('click');
						}
						// Down
						if( e.keyCode == 40 ) {
							if( !$(div_id).find('LABEL').hasClass('hover') ) {
								// Default to first item
								$(div_id).find('LABEL:first').addClass('hover');
							} else {
								// Move down, cycle to top if on bottom
								$(div_id).find('LABEL.hover').removeClass('hover').next('LABEL').addClass('hover');
								if( !$(div_id).find('LABEL').hasClass('hover') ) {
									$(div_id).find('LABEL:first').addClass('hover');
								}
							}
							
							// Adjust the viewport if necessary
							$(this).multiSelectAdjustViewport($(this) );
							
							return false;
						}
						// Up
						if( e.keyCode == 38 ) {
							if( !$(div_id).find('LABEL').hasClass('hover') ) {
								// Default to first item
								$(div_id).find('LABEL:first').addClass('hover');
							} else {
								// Move up, cycle to bottom if on top
								$(div_id).find('LABEL.hover').removeClass('hover').prev('LABEL').addClass('hover');
								if( !$(div_id).find('LABEL').hasClass('hover') ) {
									$(div_id).find('LABEL:last').addClass('hover');
								}
							}
							
							// Adjust the viewport if necessary
							$(this).multiSelectAdjustViewport($(this) );
							
							return false;
						}
						// Enter, Space
						if( e.keyCode == 13 || e.keyCode == 32 ) {
							// Select All
							if( $(div_id).find('LABEL.hover INPUT:checkbox').hasClass('selectAll') ) {
								if( $(div_id).find('LABEL.hover INPUT:checkbox').attr('checked') ) {
									// Uncheck all
									$(div_id).find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
								} else {
									// Check all
									$(div_id).find('INPUT:checkbox').attr('checked', true).parent().addClass('checked');
								}
								$(div_id).multiSelectUpdateSelected(input_id, o);
								if( callback ) callback($(this));
								return false;
							}
							// Other checkboxes
							if( $(div_id).find('LABEL.hover INPUT:checkbox').attr('checked') ) {
								// Uncheck
								$(div_id).find('LABEL.hover INPUT:checkbox').attr('checked', false);
								$(div_id).multiSelectUpdateSelected(input_id, o);
								$(div_id).find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
								// Select all status can't be checked at this point
								$(div_id).find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
								if( callback ) callback($(this));
							} else {
								// Check
								$(div_id).find('LABEL.hover INPUT:checkbox').attr('checked', true);
								$(div_id).multiSelectUpdateSelected(input_id, o);
								$(div_id).find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
								if( callback ) callback($(this));
							}
						}
						return false;
					} else {
						// Dropdown is not visible
						if( e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 || e.keyCode == 32 ) { // down, enter, space - show
							// Show dropdown
							$(this).removeClass('focus').trigger('click');
							$(div_id).find('LABEL:first').addClass('hover');
							return false;
						}
						//  Tab key
						if( e.keyCode == 9 ) {
							// Shift focus to next INPUT element on page
							$(this).focus().next(':input').focus();
							return true;
						}
					}
					// Prevent enter key from submitting form
					if( e.keyCode == 13 ) return false;
				});
				
				// Eliminate the original form element
				$(select).remove();
			});
			
		},
		
		isValid: function(){
		  var id = $(this).attr('id');
		  var input_id = '#' + id + '_input';
			var img_id = '#' + id + '_img';
			var error_id = '#' + id + '_error';
			$(input_id).validate(error_id, 'Select options');
			
			if($(error_id).hasClass('error')){
			  return false;
			}else{
			  return true;
			}
		},
		
		validate: function(error_id, value) {
		  var input_id = $(this).attr('id');
		  var id = '#' + input_id.substring(0, input_id.indexOf("_input"));
		  if($(this).val() == value){
		    $(error_id).addClass('error');
		    $(id).addClass('error');
        $(error_id).show();
		  }else{
		    $(id).removeClass('error');
		    $(error_id).removeClass('error');
		    $(error_id).hide();
		  }
		},
		
		// Hide the dropdown
    multiSelectOptionsHide: function(div_id, error_id, val) {
			$(this).removeClass('active');
			$(div_id).hide();
			if(val != ''){
        $(this).validate(error_id, val);
      }
		},
		
		// Show the dropdown
		multiSelectOptionsShow: function(div_id, error_id, val) {
			// Hide any open option boxes
			$(this).multiSelectOptionsHide(div_id, error_id, '');
			
			$(div_id).find('LABEL').removeClass('hover');
			$(this).addClass('active');
			$(div_id).show();
			
			// Position it
			var offset = $(this).position();
			$(div_id).css({ top:  offset.top + $(this).outerHeight() + 'px' });
			$(div_id).css({ left: offset.left + 'px' });

			// Disappear on hover out
			multiSelectCurrent = $(this);
			var timer = '';
			$(div_id).hover( function() {
				clearTimeout(timer);
			}, function() {
				timer = setTimeout('jQuery(multiSelectCurrent).multiSelectOptionsHide("' + div_id + '", "' + error_id + '", "' + val + '"); jQuery(multiSelectCurrent).unbind("hover");', 100);
			});
		},
		
		// Update the textbox with the total number of selected items
		multiSelectUpdateSelected: function(input_id, o) {
			var i = 0, s = '';
			$(this).find('INPUT:checkbox:checked').not('.selectAll').each( function() {
				i++;
			})
			if( i == 0 ) {
				$(input_id).val( o.noneSelected );
			} else {
				if( o.oneOrMoreSelected == '*' ) {
					var display = '';
					$(this).find('INPUT:checkbox:checked').each( function() {
						if( $(this).parent().text() != o.selectAllText ) display = display + $(this).parent().text() + ', ';
					});
					display = display.substr(0, display.length - 2);
					$(input_id).val( display );
				} else {
					$(input_id).val( o.oneOrMoreSelected.replace('%', i) );
				}
			}
		},
		
		// Ensures that the selected item is always in the visible portion of the dropdown (for keyboard controls)
		multiSelectAdjustViewport: function(el) {
			// Calculate positions of elements
			var i = 0;
			var selectionTop = 0, selectionHeight = 0;
			$(el).parent().parent().parent().parent().next('.multiSelectOptions').find('LABEL').each( function() {
				if( $(this).hasClass('hover') ) { selectionTop = i; selectionHeight = $(this).outerHeight(); return; }
				i += $(this).outerHeight();
			});
			var divScroll = $(el).parent().parent().parent().parent().next('.multiSelectOptions').scrollTop();
			var divHeight = $(el).parent().parent().parent().parent().next('.multiSelectOptions').height();
			// Adjust the dropdown scroll position
			$(el).parent().parent().parent().parent().next('.multiSelectOptions').scrollTop(selectionTop - ((divHeight / 2) - (selectionHeight / 2)));
		}
		
	});
	
})(jQuery);
