
/*
 * Plugins
 */
(function($) {
	
	$.fn.extend({
			
		/*
		 * placeholder plugin by Maarten Wierda, minus3 <http://minus3.nl>
		 */
		m3Paceholder: function(options) {
			var defaults = {
				attr_placeholder: "placeholder", // attribute name
				class_placeholder: "placeholder" // class name
			};
			
			var options = $.extend(defaults, options);
		
			return this.each(function() {
				
				var element = $(this);
				var placeholder_value = element.attr(options.attr_placeholder);
				
				function clear() {
					
					element.removeClass(options.attr_placeholder);
					
					if (element.val() == placeholder_value)
						element.val("");
				}
				
				function display() {
						
					if ((element.val() == "") || (element.val() == placeholder_value))
						element.val(placeholder_value).addClass(options.attr_placeholder).removeClass("error");
				}
				
				display();
				
				element
					.change(clear)
					.focus(clear)
					.blur(display)
					.parents('form').submit(clear)
				;
			});
		},
		
		/* ------------------------------------------------
		 * @plugin		m3Toggle
		 * @created		May 19, 2010
		 * -----------------------------------------------*/
		/*
			toggles the panel element corresponding with the trigger element. by default,
			the panel element is the next element after the trigger, but it can also be
			the previous element or an element to be determined by a set selector.
		 */
		
		m3Toggle: function(options) {
			
			var defaults = {
				panelSelector: null,
				opened: false,
				ajax: null,
				openedSelector: "opened",
				closedSelector: "closed",
				direction: 'next',
				labelOpen: null,
				onOpen: function(){},
				onClose: function(){},
				onAfterOpen: function() {},
				onAfterClose: function() {}
			};

			var options = jQuery.extend(defaults, options);
			var self = this;
			
			return this.each(function() {
				
				var element = jQuery(this);
				
				/*
				 * select the panel we're gonna work with
				 */
				if (options.panelSelector !== null) {
					var panel = element.siblings(options.panelSelector);
				}
				else {
					if (options.direction === 'next') {
						var panel = element.next(options.panelSelector);
					}
					else if (options.direction === 'prev') {
						var panel = element.prev(options.panelSelector);
					}
				}
				
				//log(element)
				//log(panel)
				//log('---------------------');
				
				/*
				 * store some original values that we might need later
				 */
				var panelLabel = element.text(),
					panelOpacity = panel.css('opacity'),
					panelWidth = panel.width(),
					panelHeight = panel.height()
				;
				
				function markOpened() {
					element.removeClass(options.closedSelector).addClass(options.openedSelector);
					
					if (null !== typeof options.labelOpen) {
						element.text(options.labelOpen);
					}
				}
				
				function markClosed(){
					element.addClass(options.closedSelector).removeClass(options.openedSelector);
					
					if (null !== typeof options.labelOpen) {
						element.text(panelLabel);
					}
				}
				
				if (null !== options.ajax) {
					jQuery.ajax({
						type: 'GET',
						url: options.ajax,
						success: function(content) {
							panel.html(content);
							
							// panel content has been altered, store the new width and height value
							panelWidth = panel.width(),
							panelHeight = panel.height()
						}
					});
				}
				
				if (element.is(options.opened)) {
					markOpened();
					element.text(panelLabel);
				}
				else {
					panel.hide();
					markClosed();
				}
				
				//log('-----------');
				//log(element);
				//log(panel);
								
				element.click(function(e) {
					if (panel.is(":hidden")) {
						panel.show();
						options.onOpen.call(panel);
						
						/*
						 * inspect the visibility, width, height and opacity of the panel.
						 * if these properties all equal the original values,
						 * the panel is in its original state and is declared 'opened'
						 */
						var trackerOpen = setInterval(function() {
							if (panel.is(':visible') && panel.css('opacity') === panelOpacity && panel.width() == panelWidth && panel.height() && panelHeight) {
								clearInterval(trackerOpen);
								markOpened();
								options.onAfterOpen.call(panel);
							}
						}, 100);
					}
					else {
						panel.hide();
						options.onClose.call(panel);
						
						/*
						 * inspect the invisibility of the panel
						 */
						var trackerClose = setInterval(function() {
							if (panel.is(':hidden')) {
								clearInterval(trackerClose);
								markClosed();
								options.onAfterClose.call(panel);
							}
						}, 100);
					}
					return false;
				});
			});
		}
	});
})(jQuery);


