
/******************************************************************************
 *  
 *  PROJECT: Flynax Classifieds Software
 *  VERSION: 4.5.2
 *  LICENSE: FL4HLD2A8696 - http://www.flynax.com/license-agreement.html
 *  PRODUCT: Real Estate Classifieds
 *  DOMAIN: savingrack.com
 *  FILE: LIB.JS
 *  
 *  The software is a commercial product delivered under single, non-exclusive,
 *  non-transferable license for one domain or IP address. Therefore distribution,
 *  sale or transfer of the file in whole or in part without permission of Flynax
 *  respective owners is considered to be illegal and breach of Flynax License End
 *  User Agreement.
 *  
 *  You are not allowed to remove this information from the file without permission
 *  of Flynax respective owners.
 *  
 *  Flynax Classifieds Software 2017 | All copyrights reserved.
 *  
 *  http://www.flynax.com/
 ******************************************************************************/

var lfAddressInput = $('#lf-container div.address-line input[type=text]');
var lfHandler = function(base) {
	var self = this;
	var autocomplete = false;
	var geocode_api = "//maps.googleapis.com/maps/api/geocode/json?language=en-GB&latlng={latLng}";
	if (lfConfig['google_key']) {
		geocode_api = 'https:'+geocode_api;
		geocode_api += '&key='+lfConfig['google_key'];
	}

	this.geoChange = function(level){
		var address = '';

		// clear geolocation autocomplete results
		autocomplete.set('place', void(0));

		// get address
		var get = function(field) {
			if (field) {
				var field = $(lfAddressInput).closest('form').find('*[name="f['+field+']"]');
				if (field.length && field.val() != '' && field.val() != '0') {
					address += address ? ', ' : '';
					address += field.prop('tagName').toLowerCase() == 'select' ? field.find('option:selected').text() : field.val();

				}
			}
		}

		// collect
		get(lfConfig['mapping_country']);
		if (level > 1) {
			get(lfConfig['mapping_state']);

			if (level > 2)
				get(lfConfig['mapping_city']);
		}

		// get adderss location
		if (address) {
			var geocoder = new google.maps.Geocoder();
			geocoder.geocode({address: address}, function(results, status){
				if (status == google.maps.GeocoderStatus.OK) {
					self.update(results[0].geometry.location.lat(), results[0].geometry.location.lng());
				}
			})
		};
	}

	this.onGeoChange = function(field, level){
		if (!field) return;

		$(lfAddressInput).closest('form').find('*[name="f['+field+']"]').each(function(){
			if ($(this).prop('tagName').toLowerCase() == 'select') {
				$(this).change(function(){
					if ($(this).hasClass('affected')) {
						$(this).removeClass('affected');
					} else {
						self.geoChange(level);
						$(this).addClass('set');
					}
				});
			} else {
				$(this).blur(function(){
					self.geoChange(level);
				});
			}
		});
	}

	this.geocode = function(position) {
		var api = geocode_api.replace('{latLng}', position.lat()+','+position.lng());

		$.getJSON(api, function(response){
			if (response.status == 'OK') {
				self.parseLocation(response.results);
				$('#lf_use').attr('checked', true);
			} else {
				console.log('locationFinder: Geocoder request failed');
			}
		});
	}

	this.update = function(lat, lng) {
		var pos = new google.maps.LatLng(lat, lng);
		base.markers[0].setPosition(pos);
		base.map.setCenter(pos);

		base.infoWindows[0].close();
		base.infoWindows[0].setContent(lfConfig['phrase_your_location']);
		base.infoWindows[0].open(base.map, base.markers[0]);
		lfUpdate(base);
	}

	this.parseLocation = function(address) {
		if (address.length <= 0) {
			console.log('locationFinder: no location details received')
			return;
		}

		var country = false;
		var state = false;
		var city = false;
		var neighborhood = false;

		for(var i=0; i<address.length; i++) {
			switch(address[i].types[0]) {
				case 'country':
					country = address[i].address_components[0];
					break;

				case 'administrative_area_level_1':
					state = address[i].address_components[0];
					break;

				case 'locality':
					city = address[i].address_components[0];
					break;

				case 'neighborhood':
					neighborhood = address[i].address_components[0];
					break;
			}
		}

		var fillInField = function(field, info, clear, trigger){
			if (!field || !country) return;

			var field = $(lfAddressInput).closest('form').find('*[name="f['+field+']"]');

			field.removeClass('error');
			if (typeof flynaxTpl == 'function' && typeof flynaxTpl.locationHandler == 'function') {
				flynaxTpl.locationHandler();
			}

			if (clear) {
				console.log('clear')
				// field.val(0);
				// return;
			}

			if (!field.length) return;

			if (field.prop('tagName').toLowerCase() == 'select') {
				var val = field.find('option').filter(function(){return trim($(this).html()) == info.long_name}).val();

				if (val == field.val() || field.hasClass('set')) {
					return;
				} else if (val && val != field.val()) {
					field.removeClass('set');
				}

				if (val) {
					field.addClass('affected');

					field.val(val);
					if (trigger) {
						field.trigger('change');
					}
				} else {
					field.val(0);
				}
			} else {
				field.val(info.long_name);
			}
		}

		var last_multifield = $(lfAddressInput).closest('form').find('select[name^="f['+lfConfig['mapping_country']+'_level"]:last');
		var last_field_name = city ? last_multifield.attr('name') : 'f['+lfConfig['mapping_country']+'_level1]';

		// multifield mode
		if (lfConfig['locationFinder_mapping'] && last_multifield.length && typeof xajax_mfBuild == 'function') {
			var locality = this.str2key(country.long_name, state.long_name, city.long_name);
			var alternative = neighborhood.long_name && city.long_name && neighborhood.long_name != city.long_name
			? this.str2key(country.long_name, state.long_name, neighborhood.long_name)
			: '';

			// console.log(locality)
			// console.log(alternative)

			xajax_mfBuild(alternative, last_field_name, '', false, 'listing', 'alphabetic', locality);

			// clear selection
			// fillInField(lfConfig['mapping_country'], country, false);
			// fillInField(lfConfig['mapping_state'], state, false);
			// fillInField(lfConfig['mapping_city'], city, false);
		}
		// non multifield mode
		else {
			fillInField(lfConfig['mapping_country'], country, false, true);
			fillInField(lfConfig['mapping_state'], state, false, true);
			fillInField(lfConfig['mapping_city'], city, false, true);
		}
	}

	this.str2key = function(country, state, city){
		var out = country;
		if (state != '' && state != undefined) {
			out += '+'+state;
		}
		if (city != '' && city != undefined) {
			out += '+'+city;
		}
		out = out.replace(/ /gi, '_').replace(/[^a-zA-Z0-9\+\_]+/g, '').toLowerCase();

		return out;
	}

	// load user location
	if (lfConfig['use_location'] && !lfConfig['postLng']) {
		if (navigator.geolocation) {
			navigator.geolocation.getCurrentPosition(function(position) {
				self.update(position.coords.latitude, position.coords.longitude);
				self.geocode(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
			}, function() {
				// nothing to do
			});
		}
	}

	// initializate
	if (base.markers[0]) {
		// set marker draggable
		base.markers[0].setDraggable(true);
		
		// attache hint
		if (!lfConfig['postZoom']) {
			base.infoWindows[0].setContent(lfConfig['phrase_drag_hint']);
			base.infoWindows[0].open(base.map, base.markers[0]);
		} else {
			lfUse(base);
		}
		
		// set map listeners
		google.maps.event.addListener(base.markers[0], 'dragstart', function(){
			base.infoWindows[0].close();
		});
		
		google.maps.event.addListener(base.markers[0], 'dragend', function(){
			lfUpdate(base);
			$('#lf_use').attr('checked', true);

			self.geocode(base.markers[0].getPosition());
		});
		
		google.maps.event.addListener(base.map, 'zoom_changed', function(){
			lfUpdate(base);
		});
		
		var country_field = $(lfAddressInput).closest('form').find('*[name="f['+lfConfig['mapping_state']+']"]');

		lfUpdate(base);
		if (!lfConfig['use_location'] && country_field.val() == '0') {
			self.geocode(base.markers[0].getPosition());
		}
		
		$('#lf_use').change(function(){
			base.infoWindows[0].close();
			lfUse(base);
		});

		// sync location with fields if fields are empty
		var country_field = $(lfAddressInput).closest('form').find('*[name="f['+lfConfig['mapping_country']+']"]');
		if (country_field.val() == '' || country_field.val() == '0') {
			self.geocode(base.markers[0].getPosition());
		}
		
		// geolocation autocomplete search
		autocomplete = new google.maps.places.Autocomplete(lfAddressInput.get(0));
		var autocompleteEvent = function() {
			var place = autocomplete.getPlace();

			if (typeof place != 'undefined' && place.geometry) {
				self.update(place.geometry.location.lat(), place.geometry.location.lng());
				self.geocode(place.geometry.location);
			} else {
				console.log('locationFinder: geolocation response failed, no geometry');
			}
		};

		google.maps.event.addListener(autocomplete, 'place_changed', autocompleteEvent);
		$('#lf_search').click(autocompleteEvent);

		$('#lf_query').keydown(function(event){
			if ( event.keyCode == 13 ) {
				$(this).closest('form').attr('onsubmit', 'return false;');
			}
		}).blur(function(){
			$(this).closest('form').attr('onsubmit', 'return true;');
		});

		// geo field change listener
		self.onGeoChange(lfConfig['mapping_country'], 1);
		self.onGeoChange(lfConfig['mapping_state'], 2);
		self.onGeoChange(lfConfig['mapping_city'], 3);
	}
}

var lfHighlightFields = function(){
	var error_fields = Array();

	var check = function(name) {
		if (name) {
			var field = $(lfAddressInput).closest('form').find('*[name="f['+name+']"]');
			if (field.length && (field.val() == '' || field.val() == '0')) {
				error_fields.push('f['+name+']');
			}
		}
	}

	check(lfConfig['mapping_country']);
	check(lfConfig['mapping_state']);
	check(lfConfig['mapping_city']);

	printMessage('warning', lfConfig['locationFinder_sync_warning'], error_fields);
}

var lfUpdate = function(base){
	var zoom = base.map.getZoom();
	var lat = base.markers[0].getPosition().lat();
	var lng = base.markers[0].getPosition().lng();
	
	$('#lf_zoom').val(zoom);
	$('#lf_lat').val(lat);
	$('#lf_lng').val(lng);
}

var lfUse = function(base){
	base.markers[0].setVisible($('#lf_use').is(':checked'))
}

var lfAccountAddressOnMap = function(){
    var on_map_input = $('input[name="f[account_address_on_map]"]:checked');

    // return if there isn't such field in the form
    if (!on_map_input.length) {
        return;
    }

    // disable/enable plugin for the listing
    if (parseInt(on_map_input.val())) {
        $('#lf-container').hide();
    }
}

$(document).ready(function(){
	lfConfig['geoCoder'] = new google.maps.Geocoder();

	// assign map container
	if ( lfConfig['containerPosition'] == 'bottom' ) {
		$('div#controller_area form table.submit:last').before($('#lf-container'));
	} else if ( lfConfig['containerPosition'] != 'top' ) {
		var target_group = lfConfig['admin_panel'] 
				? $('legend#legend_group_'+lfConfig['containerPositionGroup']).next().find('> table > tbody')
				: $('div#fs_'+lfConfig['containerPositionGroup']+' > div.body');

		if (lfConfig['containerPositionType'] == 'prepend') {
			target_group.prepend($('#lf-container'));
		} else {
			target_group.append($('#lf-container'));
		}
	}

    // account address on map handler
    lfAccountAddressOnMap();
    $('input[name="f[account_address_on_map]"]').change(function(){
        lfAccountAddressOnMap();
    });
	
    if (!parseInt($('input[name="f[account_address_on_map]"]:checked').val())) {
        // show map container
    	$('#lf-container').show();

        // generate map
        $('#lf_map').flMap({
            addresses: [
                [lfConfig['postLat'] && lfConfig['postLng'] 
                    ? lfConfig['postLat']+','+lfConfig['postLng'] 
                    : lfConfig['location'], lfConfig['location'], lfConfig['postLat'] && lfConfig['postLng'] ? 'direct' : 'geocoder']
            ],
            phrases: {
                notFound: lfConfig['phrase_not_found']
            },
            scrollWheelZoom: false,
            zoom: lfConfig['postZoom'] ? lfConfig['postZoom'] : lfConfig['zoom'],
            ready: lfHandler
        });
    }
});