
// https://googlemaps.github.io/js-markerclusterer/classes/MarkerClusterer.html
// add true for noDraw
// bounds : https://stackoverflow.com/questions/19304574/center-set-zoom-of-map-to-cover-all-visible-markers/19304625#19304625



function array_first_not_in_second(first, second) {
	let temp_array = [];
	for (let index of first) {
		if (second.indexOf(index) == -1) {
			temp_array.push(index);
		}
	}
	return temp_array;
}

function filter_selection_indexes(menu, indexes, reverse, add) {

	if (indexes.length === 0) {
	// if array of index is empty, delete menu
		delete g_indexes[menu];
	}
	else if (reverse) {
	// if reverse is true, delete all indexes in g_indexes.menu
		// https://stackoverflow.com/questions/5113374/javascript-check-if-variable-exists-is-defined-initialized
		if ( typeof(g_indexes[menu]) !== "undefined" && g_indexes[menu] !== null ) {
			// creates an array with all values of g_indexes[menu] minus indexes
			let temp_array = array_first_not_in_second(g_indexes[menu], indexes);
			if (temp_array.length === 0)
				delete g_indexes[menu];
			else
				g_indexes[menu] = [].concat(temp_array);
		}
	}
	else {
		if (add && typeof(g_indexes[menu]) !== "undefined") {
		// add array of menus to g_indexes{}
			// creates an array with all values of indexes that are not in g_indexes[menu] already
			let temp_array = array_first_not_in_second(indexes, g_indexes[menu]);
			g_indexes[menu] = g_indexes[menu].concat(temp_array);
		}
		else {
		// replace or create array of menu in g_indexes{}
			g_indexes[menu] = [].concat(indexes);
		}
	}

	// loop through all arrays of g_indexes to find intersection
	// take first one as comparison
	let keys = Object.keys(g_indexes);
	let intersection = [];
	let compare = [];
	keys.forEach((key, i) => {
		if (i == 0) {
			intersection = g_indexes[key];
		}
		else {
			let temp = [];
			compare = g_indexes[key];
			for (let index of intersection) {
				if (compare.indexOf(index) != -1)
					temp.push(index);
			}
			intersection = [].concat(temp);
		}
	});
	return intersection;
}

function redraw_clusters(indexes) {

	let indexes_count = indexes.length;

	if (indexes_count !== 0) {
	// if index array, hide all other markers, and if zoomin, zoom to new markers
		g_marker_cluster.clearMarkers(true);

		let marker = g_markers[0];
		let current_bounds = g_map.getBounds();
		let bounds = new google.maps.LatLngBounds();

		let outside_bounds = false;
		for (let index of indexes) {
			marker = g_markers[index];
			position = marker.getPosition();
			if (! current_bounds.contains(position))
				outside_bounds = true;
			bounds.extend(position);

			g_marker_cluster.addMarker(marker, true);
		}
		if (outside_bounds) {
			if (indexes_count === 1) {
				g_map.setCenter(position);
				g_map.setZoom(max_zoom);
			}
			else if (indexes_count > 1) {
				g_map.fitBounds(bounds);
			}
		}

	}
	else if ( Object.keys(g_indexes).length === 0 ) {
	// object is empty, there are no filters
		g_map.setCenter(coordinates_default);
		g_map.setZoom(2);
		g_marker_cluster.addMarkers(g_markers, true);
	}
	else { 
	// filters intersection lets no markers on the map
		g_marker_cluster.clearMarkers(true);
	}

	g_marker_cluster.render();
}

function html_item(menu_name, menu_item) {
	let item = menu_item.replace(/ /g, "_");
	let html_id = `filter_${menu_name}_${item}`;
	return document.getElementById(html_id);
}

function toggle_menu_items(menu_name, x_abled) {

	let name = menu_name.replace(/ /g, "_");
	let class_name = `filter_menu_${name}`;
	let items = document.getElementsByClassName(class_name);

	if (x_abled === "disable") {
		for (let item of items) {
			// if item is a menu title (like 'categorie' or 'pays')
			// don't remove 'enable', instead add it, because it's not in the list of 'to_enable'
			if (item.selected) {
				item.classList.add('enable');
			}
			else {
				item.classList.remove('enable');
			}
			if (item.classList.contains('to_enable')) {
				item.classList.replace('to_enable', 'enable');
				item.removeAttribute('disabled');
			}
			else if (! item.selected)
				item.setAttribute('disabled', '');
		}
	}
	else {
		for (let item of items) {
			item.classList.remove('enable');
			item.removeAttribute('disabled');
		}
	}
}

