var Search = new Class({
	
	Implements: Options,
	
	options: {
		'searchForm': null,
		'resultContainer': null,
		'moreButton': null
	},
	
	initialize: function(options){
		this.miOffset = 0;
		this.setOptions(options);
		
		this.options.searchForm = $(this.options.searchForm);
		this.options.resultContainer = $(this.options.resultContainer);
		
		this.build();
	},
	
	build: function(){
		// add saved search events
		$$('a.savedSearch').each(function(oA){
			oA.addEvent('click', function(oEvent){
				oEvent.stop();
				
				var o_item = $(oEvent.target).getParent('li'),
					i_searchid = parseInt(o_item.get('id').replace(/search_/, ''), 10);
					
				
				(new Request.JSON({
					'url': '/ajax/get_saved_search/',
					'method': 'post',
					'onComplete': function(oResponse){
						this.cleanResults();
						this.execute(oResponse);
					}.bind(this)
				})).send('searchid=' + i_searchid);
			}.bind(this));
		}, this);
		
		$$('a.deleteSavedSearch').each(function(oA){
			oA.addEvent('click', function(oEvent){
				oEvent.stop();
				
				var o_item = $(oEvent.target).getParent('li'),
					o_list = o_item.getParent('ul'),
					i_searchid = parseInt(o_item.get('id').replace(/search_/, ''), 10);
				
				o_item.destroy();
				if (o_list.getElements('li').length === 0){
					$('savedSearches').destroy();
				}
				
				(new Request.JSON({
					'url': '/ajax/delete_saved_search/',
					'method': 'post',
					'data': $H({
						'searchid': i_searchid
					}).toQueryString()
				})).send();
			});
		});
	},
	
	getPostData: function(){
		// format post data
		var o_data = $H({});
		if (this.options.searchForm === null){
			return o_data;
		}
		
		// all inputs
		this.options.searchForm.getElements('input').each(function(oInput){
			var s_name = oInput.get('name'),
				s_value = oInput.get('value').trim();
			if (s_value.length === 0){
				return;
			}
			
			// skip values within closed segments
			if (oInput.getParent('div.segment.closed')){
				return;
			}
			
			switch (oInput.get('type')){
				case 'text':
				case 'hidden':
					o_data[s_name] = s_value;
					break;
					
				case 'checkbox':
					if (oInput.get('checked') === false){
						return;
					}
					
					if ($type(o_data[s_name]) === false){
						o_data[s_name] = $A([]);
					}
					
					o_data[s_name].include(oInput.get('value'));
					break;
			}
		});
		
		// all selects
		this.options.searchForm.getElements('select').each(function(oSelect){
			// skip invalid selects
			if (oSelect.get('value') === '' || oSelect.get('name') === null || oSelect.get('name').trim().length === 0){
				return;
			}
			
			o_data[oSelect.get('name')] = oSelect.get('value');
		});
		
		return o_data;
	},
	
	cleanResults: function(){
		this.miOffset = 0;
		var o_header = this.options.resultContainer.getElement('h3');
		this.options.resultContainer.set('html', '').adopt(o_header);
		this.options.resultContainer.addClass('loading');
	},
	
	execute: function(externalData){
		var o_data, 
			s_type;
		
		externalData = $type(externalData) ? externalData : null;
		
		// stop event
		if (arguments.length > 0 && $type(arguments[0]) === 'event'){
			arguments[0].stop();
		}
		
		// gather post data
		if (externalData !== null){
			o_data = $H(externalData);
		} else {
			o_data = this.getPostData();
		}
		
		// determine search type
		if (this.options.searchForm.get('class').match(/^type_/)){
			s_type = this.options.searchForm.get('class').replace(/^type_/, '');
		}
	
		// check for current request
		if ($type(this.moRequest) !== false){
			return false;
		}
		
		// init request
		this.moRequest = new Request.JSON({
			'url': '/search.php?action=search&offset=' + this.miOffset + (s_type.length > 0 ? '&type=' + escape(s_type) : ''),
			'method': 'post',
			'onComplete': this.handleResponse.bind(this)
		});
		
		// fire request
		this.moRequest.send(o_data.toQueryString());
	},
	
	handleResponse: function(oResponse){
		// get rid of current request object
		delete this.moRequest;
		
		// remove more button
		if ($(this.options.moreButton)){
			$(this.options.moreButton).destroy();
		}
		
		// add response HTML to result container
		try {
			this.options.resultContainer.set('html', this.options.resultContainer.get('html') + oResponse.html);
			this.options.resultContainer.removeClass('loading');
		} catch (x){}
		
		// keep track of current offset
		this.miOffset = oResponse.offset;
		
		// make results behave on mouse events
		$$('div.result').each(function(oResult){
			oResult.removeEvents();
			oResult.addEvent('mouseover', this.bringToFront.bind(this));
			oResult.addEvent('mouseleave', this.sendToBack.bind(this));
		}, this);
		
		// determine which images ar new
		var a_all_images = $$('div.results img.profile'),
			i_new_pointer = (a_all_images.length - oResponse.results),
			a_new_images = a_all_images.filter(function(item, index){
				return index >= i_new_pointer;
			});
		
		// magically resize new images
		a_new_images.each(function(oImg){
			// if not loaded completely
			// enhance when loaded
			if (oImg.get('height') === null){
				oImg.addEvent('load', function(){
					this.enhanceImage(oImg);
				}.bind(this));
				return;
			}
			
			// when loaded, enhance now
			this.enhanceImage(oImg);
		}, this);
		
		// add event to more button when shown
		if ($(this.options.moreButton)){
			$(this.options.moreButton).addEvent('click', function(oEvent){
				oEvent.stop();
				
				$(this.options.moreButton).set('html', '');
				$(this.options.moreButton).addClass('loading');
				this.execute();
			}.bind(this));
		}
		
		// add event to save results button
		if ($('saveResultsButton')){
			$('saveResultsButton').removeEvents();
			$('saveResultsButton').addEvent('click', function(){
				if ($('saveResultsButton').hasClass('goldmember')){
					location = '/goldmember/';
					return;
				}
				
				// switch shown text
				$('resultsText').setStyle('display', 'none');
				$('saveText').setStyle('display', 'block');
				$('saveName').focus();
				// replace button handler
				$('saveResultsButton').removeEvents().addEvent('click', this.handleSaveSearch.bind(this));
			}.bind(this));
		}
	},
	
	enhanceImage: function(oImg){
		var o_gay = new GayImage({
			'imageSource': oImg.get('src'),
			'container': oImg.getParent('div.resultImage'),
			'valign': 'face',
			'width': 80,
			'height': 80,
			'onComplete': function(){
				oImg.removeClass('loading');
			}
		});
		o_gay.setImage(oImg, false);
	},
	
	bringToFront: function(oEvent){
		oEvent.stop();
		
		// trace right parent
		var o_target = $(oEvent.target),
			a_styles,
			o_image;
		if (o_target.get('tag') !== 'div' || !o_target.hasClass('result')){
			o_target = o_target.getParent('div.result');
		}
		
		// store object position
		a_styles = {
			'top': o_target.getCoordinates().top,
			'left': o_target.getCoordinates().left
		};
		
		// remove existing placeholder
		if ($type(o_target.o_placeholder) !== false){
			o_target.o_placeholder.destroy();
			delete o_target.o_placeholder;
		}
		
		// prepare placeholder
		o_target.o_placeholder = new Element('div', {
			'class': 'result'
		});
		o_target.o_placeholder.inject(o_target, 'before');
		
		// adjust image size
		o_image = o_target.getElement('img.profile');
		if (o_image.get('height') === '80'){
			o_image.set('height', 82);
		}
		
		if (o_image.get('width') === '80'){
			o_image.set('width', 82);
		}
		
		// bring to front
		o_target.addClass('over').setStyles(a_styles);
	},
	
	sendToBack: function(oEvent){
		oEvent.stop();
		
		// trace right parent
		var o_target = $(oEvent.target);
		if (o_target.get('tag') !== 'div' || !o_target.hasClass('result')){
			o_target = o_target.getParent('div.result');
		}
		
		// remove existing placeholder
		if ($type(o_target.o_placeholder) !== false){
			o_target.o_placeholder.destroy();
			delete o_target.o_placeholder;
		}
		
		// send to back
		o_target.removeClass('over');
	},
	
	handleSaveSearch: function(){
		if ($('saveName').get('value').trim().length === 0){
			$('saveName').focus();
			return;
		}
		
		(new Request.JSON({
			'url': '/ajax/save_search/',
			'method': 'post',
			'data': $H({
				'searchname': $('saveName').get('value').trim()
			}).toQueryString()
		})).send();
		
		// when finished
		// remove form
		$('saveResultsButton').destroy();
		$('saveText').setStyle('display', 'none');
		$('resultsText').setStyle('display', 'block');
	}
}),

