/**
 * @author Gorsh
 */

$.fn.gorshSel = function(options){

  // настройки по умолчанию
  var options = jQuery.extend({
		elements: 'div'
  },options);
  return this.each(function() {
	var t = this;
 jQuery(document).unbind('keydown');
 jQuery(document).keydown(function(event){ 	
 	if (focused) {

		if ($(t).find(options.elements + '.active').length)
			var active = jQuery(t).find(options.elements + '.active');
		if ((!event.ctrlKey)&&(event.keyCode!=46)) 
			jQuery(t).find(options.elements + '.selected').removeClass('selected');
		switch (event.keyCode ? event.keyCode : event.which ? event.which : null) {
			case 38:
				if ($(active)[0] != $(t).find(options.elements + ':first')[0]) {
					active.removeClass('active');
					active.prev().addClass('selected').addClass('active');
				}
				else {
					active.addClass('selected').addClass('active');
				}
				$('#plusPopUp').css('display', 'none');
				return false;
			case 40:
				if ($(active)[0] != $(t).find(options.elements + ':last')[0]) {
					active.removeClass('active');
					active.next().addClass('selected').addClass('active');
				}
				else {
					active.addClass('selected').addClass('active');
				}
				$('#plusPopUp').css('display', 'none');
				return false;
				
			case 46:
				 active.addClass('selected').addClass('active');
				 tracklists[activeTracklist].deleteTracks();
				 break;
			 case 13:
				 active.addClass('selected').addClass('active');
				 load_track_in_player("/track/get/" + active.children('.playButton')[0].id + "/");				 

				 break;
		}
	}
 });		
 jQuery(this).find(options.elements)
 	.mousedown(
	 function(event){
	 		jQuery(t).find(options.elements + '.active').removeClass('active');
	 		if((!event.ctrlKey))
				jQuery(t).find(options.elements + '.selected')
    		          .removeClass('selected');
			if (this.className.indexOf('selected')!=-1) {
				jQuery(this).removeClass('selected').addClass('active');
			}
			else {
				jQuery(this).addClass('selected').addClass('active');
			}
			allTracksSelected = 0;
			focused = 1;
		}
	);


  });
 
};

var focused = 0;

$.fn.dropDownSelect = function(options){

  // настройки по умолчанию

 return this.each(function() {
	var t = this;
	$(t).addClass("dropDownSelect");
	var h = "";
	h += "<div class='selectItem chosen'>" + options.start + "</div>";
	h += "<input type='text' value='Другой...' onfocus='if(this.value==\"Другой...\") this.value=\"\";' onblur='if(this.value==\"\") this.value=\"Другой...\";'/>";
	for(i=0;i<options.items.length;i++){
		h += "<div class='selectItem'>" + options.items[i] + "</div>";
	}
	$(t).html(h);
	t.realHeight = t.offsetHeight;
	
	$(t).css("height", $(t).children(".chosen")[0].offsetHeight + "px");
	t.full = 0;
	
	$(t).children("input").bind('keydown', function(ev){
		if(ev.keyCode==13){
			$(t).children(".chosen").html($(this).val());
			$(t).css("height", $(t).children(".chosen")[0].offsetHeight + "px");
			$(this).val('');
		}
	});
	
	$(t).children(".selectItem").bind("click", function(){
		if (t.full == 0) {
			$(t).css("height", t.realHeight + "px");
			t.full = 1;
		} else {
			$(t).css("height", $(t).children(".chosen")[0].offsetHeight + "px");
			$(t).children(".chosen").html($(this).html());
			t.full = 0;
		}
	});
 });
};

/* 
 * vim: noexpandtab 
 */

/**
 * JQuery UI combobox plugin.  This may be called on any element; the element
 * is replaced by a text field and drop-down div.  If the replaced element was
 * a select, the combobox options can be picked up from the contents of the
 * select.  Otherwise, the 'data' option must be provided to specify choice.
 *
 * Method names in documentation are relative to the JQuery UI infrastructure,
 * i.e. the method call is always 'combobox', and then the method name is
 * passed as the first (string) argument.
 *
 * @fileoverview
 * @author Jonathan Tang
 * @dependency jquery-1.2.6.js
 * @dependency ui.core.js
 * @version 1.0.1
 */
