/**
 * jQuery extend
 */
$.extend({
	/**
	 * get param
	 * @param {String} url	The string to be parsed
	 * @param {Object} param	The param to be returned
	 */
	getParam: function(url,param){
		var map = {};
		var paramValue = null;
		var parts = url.toString().replace(/[?#&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
			map[key] = value;
			if( param == key ){
				paramValue = value;
			}
		});
		if( !param ){
			paramValue = map;
		}
		return paramValue; 
	},
	/**
	 * Modify serialized string
	 * @param {Object} url
	 * @param {Object} param
	 * @param {Object} newValue
	 */
	setParam: function(url,param,newValue){
		var str_newURL = '';
		if (url != undefined) {
			str_newURL = url.toString().split("?")[0] + "?";
			var separator = "";
			var parts = url.toString().replace(/[?#&]+([^=&]+)=([^&]*)/gi, function(m, key, value){
				str_newURL += separator + key + "=";
				str_newURL += (param == key) ? newValue : value;
				separator = "&";
			});
		}	
		return str_newURL; 
	}
});

var ef = {};

(function(ef, $) {
	ef.Settings = (function() {
		var EVENTS_SCOPE,
		//	constants
			NAMESPACE = '.ef',
			SERVICES = {
				addToFavorites: '/locales/favoritos/', //'data/add_to_favorites_error.json',
				placeDetail: '/locales/verlocal', //'data/popup.html',
				getAllPlaces: '/locales/mostrar?callback=?', //'/places.json',
				sections: '/secciones/' 
			},
			Events = {
				SEARCH_CHANGE: "searchChange",
				LOAD_COMPLETE: "loadComplete"
			};
		
		(function(){
			EVENTS_SCOPE = $(ef);
			init();
		})();
		
		function init() {
			loadPlaces();
			$(document).ready(function(){
				verifyAjaxNavigation();
			});
			
		    // Using manual call - dynamic url change
			if ($('#mycarousel').length) {
				$('#mycarousel').jcarousel();
			}	
			if ($(".eventos_inscripcion_form").length) {
				$(".eventos_inscripcion_form").find("input[type=checkbox]").unbind("click").bind("click", function(e) {
					$(this).closest("form").submit();
				});
			}
		}
		
		function loadPlaces() {
			EVENTS_SCOPE.unbind(NAMESPACE).bind(Events.LOAD_COMPLETE + NAMESPACE, places_loadedHandler);
		}
		
		function verifyAjaxNavigation() {
			var hash = window.location.hash;
			//	verify ID detail
			var id = $.getParam(hash,"id");
			if (id) {
				$.fancybox({
					type: "ajax",
					href: SERVICES.placeDetail + "/" + id,
					'autoDimensions': false,
					'width': 730,
					'height': 500,
					'scrolling': 'no'
				});
			}
			
			//	verify sections
			var sectionHash = $.getParam(hash,"seccion");
			//	cargar seccion
			if (sectionHash) {
				$.fancybox({
					type: "ajax",
					href: SERVICES.sections + sectionHash,
					'showCloseButton'	: true,
					'titlePosition' : 'inside'
				});
			}
		}
		
		function places_loadedHandler(e) {
			ef.PlacesList.init();
			EVENTS_SCOPE.unbind(NAMESPACE).bind(Events.SEARCH_CHANGE + NAMESPACE, function(e, value) {
				ef.PlacesModel.setKeyword(value);
				ef.PlacesList.filterList();
			});
		}
		
		function showPopup(url, params, fnComplete) {
			$.post(url, params, function(data){
				
				var overlay = $('<div />', {
					'id': 'popup',
					'class': 'overlay'
				}).css({
					opacity: 0.7
				});
				
				var modal = $('<div />', {
					'class': 'overlay_modal'
				});
				
				var overlayWrapper = $('<div />', {
					'id': 'overlay_wrapper'
				}).css({
					'position': 'fixed',
					top: "0px",
					left: "0px",
					margin: "auto",
					width: $(window).width(),
					height: $(window).height()
				}).appendTo("body");	
				
				$(window).resize(resizeOverlay);
				
				overlay.unbind("click").bind("click", function(e){
					overlayWrapper.remove();
				});
				
				
				overlay.appendTo(overlayWrapper).fadeIn("slow", function(){
					modal.appendTo(overlayWrapper).show();
					$(data).appendTo(modal);	
					modal
						.css({
							left:  $(window).width()*.5 - modal.width()*.5,
							top: $(window).height()*.5 - modal.height()*.5
						})
						.find("a[rel=close]").unbind("click").bind("click",function(e){
							e.preventDefault();
							overlayWrapper.remove();
						});
						
					if (typeof fnComplete == "function") {
						alert("fsadf");
					}
				});
			});
			
			function resizeOverlay() {
				var modal = $(".overlay_modal");
				
				$(".overlay").css({
					width: $(window).width(),
					height: $(window).height()
				});
				
				modal.css({
					left:  $(window).width()*.5 - modal.width()*.5,
					top: $(window).height()*.5 - modal.height()*.5
				});
			}
		}
		return {
			showPopup: showPopup,
			SERVICES: SERVICES,
			EVENTS_SCOPE: EVENTS_SCOPE,
			NAMESPACE: NAMESPACE,
			Events: Events
		}
	})();
	
	/**
	 * Places Model: Retrieves places data from server
	 */
	ef.PlacesModel = (function(){
		var _data = [],
			_filteredData = [],
			_categories = [],
			_keyword = '',
			_fields = ["name","location", "tags"],
			_currentFilter = '',
			_currentOrder = '',
			_orderDirection = true,
		// constants
			FILTER_TYPE = {
				ALL: 'all',
				PROMO: 'promo',
				FAVORITE: 'favorite'
			},
			ORDER_TYPE = {
				CATEGORY: 'category',
				NAME: 'name',
				LOCATION: 'location'
			};
			
		/**
		 *	@constructor
		 */
		(function(){
			var jqxhr = $.getJSON(ef.Settings.SERVICES.getAllPlaces, function(data) {
			    _data = data.places;
			    _filteredData = _data;
			    _categories = data.categories;
			    ef.Settings.EVENTS_SCOPE.trigger(ef.Settings.Events.LOAD_COMPLETE + ef.Settings.NAMESPACE);
			  })
			  .error(function(jqXHR, textStatus, errorThrown) { window.console && console.log("error: ", jqXHR, textStatus, errorThrown); })
			  .complete(function() { /*complete*/ });
			//	set current filter as 'category'  
			setFilter(FILTER_TYPE.ALL);
			setOrder(ORDER_TYPE.CATEGORY);
		}());
		
		function setFilter(value) {
			if (_currentFilter != value) {
				_currentFilter = value;
			}
		}
		
		function getFilter() {
			return _currentFilter;
		}
		
		/**
		 * set order field (category-all, name, location)
		 */
		function setOrder(value) {
			if (_currentOrder != value) {
				if (value == ORDER_TYPE.CATEGORY) {
					_currentOrder = '';
				} else {
					_currentOrder = value;
					_orderDirection = true;
				}
			} else {
				_orderDirection = !_orderDirection;
			}
			
		}
		
		function getOrder() {
			return _currentOrder;
		}
		
		function setKeyword(value) {
			_keyword = value;
		}
		
		
		function execute() {
			var proccesedData;
			window.console && console.log("----------  execute query ---------- ", _currentFilter, _currentOrder, _keyword);
			
			if (_keyword != '') {
				setFilterByKeyword();
			} else {
				_filteredData = _data;
			}
			//	filter applied
			if (_currentFilter != "") {
				//	get all places (category->places || all places)
				if (_currentFilter == FILTER_TYPE.ALL) {
					proccesedData = (_currentOrder == "") ? filterByCategory() : _filteredData;
				//	filter by promo, favorite	
				} else {
					proccesedData = filterItemsByVal(_currentFilter, 1);
				}
			//	get all places
			} else {
				proccesedData = _data;
			}
			//	order applied
			if (_currentOrder != "") {
				proccesedData = sortFilteredItems(proccesedData);
			}
		
			return proccesedData; 
		}
		
		function setFilterByKeyword() {
			var regExp = new RegExp(_keyword, 'gi');
			var j;
			var isValidField = false;
			var fieldsLength = _fields.length;
			//	filter using default fields
			_filteredData = _data.filter(function(item, index, array) {
				//	filter by keyword and array of fields
				j = fieldsLength;
				isValidField = false;
				while (j--) {
					if (regExp.test(item[_fields[j]])) {
						isValidField = true;
						continue;
					}
				}
				return isValidField;
			});
		}
		
		function filterByCategory() {
			var total = _categories.length, i=0;
			var allData = [], currentCategory;
			var regExp = new RegExp(_keyword, 'gi');
			while (i < total) {
				currentCategory = _filteredData.filter(function(item, index, array){
						return (_categories[i].id === item.category);
				});
				if (currentCategory.length) {
					allData.push({"name":_categories[i].name, "places": currentCategory});
				}
				i++;
			}
			
			return allData;
		}
		
		function getItemByKey(key, value) {
			return _data.filter(function(item, index, array){
				return value == item[key];
			})[0];
		}
		
		/**
		 *	order data by current filter (e.g name, location) 
		 */	
		function sortFilteredItems(items) {
			return items.sort(function(a, b){
				//	ascending
				if (a[_currentOrder] < b[_currentOrder]) {
					return (_orderDirection) ? -1 : 1;
				//	descending
				} else if (a[_currentOrder] > b[_currentOrder]) {
					return (_orderDirection) ? 1 : -1;
				}
				return 0;
			});
		}
		
		/**
		 *	filter data by key (e.g promo, favorites) 
		 */
		 function filterItemsByVal(key, value) {
			return _filteredData.filter(function(item, index, array) {
				return value === item[key];
			});
		}
		
		return {
			getItemByKey: getItemByKey,
			setKeyword: setKeyword,
			getFilter: getFilter,
			setFilter: setFilter,
			setOrder: setOrder,
			getOrder: getOrder,
			execute: execute,
			FILTER_TYPE: FILTER_TYPE,
			ORDER_TYPE: ORDER_TYPE
		};
	})();
	
	ef.Autocomplete = (function(module, context, options){
		//	private properties
		var el = $(context),
			searchInput,
			SETTINGS = {
				inputClass: "#search"
			};
		//	constants
		var LABELS = {
				search: "Buscar en GE"
			};
		/**
		 * @constructor
		 */
		(function(){
			SETTINGS = options || SETTINGS;
			
			init();
		})();
		
		//	private methods
		function init() {
			//	search text
			searchInput = el.find(SETTINGS.inputClass).val(LABELS.search);
			searchInput.unbind("keyup").bind("keyup", searchInput_keyupHandler);
			searchInput.unbind("focusin").bind("focusin", searchInput_focusinHandler);
			searchInput.unbind("focusout").bind("focusout", searchInput_focusoutHandler);
		}
		//	public methods
		
		//	event handlers
		function searchInput_keyupHandler(e) {
			var scope = $(this).val();
			if (scope != LABELS.search) {
				ef.Settings.EVENTS_SCOPE.trigger(ef.Settings.Events.SEARCH_CHANGE + ef.Settings.NAMESPACE, [scope]);
			}
		}
		
		function searchInput_focusinHandler(e) {
			var scope = $(this), 
				val = scope.val();
				
			if (val == LABELS.search) {
				scope.val("");
			}
		}
		
		
		function searchInput_focusoutHandler(e) {
			var scope = $(this), 
				val = scope.val();
				
			if (val == "") {
				scope.val(LABELS.search);
			}
		}
	})(ef.Autocomplete || {}, "#search_container");
	
	/**
	 * @class Places list finder
	 */
	ef.PlacesList = (function(module, context, options){
		//	private properties
		var element = $(context),
			categoriesContainer,
			placesTooltip,
			categoryItem,
			orderType,
			listType,
			EVENTS_SCOPE = $(ef),
			SETTINGS = {
				categoryContainer: "#places_elements",
				categoryItem: ".places_category",
				placesTooltip: '.places_tooltip',
				orderType: '#filter_type',
				listType: '#places_mainnav',
				navSelected: 'nav_selected'
			},
			TEMPLATES = {
				CATEGORY: {
					content: '<div class="places_category">'+
	        			'<h3>{name}</h3>'+
	        			'<ul>'+
	        			'{placesList}'+
	        			'</ul>'+
	        			'<hr />'+
	        		'</div>',
	        		item: '<li id="placeItem{id}" class="{newTag}"><a href="#id={id}" rel"fancybox">{name}{promoTag}{favoriteTag}{newSede}</a></li>'
	        		},
	        	PLACES: {
					content: '<div class="places_category">'+
	        			'<ul>'+
	        			'{placesList}'+
	        			'</ul>'+
	        		'</div>',
	        		item: '<li class="{newTag}"><a href="#id={id}" rel"fancybox">{name}{favoriteTag}{promoTag}{newSede}</a></li>'
	        	},
	        	PROMO_TAG: '<span class="place_promo">promo</span>',
	        	FAVORITE_TAG: '<span class="place_favorite">fav</span>',
	        	NEW_SEDE: '<span class="place_sede2">sede</span>',
	        	NEW_TAG: 'place_update',
	        	TOOLTIP: '<div class="ef_tooltip"><p>{message}</p></div>'     	
	      	};
	      	
	      	//	constants
			var LABELS = {
					notfound: "<p>No se encontraron resultados</p>"
				},
				LIST_TYPE = {
					category: {
						key: 'all',
						title: 'ver todos'
						},
					favorite: {
						key: 'favorite',
						title: 'ver favoritos'
						},
					promotion: {
						key: 'promo',
						title: 'ver promociones'
					}
				};
		
		/**
		 * @constructor
		 */
		(function(){
			SETTINGS = options || SETTINGS;
			
			categoriesContainer = element.find(SETTINGS.categoryContainer);
			orderType = element.find(SETTINGS.orderType);
			listType = element.find(SETTINGS.listType);
			categoryItem = element.find(SETTINGS.categoryItem);
			placesTooltip = element.find(SETTINGS.placesTooltip);
		})();
		
		//	private methods
		function init() {
			element.addClass("visible").find(".main_preloader").remove();
			setFilters();
			filterList();
		}
		
		function setFilters() {
			orderType.find("a").unbind("click").bind("click", orderType_clickHandler);
			listType.find("a").unbind("click").bind("click", listType_clickHandler);
			listType.find("a").unbind("mouseover").bind("mouseover", listType_mouseoverHandler);
			listType.find("a").unbind("mouseout").bind("mouseout", listType_mouseoutHandler);
		}
		var tempTitle = "";
		function listType_mouseoverHandler(e) {
			e.preventDefault();
			tempTitle = $(this).attr("title");
			$(this).attr("title", '');
			
			var coords = {
					top: $(this).offset().top-element.offset().top,
					left: $(this).offset().left-102-element.offset().left
			};
			addTooltip(tempTitle, coords);
		}
		
		function listType_mouseoutHandler(e) {
			$(this).attr("title", tempTitle);
			removeTooltip();
		}
		
		function addTooltip(message, coords) {
			var data = {};
			data.message = message;
			var tooltip = $(ef.TemplateEngine.parse(TEMPLATES.TOOLTIP, data)).appendTo(element).fadeIn("fast");
			tooltip.
				css(coords);
		}
		
		function removeTooltip(message) {
			element.find(".ef_tooltip").remove();
		}
		
		/**
		 * orden seleccionado (Categoria, nombre, local)
		 */
		function orderType_clickHandler(e) {
			e.preventDefault();
			//	add selected state
			orderType.find("a").removeClass(SETTINGS.navSelected);
			$(this).addClass(SETTINGS.navSelected);
			var orderLabel = $(this).attr("title");
			//	update order type
			ef.PlacesModel.setOrder(orderLabel);
			filterList();
		}
		
		/**x
		 * Tipo de lista seleccionada (todos, promociones)
		 */
		function listType_clickHandler(e) {
			e.preventDefault();
			var listTypeLabel = tempTitle;
			//	add selected state
			listType.find("a").removeClass("nav_selected");
			$(this).addClass("nav_selected");
			switch (listTypeLabel) {
				//	show all places
				case LIST_TYPE.category.title:
					// update Model
					ef.PlacesModel.setFilter(LIST_TYPE.category.key);
					ef.PlacesModel.setOrder(ef.PlacesModel.ORDER_TYPE.CATEGORY);
					// update UI
					filterList();
					orderType.find("a").removeClass(SETTINGS.navSelected);
					orderType.find(".btnFilterCategory").addClass(SETTINGS.navSelected).show();
					orderType.show();
				break;
				//	show favorites
				case LIST_TYPE.favorite.title:
					// update Model	
					ef.PlacesModel.setFilter(LIST_TYPE.favorite.key);
					ef.PlacesModel.setOrder(ef.PlacesModel.ORDER_TYPE.NAME);
					//	update UI (View)
					orderType.find("a").removeClass(SETTINGS.navSelected);
					orderType.find(".btnFilterName").addClass("nav_selected");
					orderType.find(".btnFilterCategory").hide();
					orderType.show();
					showByPlaces();
				break;
				//	show promotions
				case LIST_TYPE.promotion.title:
					ef.PlacesModel.setFilter(LIST_TYPE.promotion.key);
					showByPlaces();
					orderType.hide();
				break;
			}
		}
		
		//	public methods
		function filterList() {
			//	display categories -> places
			if (ef.PlacesModel.getFilter() == ef.PlacesModel.FILTER_TYPE.ALL && ef.PlacesModel.getOrder() == '') {
				showByCategory();
			//	display all places	
			} else {
				showByPlaces();
			}
		}
		
		function showByCategory() {
			var categories = ef.PlacesModel.execute();
			var itemsContent = '';
				
			if (categories.length) {
				var	placesList = '', 
					items;
					
				for (var i = 0; i < categories.length; i++) {
					itemsContent += ef.TemplateEngine.parse(TEMPLATES.CATEGORY.content, categories[i]);
					items = categories[i].places;
					
					placesList = '';
					for (var j = 0; j < items.length; j++) {
						//	replace promotion value with HTML star
						items[j].promoTag = (items[j].promo == 1) ? TEMPLATES.PROMO_TAG : '';
						items[j].favoriteTag = (items[j].favorite == 1) ? TEMPLATES.FAVORITE_TAG : '';
						items[j].newTag = (items[j]['new'] == 1) ? TEMPLATES.NEW_TAG : '';
						items[j].newSede = (items[j]['sede'] == 2) ? TEMPLATES.NEW_SEDE : '';
						//	add places items (<li>)
						placesList += ef.TemplateEngine.parse(TEMPLATES.CATEGORY.item, items[j]);
					}
					itemsContent = ef.TemplateEngine.replace(itemsContent, "placesList", placesList);
				
				}
			} else {
				itemsContent = LABELS.notfound;
			}
			
			categoriesContainer.html(itemsContent);
			
			setItems();
		}
	
		/**
		 *	order items (ordered by name and location)
		 */
		function showByPlaces() {
			
			var items = ef.PlacesModel.execute(),
				itemsContent = TEMPLATES.PLACES.content,
				placesList = '';
				
			if (items.length) {
				for (var i = 0; i < items.length; i++) {
					//	replace promotion value with HTML star
					items[i].promoTag = (items[i].promo == 1) ? TEMPLATES.PROMO_TAG : '';
					items[i].favoriteTag = (items[i].favorite == 1) ? TEMPLATES.FAVORITE_TAG : '';
					items[i].newTag = (items[i]['new'] == 1) ? TEMPLATES.NEW_TAG : '';
					items[i].newSede = (items[i]['sede'] == 2) ? TEMPLATES.NEW_SEDE : '';
					placesList += ef.TemplateEngine.parse(TEMPLATES.PLACES.item, items[i]);
				}
				
				itemsContent = ef.TemplateEngine.replace(itemsContent, "placesList", placesList);
			} else {
				itemsContent = LABELS.notfound;
			}
			
			categoriesContainer.html(itemsContent);
			
			setItems();
		}
		
		/**
		 * Set event listeners for each place item
		 */
		function setItems() {
			var navEnabled = false, placesEnabled = false;
			var target;
			var id;
			var place;
			
			//	mouse over
			categoriesContainer.find("li").unbind("mouseover").bind("mouseover",function(e) {
				target = $(this);
				id = $.getParam(target.find("a").attr("href"), "id");
				place = ef.PlacesModel.getItemByKey("id", id);
				
				if (place.favorite && place.favorite == 1) {
					placesTooltip.find(".btnAddToFavorites").hide();
				} else {
					placesTooltip.find(".btnAddToFavorites").show();
				}
				
				placesTooltip
					//	set location
					.find("span").text(place.location).end()
					//	set logo
					//.find("img").attr("href", place.logo)
					.find("img").attr("src", "/img/mini_logo/" + place.mini_logo).end()
					.css({
						"top": target.offset().top-4-element.offset().top
					});
				//	slide to left (show)
				if (!placesTooltip.is(":visible")) {
					placesTooltip
						.stop()
						.animate({
							"right": 200
						}, 200);
				}
				
				placesTooltip.show();
			});
			
			placesTooltip
				.unbind('mouseenter').bind('mouseenter',function(e) {
					navEnabled = true;
					target.addClass("place_hover");
				})
				.unbind('mouseleave').bind('mouseleave', function(e) {
					navEnabled = false;
					hideTooltip();
					target.removeClass("place_hover");
				})
				//	add to favorites click
				.find("a").unbind('click').bind('click', function(e) {
					e.preventDefault();
					var coords = {
						top: $(this).offset().top-4,
						right: 250
					};
					//	add to favorites
					ef.AddToFavorites.add(id, coords, function(data) {
						//	success
						element.find("#placeItem"+data).find("a").append(TEMPLATES.FAVORITE_TAG);
					});
					target.removeClass("place_hover");
					hideTooltip();
				});
			
			categoriesContainer.find("ul").unbind("mouseleave").bind("mouseleave",function(e) {
				setTimeout(function() {
					if (!navEnabled) {
						hideTooltip();
					}
				}, 1);
			});
			
			categoriesContainer.find("li a").unbind("click").bind("click", function(e) {
				var id = $.getParam($(this).attr("href"),"id");
				//ef.Settings.showPopup(ef.Settings.SERVICES.placeDetail, {'id': id});
				$.fancybox({
					type: "ajax",
					href: ef.Settings.SERVICES.placeDetail + "/" + id,
					'autoDimensions': false,
					'width': 730,
					'height': 500,
					'scrolling': 'no'
				});
			});
		}
		
		function hideTooltip() {
			//	slide to left (show)
			if (placesTooltip.is(":visible")) {
				placesTooltip
					.stop()
					.animate({
						"right": 100
					}, 200, function() {
						placesTooltip.hide();
					});
			} else {
				placesTooltip.hide();
			}
		}
		
		//	event handlers
		
		return {
			init: init,
			filterList: filterList
		};
	})(ef.PlacesList || {}, "#places_container");
	
	
	ef.AddToFavorites = (function() {
		
		/**
		 * Add selected place to user's favorites
		 */
		function add(id, coords, fnComplete) {
			$.post(ef.Settings.SERVICES.addToFavorites + id, {id: id}, function(data) {
				
				var target = $('<div id="add_to_fav_content"><p>'+data.message+'</p></div>')
					.appendTo('body')
					.css(coords)
					.hide()
					.fadeIn();
				
				
				var delayTime = 2000;
				//	ok
				if (data.success == 1) {
					//	update current place as favorite
					var favoritePlace = ef.PlacesModel.getItemByKey("id", data.id);
					favoritePlace.favorite = 1;
					if (fnComplete && typeof fnComplete == "function") {
						fnComplete(data.id);
					}
				//	error	
				} else {
					delayTime = 5000;
				};
				
				setTimeout(function() {
					target.fadeOut();
				}, delayTime);
				
			});
		}
		
		return {
			add: add
		};
	})();
	
	ef.TemplateEngine = {
		parse: function(template, hash) {
			var regExp;
				
	       $.each(hash, function(index, value) {
	       	   regExp = new RegExp('\{' + index + '\}', 'gi');
	           template = template.replace(regExp, value);
	       });
	
	       return template;
		},
		replace: function(template, key, value) {
			var regExp = new RegExp('\{' + key + '\}', 'gi');
			template = template.replace(regExp, value);
			return template;
		}
	};
	
	ef.TabsManager = (function(options){
		var element,
			nav,
			content,
			SETTINGS = {
				selector: ".tabs_manager",
				nav: ".tabs_nav li",
				content: ".tabs_content li",
				current: "tab_current"
		};
		
		/**
		 * @constructor
		 */
		(function(){
			$.extend(SETTINGS, options);
			init();
		})();
		
		function init() {
			element = $(SETTINGS.selector);
			nav = element.find(SETTINGS.nav);
			content = element.find(SETTINGS.content);
			
			nav.find("a").unbind("click").bind("click", nav_clickHandler);
			
			setItems();
		}
		
		function setItems() {
			content.find("a").unbind("click").bind("click", function(e) {
				var id = $.getParam($(this).attr("href"),"id");
				$.fancybox({
					type: "ajax",
					href: ef.Settings.SERVICES.placeDetail + "/" + id,
					'autoDimensions': false,
					'width': 730,
					'height': 500,
					'scrolling': 'no' 
				});
			});
		}
		
		function nav_clickHandler(e) {
			e.preventDefault();
			var li = $(this).closest("li");
			//	find clicked item index
			var index = nav.index(li);
			//	updates tabs navigation
			nav
				.removeClass(SETTINGS.current)
				.eq(index)
					.addClass(SETTINGS.current);
			//	shows content for selected tab		
			content
				.removeClass(SETTINGS.current)
				.eq(index)
					.addClass(SETTINGS.current);
		}
	
	})();
	
	/**
	 *	@class	Form validator handler
	 */
	ef.FormValidator = function(form, options){
		//	private properties
		var element = $(form),
			form = element.find("form"),
			formFields,
			formSubmit,
			SETTINGS = {
				required: '.js_required',
				submitSelector: 'input[type=submit]',
				ajax: true,
				success: function(){},
				error: 'error',
				disabled: 'disabled'
			};	
		
		/**
		 * @constructor
		 */
		(function(){
			$.extend(SETTINGS, options);
			init();
		})();
		
		//	>>	private methods
		function init() {
			formFields = element.find(SETTINGS.required);
			formSubmit = element.find(SETTINGS.submitSelector);
			enableSubmit();
		}
		
		function validateForm() {
			var i,
				currentField,
				numErrors = 0,
				totalFields = formFields.length;
			
			for (i=0; i < totalFields; i++) {
				currentField = $(formFields[i]);
				
				//	validation for InputFocus element
				if (currentField.attr("rel") == "focus") {
					if (currentField.val() == currentField.attr("title")) {
						addFieldError(currentField);
						numErrors++;
					} else {
						removeFieldError(currentField);
					}
				//	default form elements
				} else {
					if (currentField.val() == "") {
						addFieldError(currentField);
						numErrors++;
					} else {
						removeFieldError(currentField);
					}
				}
			}
			
			return (numErrors == 0);
		}
		
		function disableSubmit() {
			form.unbind('submit');
			formSubmit
				.addClass(SETTINGS.disabled)
				.unbind('click');
		}
		
		function enableSubmit() {
			form.unbind('submit').bind('submit', formSubmit_clickHandler);
			formSubmit
				.removeClass(SETTINGS.disabled)
				.unbind('click')
				.bind('click', formSubmit_clickHandler);
		}
		
		function addFieldError(currentField) {
			currentField.addClass(SETTINGS.error);
		}
		
		function removeFieldError(currentField) {
			currentField.removeClass(SETTINGS.error);
		}
		//	>>	public methods
		
		//	>>	event handlers
		/*	submit clicked	*/
		function formSubmit_clickHandler(e) {
			if (SETTINGS.ajax) {
				e.preventDefault();
				if (validateForm()) {
					disableSubmit();
					$.post(form.attr("action"), form.serializeArray(), function(data) {
						enableSubmit();
						element.html(data);
						
					//	SETTINGS.success();
						return false;
					});
				}
			}
		}
	};
}(ef, jQuery));


if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