fetchRegions = function(){
	if (!$('searchRegion')){
		return;
	}
	
	var o_body = $('searchRegion'),
		i_current = $('searchRegion').get('value'),
		s_country = $('searchCountry').get('value');
	
	initCityCompleter();
		
	(new Request.JSON({
		'url': '/ajax/get_regions',
		'method': 'post',
		'data': $H({
			'country': s_country
		}).toQueryString(),
		'onComplete': function(oResponse){
			var s_all_text = '';
			try {
				s_all_text = o_body.getElement('option').get('text');
			} catch (x){}
			
			o_body.empty();
			if (s_all_text.length > 0){
				o_body.adopt(new Element('option', {'text': s_all_text, 'value': ''}));
			}
			
			oResponse.each(function(oRegion){
				var o_option = new Element('option', {
					'value': oRegion.regionid,
					'text': oRegion.region
				});
				if (oRegion.regionid === i_current){
					o_option.set('selected', 'selected');
				}
				
				o_body.adopt(o_option);
			});
		}
	})).send();
},

anythingChecked = function(sName){
	var o_items = $$('input[name=' + sName +']'), 
		b_checked = false;
	o_items.each(function(oInput){
		if (!oInput.hasClass('toggle') && oInput.checked === true){
			b_checked = true;
		}
	});
	
	return b_checked;
},

