/*globals jQuery*/
/*
 * Multiselectable jQuery plugin
 * A Progressive Enhancement to <select multiple>
 * Copyright Aki Bjorklund, 2009
 * http://akibjorklund.com/code/multiselectable/
 * Version 1.0
 * Released under the MIT license.
 */
(function (jQuery) {
	jQuery.fn.multiselectable = function (options) {
		var that = jQuery(this);
		options = jQuery.extend({
			template: '<table cellspacing="0" cellpadding="0" class="vm_multiple multiselectable"><tr><td>'+
					'<div style="padding-bottom: 2px;">' +
					'<table cellspacing="0" cellpadding="0" width="100%">'+
						'<tr><td class="vm_multiple_title m-selectable-from"><label for="m-selectable"></label></td>'+
							'<td align="right"><table cellspacing="0" cellpadding="0"><tr>'+
								'<td><input tabindex="1" id="m-selectable-filter" type="text" value="m-selectable-filter-value" onclick="if (this.value == \'m-selectable-filter-value\') { this.value = \'\'; this.style.color = \'#000000\'; }" class="vm_multiple_filter"></td>'+
								'<td><div tabindex="2" class="vm_multiple_button mutils-filter"></div></td>'+
							'</tr></table></td>'+
						'</tr>'+
					'</table></div></td>'+
					'<td rowspan="2" align="center"><div class="m-selectable-controls">'+
							'<a href="javascript: void(0);" class="vm_multiple_links multis-right" onclick=""></a><br />'+
							'<a href="javascript: void(0);" class="vm_multiple_links multis-left" onclick=""></a>'+
					'</div></td>'+
					'<td class="vm_multiple_title m-selectable-to"><label for="m-selected"></label></td></tr>'+
					'<tr><td class="vm_multiple_listcontainer m-selectable-from">'+
						'<select tabindex="3" multiple="multiple" class="vm_multiple_list" id="m-selectable"></select>'+
					'</td><td class="vm_multiple_listcontainer m-selectable-to">'+
						'<select tabindex="4" multiple="multiple" class="vm_multiple_selected" id="m-selected"></select>'+
					'</td></tr></table>',
			selectableLabel: 'All',
			selectedLabel: 'Selected',
			moveRightText: 'Select >',
			moveLeftText: '< Remove',
			exploration: 'Filter',
			sort: true,
			sortAscending: true
		}, options || {});
		
		//disable sorting if sortOptions plugin is not found
		if (!jQuery.fn.sortOptions) {
			options.sort = false;
		}
		
		return that.each(function () {
			var master = jQuery(this);
			
			//make sure there are no duplicate id:s inserted into the document
			var template = options.template;
			var num = 1;
			var filter = 'm-selectable-filter';
			if (jQuery('#m-selectable').length > 0) {
				while (jQuery('#m-selectable_' + num).length > 0) {
					num++;
				}
				template = template.replace(/\"m-selectable\"/g, 'm-selectable_' + num);
				template = template.replace(/\'m-selectable\'/g, '\'m-selectable_' + num + '\'');
				template = template.replace(/\"m-selectable-filter\"/g, 'm-selectable-filter_' + num);
				template = template.replace(/\'m-selectable-filter\'/g, '\'m-selectable-filter_' + num + '\'');
				template = template.replace(/\"m-selected\"/g, 'm-selected_' + num);
				
				filter = 'm-selectable-filter_' + num;
			}
			
			template = template.replace(/m-selectable-filter-value/g, options.exploration);
			
			//set the template
			master.hide().after(template);
			
			var size = master.attr('size');
			var m = master.next();
			var m1 = m.find('.m-selectable-from select');
			var m2 = m.find('.m-selectable-to select');
			
			//match the size of the reference element
			m1.attr('size', size);
			m2.attr('size', size);			
			
			//set texts according to options 
			m.find('.m-selectable-from label').text(options.selectableLabel);
			m.find('.m-selectable-to label').text(options.selectedLabel);
			m.find('.multis-right').text(options.moveRightText);
			m.find('.multis-left').text(options.moveLeftText);
			
			//move selected options to m2, unselected to m1
			master.find('option:selected').clone().removeAttr('selected').appendTo(m2);
			master.find('option').clone().removeAttr('selected').appendTo(m1);
			master.find('option:not(:selected)').remove();
			
			//do an initial sort to both selects
			if (options.sort) {
				m1.sortOptions(options.sortAscending);
				m2.sortOptions(options.sortAscending);
			}
			
			function filterValues() {			
				jQuery.get("/0_262.aspx?object=" + master.attr('objectID') + "&objectType=" + master.attr('objectTypeID') + "&search=" + vm_gid(filter).value, function(data) {
					m1.empty();
					m1.html(data);
				});

				return false;
			}
			m.find('.mutils-filter').
				click(filterValues).
				keydown(function(event) {
					if (event.keyCode == 13)
						filterValues();
				});
			
			function move(from, to, master, select) {
				from.find('option:selected').removeAttr('selected').remove().appendTo(to).each(function () {
					var matchedElem = master.find('option[value="' + $(this).val() + '"]');
					if (select) {
						matchedElem.attr('selected', 'selected');
					} else {
						matchedElem.removeAttr('selected');
					}
				});
				return false;
			}
		
			function moveLeft() {
				m2.find('option:selected').remove().each(function () {
					master.find('option[value="' + $(this).val() + '"]').remove();
					var matchedElem = m1.find('option[value="' + $(this).val() + '"]');
					if (!matchedElem[0]) {
						$(this).clone().removeAttr('selected').appendTo(m1);
					}
				});
			}
			function moveRight() {
				m1.find('option:selected').each(function () {
					var matchedElem = m2.find('option[value="' + $(this).val() + '"]');
					if (!matchedElem[0]) {
						$(this).clone(true).appendTo(master);
						if (!($.browser.msie && $.browser.version == 6)) master.find('option[value="' + $(this).val() + '"]').attr('selected', 'selected');
						$(this).clone().appendTo(m2);
					}
					$(this).removeAttr('selected');
				});
				if (options.sort) {
					to.sortOptions(options.sortAscending);
				}
			}

			//set all the events that trigger a move
			m.find('.multis-right').click(moveRight);
			m.find('.multis-left').click(moveLeft);
			m1.dblclick(moveRight);  
			m2.dblclick(moveLeft);
			m1.keydown(function (event) {
				if (event.keyCode === 13) {
					moveRight();
				}
			});
			m2.keydown(function (event) {
				if (event.keyCode === 13) {
					moveLeft();
				}
			});
		});
	};
})(jQuery);


/**
 * Get DOM element by id
 *
 * @param mixed id DOM identifier
 */
function vm_gid(id) {
	var element = document.getElementById(id);
	if (element)
		return element;
	else
		return false;
}