;(function($) {
	
var KEY_UP = 38,
	KEY_DOWN = 40,
	KEY_ENTER = 13,
	KEY_ESC = 27,
	KEY_F4 = 115;

$.widget('ui.combobox', {


	init: function() {
		var that = this;
		var options = this.options;
		var inputElem = $('<input type = "text" />');

		if(this.element[0].tagName.toLowerCase() == 'select') {
			fillDataFromSelect(options, this.element);
		}

		function closeListOnDocumentClick() {
			that.hideList();
			$(document).unbind('click', closeListOnDocumentClick);
		};

		this.arrowElem = $(this.options.arrowHTML.call(this))
			.click(function(e) {
				if(that.isListVisible()) {
					that.hideList();
				} else {
					that.showList();
					$(document).click(closeListOnDocumentClick);
				}
				return false;
			}); 

		function maybeCopyAttr(name, elem) {
			var val = that.element.attr(name);
			if(val) {
				if(name == 'class') {
					elem.addClass(val);
				} else {
					elem.attr(name, val);
				}
			}
		};

		maybeCopyAttr('class', inputElem);
		maybeCopyAttr('name', inputElem);
		maybeCopyAttr('title', inputElem);
		maybeCopyAttr('dir', inputElem);
		maybeCopyAttr('lang', inputElem);
		maybeCopyAttr('xml:lang', inputElem);

		maybeCopyAttr('size', inputElem);
		maybeCopyAttr('value', inputElem);

		// Maxlength comes back -1 if unset, which causes problems when set
		if(this.element.attr('maxlength') != -1) {
			inputElem.attr('maxlength', this.element.attr('maxlength'));
		}

		this.oldElem = this.element
			.unbind('getData.combobox')
			.unbind('setData.combobox')
			.unbind('remove')
			.after(this.arrowElem)
			.after(inputElem)
			.remove();
		this.listElem = this.buildList().insertAfter(this.arrowElem).hide();

		// ID copied afterwards so we never have two elements with the same
		// ID in the DOM.
		maybeCopyAttr('id', inputElem);
		maybeCopyAttr('class', this.listElem);
		maybeCopyAttr('class', this.arrowElem);

		this.element = inputElem
			.keyup(function(e) {
				if(e.which == KEY_F4) { 
					that.showList(e);
				}
			})
			.change(boundCallback(this, 'fireEvent', 'select'));

		if(options.autoShow) {
			this.element
				.focus(boundCallback(this, 'showList'))
				.blur(function(e) {
					that.finishSelection(that.selectedIndex, e);
					that.hideList();
				});
		}
		
		$(this.element).val(options.data[0]);
		
		$(this.element).bind('mouseover', function(){
			$(that.arrowElem).css('background-position', '-17px 0');
		});
		
		$(this.element).bind('mouseout', function(){
			$(that.arrowElem).css('background-position', '0 0');
		});
		
		$(this.arrowElem).bind('mouseover', function(){
			$(this).css('background-position', '-17px 0');
		});
		
		$(this.arrowElem).bind('mouseout', function(){
			$(this).css('background-position', '0 0');
		});
		
		if(options.initstr){
			$(this.element).val(( options.initstr == ' ' ) ? ('') : (options.initstr));
			
			$(this.element).bind('blur', function(){
				if(this.value == ''){
					this.value = ( ( options.initstr == ' ' ) ? ('') : (options.initstr) );
				}
			});
		}

			$(this.element).bind('focus', function(){
//				if(this.value == options.initstr){
					this.value = '';
//				}
			});
		
	},

	_init: function() {
		// JQuery UI 1.6rc6 compatibility
		this.init.apply(this, arguments);
	},

	cleanup: function() {
		// Cleanup and destroy are split into two separate handlers because
		// one of them (cleanup, in this case) needs to be bound to the
		// 'remove' event handler to clean up the extra elements.  The
		// destroy handler removes the custom input element added by this
		// plugin, and so we get an infinite loop if they aren't split.
		if(this.boundKeyHandler) {
			$(document).unbind('keyup', this.boundKeyHandler);
		}
		this.arrowElem.remove();
		this.listElem.remove();
	},

	/**
	 * Remove all combobox functionality from this element, restoring the
	 * original element.
	 */
	destroy: function() {
		var newElem = this.element;
		this.element = this.oldElem.insertBefore(this.arrowElem);
		newElem.remove();	// Triggers cleanup
	},

	/**
	 * Dynamically changes one of the combobox options.
	 * 
	 * @param {String} key Option name.
	 * @param {Object} value New value.
	 */
	setData: function(key, value) {
		this.options[key] = value;

		if(key == 'disabled' && this.isListVisible()) {
			this.hideList();
		}

		if(key == 'data' || key == 'listContainerTag' || key == 'listHTML') {
			var isVisible = this.isListVisible();
			this.listElem = this.buildList().replaceAll(this.listElem);
			this[isVisible ? 'showList' : 'hideList']();
		}
	},

	buildList: function() {
		var that = this;
		var options = this.options;
		var tag = options.listContainerTag;
		var elem = $('<' + tag + ' class = "ui-combobox-list">' + '</' + tag + '>');

		$.each(options.data, function(i, val) {
			$(options.listHTML(val, i))
				.appendTo(elem)
				.click(boundCallback(that, 'finishSelection', i))
				.mouseover(boundCallback(that, 'changeSelection', i));
		});

		return elem;
	},

	isListVisible: function() {
		return this.listElem.is(':visible');
	},

	/**
	 * Programmatically shows the drop-down list.
	 * 
	 * @param {Event} e Original event triggering this.
	 */
	showList: function(e) {
		if(this.options.disabled) {
			return;
		}

		var styles = this.element.position();
		// TODO: account for borders/margins.  Hardcode as '5' for now
		styles.top += this.element.height() + 5;

		styles.width = this.element.width() + 22;
		styles.position = 'absolute';
		styles.marginLeft = this.element.css('margin-left');

		this.boundKeyHandler = boundCallback(this, 'keyHandler');
		$(document).keyup(this.boundKeyHandler);
		$('.ui-combobox-list').hide();
		this.listElem.css(styles).show();
		this.changeSelection(this.findSelection(), e);
	},

	/**
	 * Programmatically hide the drop-down list.
	 */
	hideList: function() {
		this.listElem.hide();
		$(document).unbind('keyup', this.boundKeyHandler);
		this.listElem.children().show();
	},

	keyHandler: function(e) {
		if(this.options.disabled) {
			return;
		}

		var optionLength = this.options.data.length;
		switch(e.which) {
			case KEY_ESC:
				this.hideList(); 
				break;
			case KEY_UP:
				// JavaScript modulus apparently doesn't handle negatives
				var newIndex = this.selectedIndex - 1;
				if(newIndex < 0) {
					newIndex = optionLength - 1;
				}
				this.changeSelection(newIndex, e);
				return true;
				break;
			case KEY_DOWN:
				this.changeSelection((this.selectedIndex + 1) % optionLength, e);
				return true;
				break;
			case KEY_ENTER:
				this.finishSelection(this.selectedIndex, e);
				break;
			default:
				this.fireEvent('key', e);
				this.changeSelection(this.findSelection());
				if (this.options.hideElse) {
					this.hideElse();
				}
				break;
		}
	},

	prepareCallbackObj: function(val) {
		val = val || this.element.val();
		var index = $.inArray(val, this.options.data);
		return {
			value: val,
			index: index,
			isCustom: index == -1,
			inputElement: this.element,
			listElement: this.listElement
		};
	},

	fireEvent: function(eventName, e, val) {
		this.element.triggerHandler('combobox' + eventName, [
			e,
			this.prepareCallbackObj(val)
		], this.options[eventName]);
	},

	findSelection: function() {
		var data = this.options.data;
		var typed = this.element.val().toLowerCase();

		for(var i = 0, len = data.length; i < len; ++i) {
			var index = data[i].toLowerCase().indexOf(typed);
			if(index == 0) {
				return i;
			}
		};

		if(this.options.matchMiddle) {
			for(var i = 0, len = data.length; i < len; ++i) {
				var index = data[i].toLowerCase().indexOf(typed);
				if(index != -1) {
					return i;
				}
			};
		}
		if (this.options.letType) {
			return -1
		}
		return 0;
	},

	hideElse: function() {
		var data = this.options.data;
		var typed = this.element.val().toLowerCase();

		for(var i = 0, len = data.length; i < len; ++i) {
			var index = data[i].toLowerCase().indexOf(typed);
			if(index != 0) {
				this.listElem.children(':eq(' + i + ')').hide();
			} else {
				this.listElem.children(':eq(' + i + ')').show();
			}
		};

		return 0;
	},

	changeSelection: function(index, e) {

		this.selectedIndex = index;
		this.listElem.children('.selected').removeClass('selected');
		this.listElem.children(':eq(' + index + ')').addClass('selected');
		if(e) {
			this.fireEvent('change', e, this.options.data[index]);
		}
	},

	finishSelection: function(index, e) {
		this.element.val(this.options.data[index]);
		
		var cl = [];
		cl = $(this.element)[0].className.split(' ');
		for(i=0;i<cl.length;i++){
			if(cl[i].indexOf('value')!=-1)
				$(this.element).removeClass(cl[i]);
		}
		
		$(this.element).addClass('value' + index);
		this.hideList();
		this.fireEvent('select', e);

		$(this.element).trigger('comboChanged', index);
	}

});

$.extend($.ui.combobox, {
	getter: 'getData',
	version: '1.0.6',
	defaults: {
		data: [],
		autoShow: true,
		matchMiddle: true,
		change: function(e, ui) {},
		select: function(e, ui) {},
		key: function(e, ui) {},
		arrowURL: 'drop_down.png',
		arrowHTML: function() {
			return $('<img class = "ui-combobox-arrow" border = "0" src = "' 
				+ this.options.arrowURL + '" width = "18" height = "22" />')
		},
		listContainerTag: 'span',
		listHTML: defaultListHTML
	}
});

// Hack for chainability - since the combobox modifies this.element but 'this'
// is only the UI instance, it leaves the JQuery collection itself pointing
// at stale, removed-from-DOM instances.  This hack invokes the UI-factory 
// plugin method first, then maps each instance in the JQuery collection to 
// the new element.
var oldPlugin = $.fn.combobox;
$.fn.combobox = function() {
	var results = oldPlugin.apply(this, arguments);
	if(!(results instanceof $)) {
		return results;
	}

	var needsHack = false;
	var newResults = $($.map(results, function(dom) {
		var instance = $.data(dom, 'combobox');
		if(instance && instance.element[0] != dom) {
			needsHack = true;
			var newDOM = instance.element[0];
			$.data(newDOM, 'combobox', instance);
			return newDOM;
		} else {
			return dom;
		}
	}));

	return !needsHack ? results : newResults
		.bind('setData.combobox', function(e, key, value) {
			return $.data(this, 'combobox').setData(key, value);
		})
		.bind('getData.combobox', function(e, key) {
			return $.data(this, 'combobox').getData(key);
		})
		.bind('remove', function() {
			return $.data(this, 'combobox').cleanup();
		});
};

function defaultListHTML(data, i) {
	var cls = i % 2 ? 'odd' : 'even';
	return '<span class = "ui-combobox-item ' + cls + '">' + data + '</span>';
};

function boundCallback(that, methodName) {
	var extraArgs = [].slice.call(arguments, 2);
	return function() {
		that[methodName].apply(that, extraArgs.concat([].slice.call(arguments)));
	};
};

function fillDataFromSelect(options, element) {
	var optionMap = {}, computedData = [];
	element.children().each(function(i) {
		if(this.tagName.toLowerCase() == 'option') {
			var text = $(this).text(),
				val = this.getAttribute('value') || text;
			optionMap[val] = text;
			computedData.push(val);
		}
	});

	if(!options.data.length) {
		options.data = computedData;
	}

	if(options.listHTML == defaultListHTML) {
		options.listHTML = function(data, i) {
			return defaultListHTML(optionMap[data] || data);
		};
	}
};

})(jQuery);

function getValue(obj){
	var cl = [];
	cl = obj.className.split(' ');
	for (i = 0; i < cl.length; i++) {
		if (cl[i].indexOf('value') != -1) 
			return(1*cl[i].substr(5, cl[i].length));
	}
}