getLocality = function(fLat, fLong){
	var o_geocoder = new google.maps.Geocoder();
	o_geocoder.geocode({
		'address': fLat + ' ' + fLong
	}, function(results, status){
		if (status != google.maps.GeocoderStatus.OK){
			return;
		}
		
		var s_locality;
		results[0].address_components.each(function(a_component){
			if (a_component.types[0] == "locality" && a_component.types[1] == "political" && s_locality === undefined){
				s_locality = a_component.long_name;
			}
		});
		
		(new Request.JSON({
			'url': '/ajax/user_geolocality/',
			'method': 'post',
			'async': false,
			'data': $H({
				'locality': s_locality
			}).toQueryString(),
			'onComplete': function(){
				$('updateGeoLocation').set('tween', {
					'onComplete': function(){
						$('updateGeoLocation').destroy();
//						$('locationUpdated').setStyle('display', '').fade('hide').fade('in');
						location.reload(true);
					}
				});
				$('updateGeoLocation').fade('out');
			}
		})).send();
	});
},

cityCompleter, otCity,

initCityCompleter = function(){
	var s_url = '/ajax/search_cities_country',
		a_data = {
			'country': $('searchCountry').get('value')
		};
	if ($('searchRegion').get('value') !== ''){
		s_url = '/ajax/search_cities';
		a_data = {
			'regionid': $('searchRegion').get('value')
		};
	}
	
	cityCompleter = new SimpleComplete($('searchCity'), {
		'url': s_url,
		'fieldName': 'cityname'
	});
	cityCompleter.SetExtraData(a_data);
	
	if (otCity){
		otCity.destroy();
	}
	
	otCity = new OverText($('searchCity'));
};

window.addEvent('domready', function(){
	$$('div.tabContainer li').each(function(oTab){
		oTab.addEvent('click', function(oEvent){
			var o_link = this.getElement('a');
			location = o_link.get('href');
		});
	});
	
	$$('h3.segment').each(function(oSegment){
		oSegment.addEvent('click', function(){
			var o_segment = this.getNext('div.segment');
			if (this.hasClass('closed')){
				this.removeClass('closed').addClass('open');
				o_segment.removeClass('closed').addClass('open');
			} else {
				this.removeClass('open').addClass('closed');
				o_segment.removeClass('open').addClass('closed');
			}
		});
	});
	
	// handle toggle 
	$$('input[class!=toggle]').addEvent('click', function(){
		$$('input.toggle[name=' + this.get('name') + ']').each(function(oToggle){
			oToggle.checked = !anythingChecked(this.get('name'));
		}, this);
	});
	
	$$('input.toggle').addEvent('click', function(){
		if (!anythingChecked(this.get('name'))){
			this.checked = true;
			return;
		}
		
		$$('input[name=' + this.get('name') + ']').each(function(oInput){
			if (oInput.hasClass('toggle')){
				return;
			}
			
			oInput.checked = false;
		});
	});
	
	var o_search = new Search({
		'searchForm': 'searchForm',
		'resultContainer': $$('div.resultContainer')[0],
		'moreButton': 'moreResults'
	});
	// auto start first search after 1 second
	(function(){
		o_search.execute();
	}).delay(1000);

	$('goSearch').addEvent('click', function(oEvent){
		oEvent.stop();
	
		o_search.cleanResults();
		(function(){
			o_search.execute();
		}).delay(500);
	}.bind(o_search));
	
	// country, regions and city
	if ($('searchCountry')){
		initCityCompleter();
		
		fetchRegions();
		$('searchCountry').addEvent('change', fetchRegions);
		$('searchRegion').addEvent('change', function(){
			$('searchCity').set('value');
			$('searchCity').focus();
			$('searchCity').blur();
		
			initCityCompleter();
		});
	}
	
	if ($('updateGeoLocation')){
		// handle geolocation
		if ($type(navigator.geolocation) === false){
			// geolocation not supported
			// reset location
			(new Request({
				'url': '/ajax/user_resetlocation/',
				'onComplete': function(){
					location.reload(true);
				}
			})).send('foo=bar');
		} else {
			navigator.geolocation.getCurrentPosition(function(oPosition){
				// update succeeded
				// save results
				(new Request.JSON({
					'url': '/ajax/user_geolocation/',
					'method': 'post',
					'data': $H({
						'latitude': oPosition.coords.latitude,
						'longitude': oPosition.coords.longitude
					}).toQueryString(),
					'onComplete': function(){
						getLocality(oPosition.coords.latitude, oPosition.coords.longitude);
					}
				})).send();
			}, function(){
				// update failed
				// reset location
				(new Request({
					'url': '/ajax/user_resetlocation/',
					'onComplete': function(){
						location.reload(true);
					}
				})).send('foo=bar');
			}, {
				enableHighAccuracy: true,
				maximumAge: 3600000,
				timeout: 30000
			});
		}
	}
});
