/**
 * cust_select_plugin.js
 * Copyright (c) 2009 myPocket technologies (www.mypocket-technologies.com)
 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * View the GNU General Public License <http://www.gnu.org/licenses/>.

 * @author Darren Mason (djmason9@gmail.com)
 * @date 5/13/2009
 * @projectDescription Replaces the standard HTML form selectbox with a custom looking selectbox. Allows for disable, multiselect, scrolling, and very customizable.
 * @version 2.1.2
 * 
 * @requires jquery.js (tested with 1.3.1)
 * 
 * @param isscrolling: 		false,				//scrolls long lists
 * @param scrollminitems:	15,					//items before scrolling
 * @param scrollheight:		150,				//height of scrolling window
 * @param preopenselect:	true,				//opens prechecked select boxes
 * @param hoverstyle:		"hover",			//css hover style name
 * @param openspeed:		"normal",			//selectbox open speed "slow","normal","fast" or numbers 1000
 * @param wrappername:		".select_wrap"		//class name of the wrapper tag
*/
(function(jQuery) {

	jQuery.fn.custSelectBox = function(options){
		//already constructed?
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("custselect");
		if (el) { return el; }
		
		var defaults = {
				isscrolling: 		true,				//scrolls long lists
				scrollminitems:		6,					//items before scrolling
				scrollheight:		108,				//height of scrolling window
				preopenselect:		true,				//opens prechecked select boxes
				hoverstyle:			"hover",			//css hover style name
				openspeed:			"normal",			//selectbox open speed "slow","normal","fast" or numbers 1000
				selectwidth:		"auto",				//set width of selectbox
				wrappername:		".select_wrap",
				defaultOption: 		true,
				isMulti: 			true,
				hideUnselected: 	true,
				onChangeEvent: 		null,
				onAjaxUpdateEvent: 	null,
				spinnerId: 			null, 
				ajaxUrl: 			'',
				ajaxUpdatePanel: 	''
			};
		//override defaults
		var opts = jQuery.extend(defaults, options);

		this.each(function() { 
			el = new jQuery.CustSelect(jQuery(this), opts);
			jQuery(this).data("custselect", el);
		});

		return el;
	};
			
	jQuery.CustSelect = function (wrap, opts) {		
		
		/* public functions */
		jQuery.extend(this, {
			showHidden: function() {
				select.find('li').show();
				setHeight();
			}, 
			getValues: function() {
				return hidden_input.val();
			}, 
			setValue: function() {
				
			},
			clear: function() {
				select_options.find('li:not(.all)').remove();
				overwriteHiddenValue('');
			},
			// this removes an li altogether
			deleteValue: function(id) {
				removeHiddenValue(id);
			},
			checkHeight: function() {
				setHeight();
			},
			
			ajaxCall: function(showSpinner) {
				ajaxCall(showSpinner);
			}
		});
			
		//css names
		var classselectbox = "selectbox";
		var selectbox = "." + classselectbox;
		var classselectboxoptionswrap = ".selectboxoptions_wrap";
		var hideitem = "hideitem";
		var classselected = "selected";
		var classselectboxopen = "selectboxopen";
		var select_value = ".select_value";
	
		//BUILD HTML TO CREATE CUSTOM SELECT BOX
		var select_wrap = jQuery(wrap);
		var base_id = select_wrap.attr('id');
		
		var select = jQuery('#' + base_id + '_inner_wrap');
		var select_options = jQuery('#' + base_id + '_list');
		var hidden_input = jQuery('#' + base_id + '_hidden');
		
		hidden_input.change(opts.onChangeEvent);
									
		//loop through options
		select_options.children().each(function(i) {
			var li = jQuery(select_options.children().get(i));			
			
			if (jQuery.inArray(li.find('.select_value').html(), hidden_input.val().split(',')) > -1) {
				li.addClass('selected');
			} 				
			else if (opts.hideUnselected && hidden_input.val() == '')
				li.hide();
		});
	
		// var thisElement = jQuery(opts.wrappername);
						
		// select.find("li").unbind().click( function() {
		select.find('li').live('click', function() {
			var element = jQuery(this);
			var id;
		
			if(!opts.isMulti || element.hasClass('all')) {
				if(!element.hasClass(classselected))
				{
					//check
					id = element.find(select_value).text();
					select.find('li.' + classselected).removeClass(classselected);
					element.addClass(classselected);
					
					overwriteHiddenValue(element.find(select_value).text());					
				}
				else
				{
					// uncheck
					// element.parent().find("." + classselected).removeClass(classselected);
					// hidden_input.val(opts.defaultOptionValue);
				}
			}
			else //checkbox
			{
				//uncheck all selection
				if (opts.defaultOption) { 
					var all = select.find('li.all');
					
					if (all.hasClass(classselected)) {
						all.removeClass(classselected);
						removeHiddenValue('all')
					}
				}					
				
				if(element.hasClass(classselected)) {
					//turn off the checkbox
					element.removeClass(classselected);
					removeHiddenValue(element.find(select_value).text())
				}
				else
				{
					//gets the value of the element
					id = element.find(select_value).text();	
					element.addClass(classselected);
					addHiddenValue(id);
				}					
			}
			
			ajaxCall(true);
						
		});
		// .live('mouseover', function(){
		// 	jQuery(this).addClass(opts.hoverstyle);
		// }).live('mouseout', function() {
		//  	jQuery(this).removeClass(opts.hoverstyle);
		// });
	
		// only the set the height if it's not set to hide selected values... or if it is set to hide them and the hidden input isn't blank
		if (!opts.hideUnselected || (opts.hideUnselected && hidden_input.val() != ''))
			setHeight();
		
		
		/** FUNCTIONS **/
		
		// appends value		
		function addHiddenValue(id) {
			if (hidden_input.val() == '')
				hidden_input.val(id);
			else
				hidden_input.val(hidden_input.val() + ',' + id);
				
			hidden_input.change();
		}
		
		// overwrites value
		function overwriteHiddenValue(id) {
			hidden_input.val(id);
			hidden_input.change();
		}
		
		// removes a value
		function removeHiddenValue(id) { 
		    // Delete this token's id from hidden input
			var vals = hidden_input.val().split(',');
			
			// does the ID exist in the hidden input? If so, find it's position and delete it
			var i = jQuery.inArray(id, hidden_input.val().split(','));
			if (i > -1) { 
				vals.splice(i, 1).toString()
				hidden_input.val(vals);
				hidden_input.change();
			}			
		}
		
		function ajaxCall(showSpinner) {
			if (sidebar_timer) {
				clearTimeout(sidebar_timer);
			}
			
			sidebar_timer = setTimeout(function () {
				if (opts.spinnerId && showSpinner) { jQuery(opts.spinnerId).show(); jQuery(opts.ajaxUpdatePanel).css('opacity', 0.4); }
					
				var params = $j('#filter_form').serialize();

				// update the name search if it exists
				if (jQuery('#name_filter').length > 0) { $j('#name_filter').liveSearch().update(); }
				
				if (opts.onAjaxUpdateEvent) opts.onAjaxUpdateEvent();
				
				jQuery.get(opts.ajaxUrl, params, function(data) { 
					$j(opts.ajaxUpdatePanel).html(data.content);
					if (opts.spinnerId && showSpinner) { jQuery(opts.spinnerId).hide(); jQuery(opts.ajaxUpdatePanel).css('opacity', ''); }
				}, 'json');
			}, 800);
		}

		function setHeight() {
			if (select.find('li').length >= opts.scrollminitems)
				select.css("height",opts.scrollheight).addClass("setScroll");
			else
			 	select.css("height", 'auto').removeClass('setScroll');
		}
		/** FUNCTIONS **/
	};
	
})(jQuery);