(function( $ ){

	var priceSliderMethods = {
		
		priceBox: null,
		priceSlider: null,
		priceMinField: null,
		priceMaxField: null,
		
		init: function( options ) {
			
			var defaults = {
				onSlideStop: function() {}
			};
			
			var options = $.extend(defaults, options);
			
			return this.each(function() {
					
				$.fn.restoreLatestValidValue = function() {
					
					$(this).val( $(this).data('latestValidValue') !== undefined
						? $(this).data('latestValidValue')
						: $(this).attr('defaultValue')
					);
				}
				
				function onlyNumeric() {
					
					var replacedValue = $(this).val().replace(/[^0-9\.]/g,'');
					
					if (replacedValue.length) {
						$(this).val(replacedValue);
					}
					else {
						$(this).restoreLatestValidValue();
					}
				}

				priceSliderMethods.priceBox = $(this);
				priceSliderMethods.priceSlider = priceSliderMethods.priceBox.find(".price_slider");
				priceSliderMethods.priceMinField = priceSliderMethods.priceBox.find("input[name='price_min']");
				priceSliderMethods.priceMaxField = priceSliderMethods.priceBox.find("input[name='price_max']");
				
				priceSliderMethods.priceSlider.slider({
					range	: true,
					min		: parseInt(priceSliderMethods.priceMinField.val()),
					max		: parseInt(priceSliderMethods.priceMaxField.val()),
					values	: [parseInt(priceSliderMethods.priceMinField.val()), parseInt(priceSliderMethods.priceMaxField.val())],
					step	: 50,
					animate	: true,
					slide: function(event, ui) {
						
						$(this).parents(".filter.price").find("input[name='price_min']").val(ui.values[0]);
						$(this).parents(".filter.price").find("input[name='price_max']").val(ui.values[1]);
					}
				});
				
				/*
				 * replace all non-numeric values with a space
				 */
				priceSliderMethods.priceMinField.keyup(onlyNumeric);
				priceSliderMethods.priceMaxField.keyup(onlyNumeric);
				
				/*
				 * make sure the minimum price is less than the current maximum price and more or equal than the minimum required value
				 */
				priceSliderMethods.priceMinField.change(function(e) {
						
					var priceMinValue = parseInt($(this).val());
					
					if ( priceMinValue < parseInt(priceSliderMethods.priceMaxField.val()) && priceMinValue >= parseInt(priceSliderMethods.priceSlider.slider("option", "min"))) {
						
						$(this).data('latestValidValue', priceMinValue);
						priceSliderMethods.priceSlider.slider("values", 0, priceMinValue);
					}
					else {
						$(this).restoreLatestValidValue();
					}
				});
				
				/*
				 * make sure the maximum price is bigger than the current minimum price and less or equal than the maximum required value
				 * if the entered value is bigger than the maximum required value (e.g. 1100 -- where 1000 is allowed), use the maximum required value
				 */
				priceSliderMethods.priceMaxField.change(function() {
					
					var priceMaxValue = parseInt($(this).val());
					
					if ( priceMaxValue > parseInt(priceSliderMethods.priceMinField.val())) {
						
						// the entered value is bigger than the maximum permitted value
						if (priceMaxValue > parseInt(priceSliderMethods.priceSlider.slider("option", "max"))) {
							
							// assign the maximum value to the priceMaxValue variable
							priceMaxValue = parseInt(priceSliderMethods.priceSlider.slider("option", "max"));
							
							$(this).val(priceMaxValue);
						}
						
						$(this).data('latestValidValue', priceMaxValue);
						priceSliderMethods.priceSlider.slider("values", 1, priceMaxValue);
					}
					else {
						this.restoreLatestValidValue();
					}
				});
				
				priceSliderMethods.priceSlider.bind("slidestop", function(event, ui) {
					options.onSlideStop.call();
				});
			});
		},
		
		setMin: function(price) {
			$(this).find("input[name='price_min']").val(price).data('latestValidValue', price);
			$(this).find(".price_slider").slider("values", 0, price);
		},
		
		setMax: function(price) {
			$(this).find("input[name='price_max']").val(price).data('latestValidValue', price);
			$(this).find(".price_slider").slider("values", 1, price);
		}
		
	};
	
	$.fn.priceSlider = function( method ) {
		
		if ( priceSliderMethods[method] ) {
			
			return priceSliderMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		}
		else if ( typeof method === 'object' || ! method ) {
			return priceSliderMethods.init.apply( this, arguments );
		}
		else {
			$.error( 'Method ' +	method + ' does not exist on jQuery.priceSlider' );
		}	
	};

})( jQuery );
