/*
 * Copyright (c) 2010 RAYNET s.r.o., All rights reserved.
 * RAYNET s.r.o. PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * www.raynet.cz
 */

SP.apply("SP.forms", {
	/**
	 * @class SP.forms.Combobox
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100903
	 * @require jQuery
	 */
	Combobox: function(id, opts){
		// init
	  var el = jQuery("#"+id);
		opts = SP.applyIf(opts, {});
		if (el.length == 0 || !SP.isArray(opts.values) || opts.values.length == 0) return false;
		var OPTION_CLASS = "x-combobox-option";
		var ACTIVE_CLASS = "x-combobox-option-active";
		
		// effects
		var toggleMenu = opts.toggleMenu || function(main, menu, visible){
			if (!SP.isBoolean(visible)) { // toggle
				visible = !main.hasClass('x-menu-visible');
			}
			if (visible) {
				main.addClass('x-menu-visible');
			} else {
				main.removeClass('x-menu-visible');
			}
		};
		
		// collect values
		var valueNames = {};
		var values = opts.values;
		SP.each(values, function(v){
			valueNames[v[0]] = v[1];
		});
		var currentVal = SP.isEmpty(opts.value) ? opts.values[0][0] : opts.value;
		
		// create DOM
		el.addClass("x-field").addClass("x-combobox");
		var hiddenEl = null;
		if (SP.isString(opts.name)) {
			hiddenEl = el.append('<input type="hidden" value="'+currentVal+'" name="'+opts.name+'" />').find('input');
		}
		var btnEl = el.append('<div class="x-combobox-l">'+
														'<div class="x-combobox-r">'+
															'<div class="x-combobox-c">'+
																'<div class="x-combobox-value"></div>'+
														  '</div>'+
														 '</div>'+
													'</div>').find('.x-combobox-l');
		var valueEl = btnEl.find('.x-combobox-value')												
									.text(valueNames[currentVal])
									.after('<div class="x-combobox-arrow"></div>');
		var valuesEl = el.append('<ul class="x-combobox-options"></ul>').find('.x-combobox-options');
		SP.each(values, function(v){
			valuesEl.append('<li rel="'+v[0]+'" class="'+OPTION_CLASS+'">'+v[1]+'</li>');
		});
		
		// update value
		var setValue = function(key) {
			currentVal = key;
			if (hiddenEl) {
				hiddenEl.val(currentVal);
			}
			valueEl.text(valueNames[currentVal]);
			
			// callback
			if (SP.isFunction(opts.change)) {
				opts.change(currentVal, valueNames[currentVal]);
			}
		};
	
		// events
		$('body').mousedown(function(e){
			// click everywhere but combobox
			if (!SP.events.isTarget(e, el)) {
				toggleMenu(el, valuesEl, false);
			}
		});
	
		$('body').mouseup(function(e){
			// click on button
			if (SP.events.isTarget(e, btnEl) && SP.events.isLeft(e)) {
				toggleMenu(el, valuesEl);
			}
			
			// click on value
			if (SP.events.isTarget(e, valuesEl) && SP.events.isLeft(e)) {
				toggleMenu(el, valuesEl, false);
	
				var valueEl = SP.events.getParent(e, '.'+OPTION_CLASS);
				if (valueEl.length == 1) {
					setValue(valueEl.attr('rel'));
				}
			}
		});
		
		valuesEl.find('.'+OPTION_CLASS).hover(function(){
			$(this).addClass(ACTIVE_CLASS);
		}, function(){
			$(this).removeClass(ACTIVE_CLASS);
		})
		
		return el;
	},

	/**
	 * @class SP.forms.AnimatedCombobox
	 * @extends SP.forms.Combobox
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100903
	 * @require jQuery
	 */
	AnimatedCombobox: function(id, opts){
		opts = SP.apply(opts, {
			toggleMenu: function(main, menu, visible) {
				if (!SP.isBoolean(visible)) { // toggle
					visible = !main.hasClass('x-menu-visible');
				}
				if (visible) {
					menu.slideDown('fast');
					main.addClass('x-menu-visible');
				} else {
					menu.slideUp('fast');
					main.removeClass('x-menu-visible');
				}
			}
		});

		return this.Combobox(id, opts);
	},

	/**
	 * @class SP.forms.Button
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100904
	 * @require jQuery
	 */
	Button: function(id, opts){
		// init
		opts = opts || {};
		var el = $("#"+id);
		var MENU_ITEM_CLASS = "x-menu-item";
		var ACTIVE_CLASS = "x-menu-item-active";
		var hasMenu = SP.isArray(opts.menu) && opts.menu.length > 0;
		
		
		// create dom
		el.addClass("x-field").addClass("x-button");
		if(!SP.isBlank(opts.title)) el.attr('title', opts.title);
		var btn = el.append('<div class="x-button-l">'+
								'<div class="x-button-r">'+
									'<div class="x-button-c">'+
										((SP.isBlank(opts.name) && SP.isBlank(opts.type)) ? 
											'<div class="x-button-text">'+(opts.text||"")+'</div>' : 
											'<input class="x-button-text"'+
												' type="'+(opts.type||"submit")+'"'+
												(SP.isBlank(opts.name)?'':' name="'+opts.name+'"')+
											' value="'+(opts.text||"")+'" />'
										)+
									'</div>'+
								'</div>'+
							'</div>').find('.x-button-l');
		if (hasMenu) {
			var menu = el.append('<ul class="x-button-menu"></ul>').find('.x-button-menu');
			SP.each(opts.menu, function(m){
				menu.append('<li rel="'+m[0]+'" class="'+MENU_ITEM_CLASS+' '+MENU_ITEM_CLASS+'-'+m[0]+'">'+m[1]+'</li>');
			});
		}

		// show/hide menu
		var toggleMenu = opts.toggleMenu || function(main, menu, visible){
			if (!SP.isBoolean(visible)) { // toggle
				visible = !main.hasClass('x-menu-visible');
			}
			if (visible) {
				main.addClass('x-menu-visible');
			} else {
				main.removeClass('x-menu-visible');
			}
		};
	
		// events
		$('body').mousedown(function(e){
			// klik na tlacitko
			if (SP.events.isTarget(e, btn) && SP.events.isLeft(e)) {
				el.addClass('x-button-pressed');
	
			// klik kdekoliv mimo tlacitko
			} else if (hasMenu && !SP.events.isTarget(e, menu)) {
					toggleMenu(el, menu, false);
			}
		});
	
		$('body').mouseup(function(e){
			el.removeClass('x-button-pressed');
	
			// klik na tlacitko
			if (SP.events.isTarget(e, btn) && SP.events.isLeft(e)) {
				if (hasMenu) {
					toggleMenu(el, menu);
					return false;
				}
				if (SP.isFunction(opts.click)) {
					return opts.click(e);
				}
			}
	
			// klik na menu
			if (hasMenu && SP.events.isTarget(e, menu) && SP.events.isLeft(e)) {
				if (SP.isFunction(opts.menuClick)) {
					var valueEl = SP.events.getParent(e, '.'+MENU_ITEM_CLASS);
					if (valueEl.length == 1) {
						opts.menuClick(valueEl.attr('rel'), valueEl);
					}
				}
				toggleMenu(el, menu, false);
			}
		});
		
		if (hasMenu) {
			menu.find('.'+MENU_ITEM_CLASS).hover(function(){
				$(this).addClass(ACTIVE_CLASS);
			}, function(){
				$(this).removeClass(ACTIVE_CLASS);
			});
		}
		
		return el;
	},

	/**
	 * @class SP.forms.AnimatedButton
	 * @extends SP.forms.Button
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100903
	 * @require jQuery
	 */
	AnimatedButton: function(id, opts){
		opts = SP.apply(opts, {
			toggleMenu: function(main, menu, visible) {
				if (!SP.isBoolean(visible)) { // toggle
					visible = !main.hasClass('x-menu-visible');
				}
				if (visible) {
					menu.slideDown('fast');
					main.addClass('x-menu-visible');
				} else {
					menu.slideUp('fast');
					main.removeClass('x-menu-visible');
				}
			}
		});

		return this.Button(id, opts);
	},

	/**
	 * @class SP.forms.Slider
	 * @namespace SP.forms
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100903
	 * @require jQuery, jQueryUI.Slider
	 */
	Slider: function(id, opts) {
		opts = SP.applyIf(opts, {
			range: true,
			min: 0,
			max: 100,
			step: 1
		});
		SP.applyIf(opts, {
			values: [opts.min, opts.max]
		});
	
		var slider = $("#"+id).slider(opts);
		if (SP.isFunction(opts.init)) {
			opts.init(slider, opts.values);
		}
		
		return slider;
	},

	/**
	 * @class SP.forms.PriceSlider
	 * @extends SP.forms.Slider
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100903
	 * @require jQuery, jQueryUI.Slider
	 */
	PriceSlider: function(id, opts) {
		opts = SP.applyIf(opts, {
				values: [opts.from, opts.to],
				slide: function(event, ui) {
					$(opts.status).text(ui.values[0] + opts.currency + " - " + ui.values[1] + opts.currency);
				},
				init: function(slider, values) { 
					$(opts.status).text(values[0] + opts.currency + " - " + values[1] + opts.currency);
				}
		});
		return this.Slider(id, opts);
	},

	/**
	 * @class SP.forms.QuickSearch
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100906
	 * @require jQuery
	 */
	QuickSearch: function(id, opts) {
		// init
		opts = SP.applyIf(opts, {
			url: null,
			button: false,
			minLength: 3,
			queryString: "query",
			queryOnType: true,
			allResultsUrl: null,
			allResultsOnEnter: false,
			allResultsOnButtonClick: false
		});
		var input = $("#"+id);
		
		if (SP.isEmpty(opts.url)) return;
		
		// create DOM
		input.addClass("x-quick-search-input");
		var results = input.after('<div class="x-quick-search-results"></div>').next()
									.hide();

		// validate fn
		var currentSearch = "";
		var redirecting = false; // for all results
		var validateQuery = function(){
			// zacneme vyhledavat pouze pokud je napsan minimalni pocet znaku
			// a text se opravdu zmenil
			if (!SP.isBlank(input.attr("switching")) && input.val() == input.attr("switching")) {
				results.hide();
				return false;
			}
			if (input.val().length < opts.minLength) {
				results.hide();
				return false;
			}
			return true;
		}

		// search fn
		var doSearch = function(force){
			if (redirecting === true) return false;
			if (validateQuery() == false) return false;

			if (force !== true && currentSearch == input.val()) {
				return;
			}
			
			currentSearch = input.val();

			var requestQueryValue = currentSearch;
			var params = {};
			params[opts.queryString] = currentSearch;
			$.get(opts.url, params, function(html){
				// pokud mezitim nez se stihl vratit vysledek ze serveru
				// uzivatel napsal jiny text do policka, vysledky zahodime
				if (requestQueryValue == currentSearch){
					results.show();
					results.html(html)
				}
			});
		}
		
		var allResults = function(){
			if (validateQuery()) {
				redirecting = true;
				location.href = opts.allResultsUrl+input.val();
			}
		}
		
		// create button
		if (opts.button) {
			var btnId = SP.genId();
			input.after('<div id="'+btnId+'" class="x-quick-search-button"></div>');
			var button = SP.forms.Button(btnId, {
				click: function(){
					if (opts.allResultsOnButtonClick == true && !SP.isBlank(opts.allResultsUrl)) {
						allResults();
					} else {
						doSearch(true); // vynutime vyhledavani, i kdyz je zadan stejny text
					}
				},
				title: opts.buttonTitle
			});
			if (SP.isString(opts.button)) {
				button.addClass(opts.button);
			}
		}

		// pridame udalosti
		if (opts.queryOnType === true) {
			input.keyup(doSearch);
		}
		
		if (opts.allResultsOnEnter === true) {
			input.keydown(function(e){
				if (e.which == 13){
					allResults();
				}
			});
		}
		
		// tlacitko pro zavreni vysledku
		if (!SP.isBlank(opts.close)) {
			$(results.getSelector() + " " + opts.close).live('click', function(){
				results.hide();
				return false;
			});
		}
	},
	
	
	/**
	 * @class SP.forms.SwitchingField
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100906
	 * @require jQuery
	 */
	SwitchingField: function(id, opts) {
		var input = $("#"+id);
		opts = SP.applyIf(opts, {
			label: "",
			defaultValue: "",
			value: ""
		});

		input.attr("switching", opts.label);
		input.val(SP.isBlank(opts.value) ? opts.label : opts.value);

		// udalosti
		input.focus(function(){
			if (input.val() == opts.label) {
				input.val(opts.defaultValue);
			}
		});
		input.blur(function(){
			if (input.val() == opts.defaultValue || SP.isBlank(input.val())) {
				input.val(opts.label);
			}
		});
	},
	
	/**
	 * @method SP.forms.submit
	 * odesle formular pomoci ajaxu
	 * @namespace SP.forms
	 * @author Miroslav Raska
	 * @version 20100907
	 * @require jQuery
	 */
	submit: function(selector, callback) {
		var form = $(selector);
		$.post(form.attr("action"), form.serialize(), callback);
	}
});