function disable_menus(menu_name_ori, menu_item_ori, reverse, menu_index) {

	let menu_item_name = "";
	if (menu_item_ori == null) // it's a menu name
		menu_item_name = menu_name_ori;
	else
		menu_item_name = menu_item_ori._name;
	let item_ori_html = html_item(menu_name_ori, menu_item_name);
	let is_enabled = item_ori_html.classList.contains('enable');

	// in case it's a menu title, like "Pays" or "Categories",
	// and it does'nt contains 'enable'
	//   just act like Reset button
	//   it's too bad it will also go through this menu items even though it's unnecessary
	if (menu_index == 'menu_name') { // it's a menu name
		if (! is_enabled) {
			// "item" as a menu name will select all items in all menus
			toggle_menu_items("item", "enable");
		}
		return;
	}

	// if it's Mode menu,
	// and it was the first selection, meaning it does'nt contains 'enable'
	// and both (irl and online) are abled or disabled,
	//   just act like Reset button
	//   it's too bas it will also go through this menu items even though it's unnecessary
	if (menu_name_ori === "mode") {
		let mode_menus = document.getElementsByClassName("filter_menu_mode");
		let state = 0;
		for (let mode_menu of mode_menus) {
			if (mode_menu.checked)
				state++;
			else
				state--;
		}
		if (state != 0) { // state equal 0 if both have a different state, because (0 + 1 - 1 = 0) and (0 - 1 + 1 = 0)
			if (! is_enabled) {
				// "item" as a menu name will select all items in all menus
				toggle_menu_items("item", "enable");
				return;
			}
		}
		else if (reverse) { // menu is "mode" and only one item is selected and the action was to deselect one, so the action has trigered one item but really we want to see the options of the other item, so let's switch them
			if (menu_index == 0)
				menu_index++;
			else
				menu_index--;
			menu_item_ori = filters[menu_name_ori][menu_index];
		}
	}

	let keys = Object.keys(menu_item_ori);
	// loop through list of other menu_items available for this menu_item
	// loop though menu names (pays, categories, mode)
	for (let menu_name of keys) {
		if (menu_name === "_name")
			continue;
		if (menu_name === "indexes")
			continue;
		else if (! is_enabled) {

			//	// it's too bad it will disable all and then enable certains, it would be better to check each time
			//	toggle_menu_items(menu_name, "disable");
			//	// loop through items in menu names (ex. for "pays" : france, chili, cuba)
			//	for (let item of menu_item_ori[menu_name]) {
			//		let item_html = html_item(menu_name, item);
			//		item_html.classList.add('enable');
			//		item_html.removeAttribute('disabled');
			//	}

			for (let item of menu_item_ori[menu_name]) {
				let item_html = html_item(menu_name, item);
				item_html.classList.add('to_enable');
			}
			toggle_menu_items(menu_name, "disable");
		}
	}
}

function filter_show_only(element, menu_name) {

	g_infowindow.close();

	let menu_index = element.getAttribute("data-menu_index");
	let menu_item = null;
	let indexes = [];
	if (menu_index != "menu_name") {
		menu_item = filters[menu_name][menu_index];
		indexes = menu_item.indexes;
	}

	add = false;
	reverse = false;
	if (element.type === "checkbox") {
		reverse = ! element.checked;
		add = true;
	}

	disable_menus(menu_name, menu_item, reverse, menu_index);

	let index_array = filter_selection_indexes(menu_name, indexes, reverse, add);

	redraw_clusters(index_array);
}

function filter_show_all() {

	g_infowindow.close();

	// "item" as a menu name will select all items in all menus
	toggle_menu_items("item", "enable");

	g_indexes = {};
	g_marker_cluster.clearMarkers(true);
	g_marker_cluster.addMarkers(g_markers);
	/* dont use fitBounds because it's not well centered */
	/* instead use setCenter and setZoom */
	//g_map.fitBounds(g__init_bounds);
	g_map.setCenter(coordinates_default);
	g_map.setZoom(2);
}

