'use strict';

/**
 * Gestion du mode d'affichage en "grille"
 * pour les catégories et fichiers.
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */
function Grid(section)
{
	// Une requête Ajax est-elle active ?
	var ajaxActive = false;

	// Requête Ajax.
	var ajaxRequest;

	// Géolocalisation.
	var geolocation;
	var geolocationCategories;
	var geolocationGroup;
	var geolocationId;

	// Nombre total d'éléments de la section courante.
	var itemsCountAll = 0;

	// Informations des éléments de la page courante.
	var itemsInfos = {};

	// Critères de tri des éléments.
	var itemsOrderByColumn = '';
	var itemsOrderByOrder = '';

	// Numéro de la page courante.
	var pageCurrent = 1;

	// Identifiant de tous les fichiers de la section.
	var sectionAllId = [];

	// Mode de sélection.
	// 1 : unitaire, 2 : groupe.
	var selectMode = 1;

	// Identifiant du fichier sélectionné en mode unitaire.
	var selectedId = 0;

	// Identifiant des objects sélectionnés en mode 2.
	var selectedGroupId = [];

	// On démarre le script ?
	var start = true;

	// Nombre maximum de lignes de vignettes par page.
	var thumbsLines = 0;

	// Marges latérales des vignettes.
	var thumbsMargin = 12;

	// Nombre maximum de vignettes par ligne.
	var thumbsPerLine = 0;

	// Taille des vignettes, en pixels.
	var thumbsSize = 0;



	init();



	/**
	 * Récupèration des données de la page courante par Ajax.
	 *
	 * @param bool browse
	 *
	 * @return void
	 */
	function ajaxData(browse)
	{
		setAjaxStatus(true);

		thumbsPerLine = getThumbsPerLine();

		ajaxRequest = $.post(
			gallery_path + '/ajax.php',
			{
				anticsrf: anticsrf,
				q: q_pageless + '/page/' + pageCurrent,
				section: 'grid-get-' + section,
				browse: browse ? 1 : 0,

				// Options.
				grid_lines: thumbsLines,
				grid_order_by_column: itemsOrderByColumn,
				grid_order_by_order: itemsOrderByOrder,
				grid_tb_size: thumbsSize,
				items_per_line: thumbsPerLine,
				options: 1
			},
			function(r)
			{
				if (typeof r != 'object' || r === null)
				{
					return;
				}
				switch (r.status)
				{
					case 'error' :
						alert('error: ' + r.message);
						break;

					case 'success' :

						// Redirection.
						if (r.redirect)
						{
							window.location = r.redirect;
						}

						// Paramètres.
						itemsCountAll = r.nb_items;
						itemsInfos = r.items;
						geolocationCategories = r.geolocation_categories || null;
						sectionAllId = r.section_all_id;
						thumbsLines = r.lines;
						thumbsSize = r.thumb_size;

						// Liste "Parcourir".
						if (r.browse)
						{
							var html = '';
							for (var i in r.browse)
							{
								var e = r.browse[i];
								if (e['node'] == 'content')
								{
									var id = e['current'] ? 'c' : '';
									id += e['password'] ? 'p' : '';
									id += e['level'] > 1 ? '' : 'v';
									id += e['type'] == 'album' ? '' : 't';
									id += ':' + e['level'] + '{' + e['id'] + '}' + e['parents'];
									html += `<li id="${id}">${e['subcats'] || e['id'] == 1
										? '<i>+</i>' : ''}<a href="${e['link']}">`;
									html += `<b>${e['title']}</b><i>${e['count']}</i></a></li>`;
								}
							}
							$('#browse').attr('data-subcats', r.browse_subcats);
							$('#browse_inner').attr('data-levels', r.browse_levels);
							$('#browse ul').html(html);

							// Catégorie courante.
							cat_list_current('#browse');

							// Sous-catégories.
							$('.cat_list li > i').off().click(function()
							{
								cat_list_subcats($(this));
							});
						}

						// Listes "Déplacer vers...".
						if (r.move)
						{
							var selected = $('#edit_category_parent option:selected').val();
							var html = '';
							for (var i in r.move)
							{
								var e = r.move[i];
								if (e['node'] == 'content' && e['type'] == 'category')
								{
									var id = 'o';
									id += e['level'] > 1 ? '' : 'v';
									id += e['type'] == 'album' ? '' : 't';
									id += e['subcats'] || e['id'] == 1 ? 's' : '';
									id += e['password'] ? 'p' : '';
									id += ':' + e['level'] + '{' + e['id'] + '}' + e['parents'];
									html += `<option value="${e['id']}" id="${id}">${' '.
										repeat(e['level'] * 4) + e['title']}</option>`;
								}
							}
							$('#edit_category_parent').html(html);
							$('#group_move').html(html.replace(/(<option[^>]+id=")o/g, '$1m'));
							if (selected)
							{
								var parent = $('#edit_category_parent option[value="'
									+ selected + '"]');
								if (parent.length)
								{
									parent
										.attr('id', parent.attr('id').replace('o', 'oc'))
										.attr('selected', true)
										.prop('selected', true);
								}
							}
						}

						// Modification de la vignette de catégorie.
						if (r.cat_thumb)
						{
							$('#obj_thumb').removeClass()
								.addClass(r.cat_thumb.status == 1 ? 'activate' : 'deactivate');
							$('#obj_thumb span').attr('class', r.cat_thumb.type);
							if (r.cat_thumb.source == '')
							{
								$('#obj_thumb a').removeClass('viewer').removeAttr('href');
								$('#obj_thumb img').attr('src', category_empty_thumb);
							}
							else
							{
								$('#obj_thumb a').addClass('viewer')
									.attr('href', r.cat_thumb.link);
								$('#obj_thumb img').attr('src', r.cat_thumb.source);
							}
						}

						// Tags de la galerie.
						if (r.tags)
						{
							tags = r.tags;
							tags_flip = [];
							for (var i in tags)
							{
								tags_flip[tags[i]] = i;
							}
						}

						// Mise à jour des statistiques de la catégorie courante.
						if ($('#box_stats').length)
						{
							for (var stat of Object.keys(r.cat_stats))
							{
								var s = r.cat_stats[stat];
								if (r.cat_stats[stat + '_link'])
								{
									s = '<a href="' + r.cat_stats[stat + '_link'] + '">'
										+ s + '</a>';
								}
								$('#box_stats .' + stat).html(s);
							}
						}

						// Code HTML des vignettes.
						$('#obj_grid_form').empty().append(r.html);
						$('#obj_grid_form dt a').css({
							width: thumbsSize + 'px',
							height: thumbsSize + 'px'
						});
						$('#obj_grid_form dt a img').css({
							maxWidth: thumbsSize + 'px',
							maxHeight: thumbsSize + 'px'
						});
						$('#obj_grid_form dd').css({maxWidth: thumbsSize + 'px'});

						// Mise à jour des informations de sélection.
						if (!sectionAllId.includes(selectedId))
						{
							selectedId = parseInt(($('#obj_grid_form dl:first')
								.attr('id') || '').replace(/\D/g, ''));
						}
						var select = [];
						for (var i = 0, n = 0; i < selectedGroupId.length; i++)
						{
							var id = selectedGroupId[i];
							if (sectionAllId.includes(id))
							{
								select[n] = id;
								n++;
							}
						}
						selectedGroupId = select;
						changeSelection();

						// Pagination.
						pagesUpdate();

						// Nombre de fichiers dans le fil d'Ariane.
						$('#objects_count').text('[' + itemsCountAll + ']');

						if (start)
						{
							$('.obj_panel_content:first-of-type').css('display', 'flex');
							start = false;
						}

						// Gestion de l'affichage des composants de l'interface.
						if (itemsCountAll)
						{
							$('#obj_grid .tools').show();
							$('#obj_panel').css('visibility', 'visible');
						}
						else if (q_filter)
						{
							$('#obj_grid').hide();
							$('#obj_grid_noresult').show();
						}
						else
						{
							$('#obj_grid').hide();
							$('#obj_grid_noitem').show();
							$('#obj_thumb img')
								.attr('src', category_empty_thumb)
								.removeAttr('height')
								.removeAttr('width');
						}

						break;
				}
			},
			'json'
		)
		.always(function()
		{
			setAjaxStatus(false);
		});
	}

	/**
	 * Requête Ajax de mise à jour des informations des fichiers.
	 *
	 * @param mixed id
	 * @param array params
	 * @param bool browse
	 *
	 * @return void
	 */
	function ajaxUpdate(id, params, browse)
	{
		if (ajaxActive && Object.keys(itemsInfos).length)
		{
			return false;
		}
		setAjaxStatus(true);

		// On convertit le tableau en chaîne à cause de max_input_vars.
		var post_id;
		if (Array.isArray(id))
		{
			post_id = id.join(',');
		}
		else
		{
			post_id = id;
		}

		ajaxRequest = $.post(
			gallery_path + '/ajax.php',
			{
				anticsrf: anticsrf,
				section: Array.isArray(id)
					? 'grid-update-group-' + section
					: 'grid-update-' + section,
				id: post_id,
				params: params
			},
			function(r)
			{
				if (typeof r != 'object' || r === null)
				{
					return;
				}
				switch (r.status)
				{
					case 'error' :
						alert('error: ' + r.message);
						break;

					case 'success' :
						if (r.report == 'error')
						{
							clearTimeout(timeout_report);
							$('#report').remove();
							$('main').append(
								'<div id="report" class="error">'
								+ '<div class="report_msg report_error"><p>'
								+ (r.message || l10n_report_error) + '</p></div></div>'
							);
							report();
						}
						if (r.report == 'warning')
						{
							clearTimeout(timeout_report);
							$('#report').remove();
							$('main').append(
								'<div id="report" class="error">'
								+ '<div class="report_msg report_warning"><p>'
								+ r.message + '</p></div></div>'
							);
							report();
						}
						if (r.report == 'nochange')
						{
							clearTimeout(timeout_report);
							$('#report').remove();
							$('main').append(
								'<div id="report"><div class="report_msg report_info"><p>'
								+ (r.message || l10n_report_nochange) + '</p></div></div>'
							);
							report();
						}
						if (r.report == 'success')
						{
							clearTimeout(timeout_report);
							$('#report').remove();
							$('main').append(
								'<div id="report"><div class="report_msg report_success"><p>'
								+ (r.message || l10n_report_success) + '</p></div></div>'
							);
							report();

							if (r.captures)
							{
								VideoCaptures(r.captures);
							}
						}
						break;
				}
			},
			'json'
		)
		.always(function()
		{
			setAjaxStatus(false);
			ajaxData(browse);
		});

	}

	/**
	 * Modifie les propriétés CSS du panneau latéral pour
	 * l'adapter à chaque situation d'affichage (scrolling).
	 *
	 * @return void
	 */
	function changePanelHeight()
	{
		var available_height = $(window).height();
		var top = Math.round($('#obj_panel').offset().top);
		var margin = 15;
		var upload_height = $('#upload_form').is(':visible')
			&& !$('#obj_grid').hasClass('extend')
			? $('#upload_form').outerHeight()
			: 0;
		var search_height = $('#search').is(':visible')
			&& !$('#obj_grid').hasClass('extend')
			? $('#search').outerHeight()
			: 0;
		var max_height = available_height - top - 100 + upload_height + search_height;

		if ($(window).scrollTop() < (top - margin))
		{
			$('#obj_panel > div').css('top', '0');
			$('#obj_panel > div').css('position', 'relative');
		}
		else
		{
			$('#obj_panel > div').css('top', margin + 'px');
			$('#obj_panel > div').css('position', 'fixed');
		}

		$('#obj_panel > div > div').css('maxHeight', max_height + 'px');
	}

	/**
	 * Modifie la sélection de fichiers selon le mode de sélection courant.
	 *
	 * @return void
	 */
	function changeSelection()
	{
		$('#obj_grid_form').attr('data-mode', selectMode);
		$('#obj_grid_form dl').removeClass('selected in_selection');
		$('#obj_grid_form dl dt > span input').prop('checked', false);

		if (selectMode == 1)
		{
			selectOne();
		}

		if (selectMode == 2)
		{
			for (var i = 0; i < selectedGroupId.length; i++)
			{
				$('#obj_' + selectedGroupId[i]).addClass('selected');
			}
			selected_group_id = selectedGroupId;
		}

		for (var i = 0; i < selectedGroupId.length; i++)
		{
			$('#obj_' + selectedGroupId[i]).addClass('in_selection');
			$('#obj_' + selectedGroupId[i] + ' dt > span input').prop('checked', true);
		}

		// Nombre d'éléments sélectionnés.
		$('#obj_panel_menu li[data-select="2"] a span').text('(' + selectedGroupId.length + ')');
	}

	/**
	 * Modifie l'affichage des vignettes en fonction de
	 * la taille du conteneur à vignettes.
	 *
	 * @return void
	 */
	function changeThumbsDisplay()
	{
		var items_per_line = getThumbsPerLine();
		var items_per_page = thumbsLines * items_per_line;
		var current_nb_items = $('#obj_grid_form dl').length;
		var html = '<dl class="empty"><dt><a></a></dt></dl>';

		// Si le nombre de fichiers de la page courante est supérieur à celui
		// qu'il y aura après redimensionnement, on supprime les fichiers en trop.
		if (current_nb_items > items_per_page)
		{
			ajaxRequest.abort();

			var n = current_nb_items - items_per_page;
			$('#obj_grid_form dl:nth-last-child(-n+' + n + ')').remove();

			pagesUpdate();
		}

		// Sinon, si le nombre de fichiers de la section est inférieur
		// au nombre de fichiers que l'on peut afficher par page, on
		// réajuste seulement le nombre de "fausses vignettes".
		else if (itemsCountAll <= current_nb_items)
		{
			ajaxRequest.abort();

			var items_lines = Math.ceil(itemsCountAll / items_per_line);
			var diff = (items_lines * items_per_line) - itemsCountAll;
			$('#obj_grid_form dl:not(.obj)').remove();
			$('#obj_grid_form').append(html.repeat(diff));
		}

		// Sinon, si le nombre de fichiers à afficher est différent après
		// redimensionnement, on met à jour la page courante.
		else if (items_per_line != thumbsPerLine)
		{
			// On ajuste le nombre de "fausses vignettes" pour assurer
			// une transition plus propre.
			var items_lines = Math.ceil(current_nb_items / items_per_line);
			var diff = (items_lines * items_per_line) - current_nb_items;
			$('#obj_grid_form dl:not(.obj)').remove();
			$('#obj_grid_form').append(html.repeat(diff));
		}

		$('#obj_grid_form dl.empty a').css('width', thumbsSize + 'px');

		thumbsPerLine = items_per_line;

		// Si la page courante est un nombre supérieur au nombre de pages,
		// on réactualise l'affichage des vignettes.
		var nb_pages = getPagesCount();
		if (pageCurrent > nb_pages)
		{
			pageCurrent = nb_pages;
		}

		changePanelHeight();

		// On met à jour les vignettes.
		ajaxData();
	}

	/**
	 * Géolocalise le fichier courant.
	 *
	 * @return void
	 */
	function geolocationItem(reload)
	{
		if (!$('#obj_panel_map').is(':visible'))
		{
			return;
		}

		var reload = reload || geolocationId != selectedId;
		var infos = itemsInfos[selectedId];

		if (section == 'categories' && reload)
		{
			$('#geolocation_cat_coords option:not([value="0"])').remove();
			for (var i = 0; i < geolocationCategories.length; i++)
			{
				$('#geolocation_cat_coords').append(
					'<option value="' + geolocationCategories[i].id
					+ '" data-lat="' + geolocationCategories[i].latitude
					+ '" data-long="' + geolocationCategories[i].longitude
					+ '">' + geolocationCategories[i].name + '</option>');
			}
		}

		var set_marker = function()
		{
			var lat = geolocation.getCoord(infos['geolocation']['latitude']);
			var lng = geolocation.getCoord(infos['geolocation']['longitude']);
			$('#geolocation_latitude').val(lat);
			$('#geolocation_longitude').val(lng);

			if (infos['geolocation']['marker'])
			{
				geolocation.setMarker([lat, lng]);
			}
			else
			{
				var latlong =
				[
					$('#geolocation_worldmap').attr('data-lat'),
					$('#geolocation_worldmap').attr('data-long')
				];
				geolocation.deleteMarker();
				geolocation.map.setView(latlong, $('#geolocation_worldmap').attr('data-zoom'));
			}

			geolocationId = selectedId;
		};

		if (typeof geolocation != 'object')
		{
			geolocation = new Worldmap('geolocation', set_marker);
		}
		else if (reload)
		{
			set_marker();
		}
	}

	/**
	 * Retourne le nombre de pages de la section.
	 *
	 * @return int
	 */
	function getPagesCount()
	{
		return Math.ceil(itemsCountAll / (thumbsLines * getThumbsPerLine()));
	}

	/**
	 * Retourne le nombre maximum de vignettes par ligne.
	 *
	 * @return int
	 */
	function getThumbsPerLine()
	{
		return Math.floor(
			parseInt($('#obj_grid_form').outerWidth()) / (thumbsSize + (thumbsMargin * 2))
		);
	}

	/**
	 * Initialisation : mise en place des événements sur les éléments
	 * d'interface et récupération des données pour générer la page.
	 *
	 * @return void
	 */
	function init()
	{
		// Taille des vignettes.
		thumbsSize = parseInt($('#grid_tb_size').val());

		// Elargissement de la zone des vignettes.
		$('#obj_panel_extend').click(function()
		{
			var el = $('#menu_inner, #menu_subsection,'
				+ ' #search > fieldset, #upload_form > fieldset');
			if ($('#obj_grid').hasClass('extend'))
			{
				el.show();
				$('#obj_grid').removeClass('extend');
				$('#content_subsection').css('position', 'relative');
				$(this).attr('title', $(this).attr('data-l10n-extend'));
				$(this).find('img').attr('src', $(this).find('img').attr('src')
					.replace(/^(.+\/)(.+?)(\.png)$/, '$1extend$3'));
			}
			else
			{
				el.hide();
				$('#obj_grid').addClass('extend');
				$('#content_subsection').css('position', 'static');
				$(this).attr('title', $(this).attr('data-l10n-reduce'));
				$(this).find('img').attr('src', $(this).find('img').attr('src')
					.replace(/^(.+\/)(.+?)(\.png)$/, '$1reduce$3'));
			}
			changeThumbsDisplay();

			return false;
		});

		// Menus du panneau latéral.
		$('#obj_panel_menu a,.obj_panel_submenu a').click(function()
		{
			$(this).parent('li').parent('ul').find('li').removeClass('current');
			$(this).parent().addClass('current');

			$(this).parent('li').parent('ul').parent('div')
				.children('div').css('display', 'none');

			$(this).parent('li').parent('ul').parent('div')
				.children('div:eq(' + $(this).parent().index() + ')')
				.css('display', 'flex')
				.find('.focus').focus();

			if ($('#obj_panel_map').is(':visible'))
			{
				geolocationItem(false);
			}
			if ($('#obj_panel_group_map').is(':visible') && typeof geolocationGroup != 'object')
			{
				if (section == 'categories')
				{
					$('#group_geolocation_cat_coords option:not([value="0"])').remove();
					for (var i = 0; i < geolocationCategories.length; i++)
					{
						$('#group_geolocation_cat_coords').append(
							'<option value="' + geolocationCategories[i].id
							+ '" data-lat="' + geolocationCategories[i].latitude
							+ '" data-long="' + geolocationCategories[i].longitude
							+ '">' + geolocationCategories[i].name + '</option>');
					}
				}
				geolocationGroup = new Worldmap('group_geolocation');
			}

			return false;
		});
		$('#obj_panel_menu a').click(function()
		{
			selectMode = $(this).parent().attr('data-select');
			changeSelection();
			return false;
		});

		// Barres de navigation entre les pages.
		$('.pages .first:not(.inactive)').click(function()
		{
			if (!ajaxActive)
			{
				pageCurrent = 1;
				ajaxData();
			}
			return false;
		});
		$('.pages .prev:not(.inactive)').click(function()
		{
			if (!ajaxActive)
			{
				pageCurrent--;
				ajaxData();
			}
			return false;
		});
		$('.pages .next:not(.inactive)').click(function()
		{
			if (!ajaxActive)
			{
				pageCurrent++;
				ajaxData();
			}
			return false;
		});
		$('.pages .last:not(.inactive)').click(function()
		{
			if (!ajaxActive)
			{
				pageCurrent = getPagesCount();
				ajaxData();
			}
			return false;
		});
		$('.grid .pages form').submit(function()
		{
			if (!ajaxActive)
			{
				var page = $(this).find('input[name="page"]').val();
				if (!page.match(/^\d{1,12}$/) || page.match(/^0/))
				{
					return false;
				}
				page = parseInt(page);
				if (page < 1 || page > getPagesCount() || page == pageCurrent)
				{
					return false;
				}
				pageCurrent = page;
				ajaxData();
			}
			return false;
		});

		// Options d'affichage.
		$('#options select').change(function()
		{
			$(this).children('option').attr('selected', false);
			$(this).children('option:selected').attr('selected', true);
		});
		$('#grid_lines').change(function()
		{
			thumbsLines = parseInt($(this).val());
			pageCurrent = 1;
			ajaxData();
		});
		$('#options select[name="order_by_column"]').change(function()
		{
			itemsOrderByColumn = $(this).val();
			ajaxData();
		});
		$('#options select[name="order_by_order"]').change(function()
		{
			itemsOrderByOrder = $(this).val();
			ajaxData();
		});
		$('#grid_tb_size').change(function()
		{
			thumbsSize = parseInt($(this).val());
			pageCurrent = 1;
			ajaxData();
		});

		// Outils de sélection.
		$('#selection a').click(function()
		{
			if (ajaxActive)
			{
				return false;
			}

			var link = $(this).attr('id');

			// Sélectionner tous les fichiers de la section.
			if (link == 'selection_section_all')
			{
				selectedGroupId = Object.assign([], sectionAllId);
			}

			// Désélectionner tous les fichiers de la section.
			if (link == 'selection_section_none')
			{
				selectedGroupId = [];
			}

			// Inverser la sélection pour tous les fichiers de la section.
			if (link == 'selection_section_invert')
			{
				var temp = Object.assign([], selectedGroupId);
				selectedGroupId = [];
				for (var i = 0; i < sectionAllId.length; i++)
				{
					if (!temp.includes(sectionAllId[i]))
					{
						selectedGroupId.push(sectionAllId[i]);
					}
				}
				temp = [];
			}

			// Sélectionner tous les fichiers de la page.
			if (link == 'selection_page_all')
			{
				for (var id of Object.keys(itemsInfos))
				{
					if (!selectedGroupId.includes(parseInt(id)))
					{
						selectedGroupId.push(parseInt(id));
					}
				}
			}

			// Désélectionner tous les fichiers de la page.
			if (link == 'selection_page_none')
			{
				for (var id of Object.keys(itemsInfos))
				{
					if (selectedGroupId.includes(parseInt(id)))
					{
						var index = selectedGroupId.indexOf(parseInt(id));
						if (index > -1)
						{
							selectedGroupId.splice(index, 1);
						}
					}
				}
			}

			// Inverser la sélection pour tous les fichiers de la page.
			if (link == 'selection_page_invert')
			{
				for (var id of Object.keys(itemsInfos))
				{
					if (selectedGroupId.includes(parseInt(id)))
					{
						var index = selectedGroupId.indexOf(parseInt(id));
						if (index > -1)
						{
							selectedGroupId.splice(index, 1);
						}
					}
					else
					{
						selectedGroupId.push(parseInt(id));
					}
				}
			}

			changeSelection();
			return false;
		});

		// Visualisation des images en grande taille (viewer).
		$('body').on('click', '#obj_panel_preview img', function()
		{
			viewer($(this).attr('data-src'));
			return false;
		});
		$('body').on('dblclick', '#obj_grid_form dt a', function()
		{
			viewer($(this).attr('data-src'));
			return false;
		});

		// Sélection de vignettes.
		$('body').on('click', '#obj_grid_form dt a, #obj_grid_form dt > span', function()
		{
			var id = parseInt($(this).parents('dl').attr('id').replace(/\D/g, ''));

			if (selectMode == 1 && id != selectedId && !$(this).is('span'))
			{
				selectedId = id;
			}
			if (selectMode == 2 || $(this).is('span'))
			{
				if (selectedGroupId.includes(id))
				{
					var index = selectedGroupId.indexOf(id);
					if (index > -1)
					{
						selectedGroupId.splice(index, 1);
					}
				}
				else
				{
					selectedGroupId.push(id);
				}
			}

			changeSelection();
			if ($(this).is('a'))
			{
				return false;
			}
		});

		// Rechargement de la carte.
		$('body').on('click', '.obj_panel_content .icon_map', function()
		{
			var prefix = $(this).attr('id').replace('_reload', '');
			if (prefix == 'geolocation')
			{
				geolocation.esri.redraw();
				geolocation.osm.redraw();
			}
			else
			{
				geolocationGroup.esri.redraw();
				geolocationGroup.osm.redraw();
			}
			return false;
		});

		// Réinitilisation de la date de publication.
		$('body').on('change', '#edit_status', function()
		{
			change_reset_item_pubdt($('#edit_status').val(), '#edit_reset_item_pubdt');
		});

		// Mises à jour des informations.
		if (section == 'items')
		{
			updateItem();
			updateGroupItems();
		}
		else
		{
			updateCategory();
			updateGroupCategories();
		}

		// Redimensionnement du navigateur.
		$(window).resize(function()
		{
			changeThumbsDisplay();
		});

		// Modification de la hauteur du panneau latéral.
		$(window).scroll(function()
		{
			changePanelHeight();
		});
		$('#tools_display .tools span, #obj_grid .tools span').click(function()
		{
			changePanelHeight();
		});
		changePanelHeight();

		// Récupération des fichiers.
		ajaxData();
	}

	/**
	 * Met à jour les barres de navigation entre les pages.
	 *
	 * @return void
	 */
	function pagesUpdate()
	{
		var nb_pages = getPagesCount();

		if (pageCurrent > nb_pages)
		{
			var pages_count = Math.ceil(itemsCountAll / (thumbsLines * thumbsPerLine));
			if (pages_count > 0 && pageCurrent > pages_count)
			{
				pageCurrent = pages_count;
				ajaxData();
			}
			return;
		}

		if (nb_pages < 2)
		{
			$('.pages').addClass('hidden').hide();
			return;
		}

		$('.pages_inner > div').hide();

		// Nombre de pages.
		$('.pages .count').text(nb_pages);

		// Liens de navigation.
		if (pageCurrent == 1)
		{
			$('.pages .first.inactive,.pages .prev.inactive').show();
		}
		else
		{
			$('.pages .first:not(.inactive),.pages .prev:not(.inactive)').show();
		}
		if (pageCurrent == nb_pages)
		{
			$('.pages .next.inactive,.pages .last.inactive').show();
		}
		else
		{
			$('.pages .next:not(.inactive),.pages .last:not(.inactive)').show();
		}

		// Page courante.
		$('.pages input[name="page"]').val(pageCurrent);

		$('.pages').removeClass('hidden').show();
	}

	/**
	 * En mode "unitaire", sélectionne la vignette correspondant au
	 * fichier ayant l'identifiant selectedId et rempli tous les
	 * onglets du panneau latéral des informations de ce fichier.
	 *
	 * @return void
	 */
	function selectOne()
	{
		var id = '#obj_' + selectedId;
		if (!$(id).is('dl'))
		{
			return;
		}
		$(id).addClass('selected');

		var html = '', link = '';
		var infos = itemsInfos[selectedId];

		// On modifie les informations à afficher que si celles enregistrées sont différentes.
		if (!start && infos['hash'] == $('#obj_panel_infos').attr('data-hash'))
		{
			return;
		}
		$('#obj_panel_infos').attr('data-hash', infos['hash']);
		$('#obj_panel_infos').attr('data-id', selectedId);

		// Modifications : réinitialisation des <select>.
		$('#obj_panel_one option')
			.attr('selected', false)
			.prop('selected', false);

		// Focus sur le formulaire.
		if ($('#obj_panel_one').is(':visible'))
		{
			$('#obj_panel_one > div:visible .focus').focus();
		}

		// Catégories.
		if (section == 'categories')
		{
			// Statistiques.
			html = '<a href="' + infos['user_link'] + '">' + infos['user_nickname'] + '</a>';
			$('#obj_panel_stats_user span').html(html);
			$('#obj_panel_stats_crtdt span').text(infos['crtdt']);
			for (var stat of Object.keys(infos['stats']))
			{
				var s = infos['stats'][stat];
				if (infos['stats'][stat + '_link'])
				{
					s = '<a href="' + infos['stats'][stat + '_link'] + '">' + s + '</a>';
				}
				$('#obj_panel_stats .' + stat).html(s);
			}
			if (infos['type'] == 'album')
			{
				$('#obj_panel_stats_albums').hide();
				$('#obj_panel_stats_subcats').hide();
			}
			else
			{
				$('#obj_panel_stats_albums').show();
				$('#obj_panel_stats_subcats').show();
			}
			$('#obj_panel_stats_type span').html(infos['type_text']);
			$('#obj_panel_stats_files span').html(infos['stats']['t_items']);
			$('#obj_panel_stats_subcats span').html(infos['stats']['t_childs']);

			// Mot de passe.
			if (infos['password'])
			{
				if (infos['password_parent'])
				{
					link = '<a href="' + infos['password_parent_link'] + '">'
						+ infos['password_parent_name'] + '</a>';
					html = (infos['type'] == 'album')
						? l10n_password_parent_album
						: l10n_password_parent_category;
					html = html.replace(/\%s/, link);
				}
				else
				{
					html = (infos['type'] == 'album')
						? l10n_password_album
						: l10n_password_category;
				}
				$('#obj_panel_submenu_password').show();
				$('#obj_panel_infos_password > p').html(html);
			}
			else
			{
				$('#obj_panel_submenu_password').hide();
				$('#obj_panel_infos_password > p').html('');

				if ($('#obj_panel_submenu_password').hasClass('current'))
				{
					$('#obj_panel_submenu_password').removeClass('current');
					$('#obj_panel_infos .obj_panel_submenu li:first-child').addClass('current');
					$('#obj_panel_infos_password').hide();
					$('#obj_panel_infos .obj_panel_content:first-of-type').css('display', 'flex');
				}
			}

			// Lien vers la galerie.
			if (infos['gallery_link'])
			{
				link = '<a title="' + l10n_gallery_link + '" class="obj_gallery_link"';
				link += ' href="' + infos['gallery_link'] + '"></a>';
				$('#obj_panel_stats h4').append(link);
			}
			else
			{
				$('#obj_panel_stats .obj_gallery_link').remove();
			}

			// Modifications : informations diverses.
			$('#edit_title').val($('<textarea/>').html(infos['title']).text());
			$('#edit_urlname').val(infos['url']);
			$('#edit_dirname').val(infos['dirname']);
			$('#edit_desc').val($('<textarea/>').html(infos['description']).text());

			// Modifications : état.
			$('#edit_status option[value="' + (infos['activated'] ? 1 : 0) + '"]')
				.attr('selected', true)
				.prop('selected', true);
			$('#edit_reset_item_pubdt').prop('checked', false);
			change_reset_item_pubdt(infos['activated'], '#edit_reset_item_pubdt');

			// Construction des listes de catégories.
			if ($('#group_move option').length)
			{
				$('#edit_category_parent').html(
					$('#group_move').html().replace(/(<option[^>]+id=")m/g, '$1o')
				);
			}
			else
			{
				var html = get_select_categories('category');
				$('#edit_category_parent').html(html);
				$('#group_move').html(html.replace(/(<option[^>]+id=")o/g, '$1m'));
			}

			// Modifications : catégorie parente.
			var parent = $('#edit_category_parent option[value="' + infos['parent_id'] + '"]');
			if (parent.length)
			{
				parent
					.attr('id', parent.attr('id').replace('o', 'oc'))
					.attr('selected', true)
					.prop('selected', true);
			}

			// Modifications : propriétaire.
			$('#edit_owner option[value="' + infos['user_id'] + '"]')
				.attr('selected', true)
				.prop('selected', true);

			// Modifications : nombre de visites à zéro.
			$('#edit_reset_hits').prop('checked', false);

			// Modifications : mot de passe.
			$('label[for="edit_password"]').text(
				infos['password_parent'] ? l10n_password_required : l10n_password
			);
			$('#edit_password').val(infos['password']);

			// Modifications : réglages, permissions.
			$('#edit_allow_comments')
				.prop('disabled', infos['parent_commentable'] ? false : true)
				.prop('checked', infos['commentable'] ? true : false);
			$('#edit_allow_create')
				.prop('disabled', infos['parent_creatable'] ? false : true)
				.prop('checked', infos['creatable'] ? true : false);
			$('#edit_allow_download')
				.prop('disabled', infos['parent_downloadable'] ? false : true)
				.prop('checked', infos['downloadable'] ? true : false);
			$('#edit_allow_upload')
				.prop('disabled', infos['parent_uploadable'] ? false : true)
				.prop('checked', infos['uploadable'] ? true : false);
			$('#edit_allow_votes')
				.prop('disabled', infos['parent_votable'] ? false : true)
				.prop('checked', infos['votable'] ? true : false);
			if (infos['type'] == 'album')
			{
				$('#edit_allow_create').parent().hide();
			}
			else
			{
				$('#edit_allow_create').parent().show();
				$('#edit_allow_create')
					.prop('disabled', infos['parent_creatable'] ? false : true)
					.prop('checked', infos['creatable'] ? true : false);
			}

			// Modifications : réglages, critères de tri.
			$('#edit_sort_' + infos['type']).show();
			$('#edit_sort_' + (infos['type'] == 'album' ? 'category' : 'album')).hide();
			for (var i = 1; i < 4; i++)
			{
				$('#edit_sort_' + infos['type']
					+ ' select#edit_' + infos['type'] + '_sortby_' + i
					+ ' option[value="' + infos['sortby_' + i] + '"]')
					.attr('selected', true)
					.prop('selected', true);
				$('#edit_sort_' + infos['type']
					+ ' select#edit_' + infos['type'] + '_orderby_' + i
					+ ' option[value="' + infos['orderby_' + i] + '"]')
					.attr('selected', true)
					.prop('selected', true);
			}

			// Modifications : géolocalisation.
			geolocationItem(true);

			// Modifications : suppression.
			$('#obj_panel_delete input')
				.val(infos['type'] == 'album' ? l10n_delete_album : l10n_delete_category);

			return;
		}

		// Aperçu.
		var source_item = infos['file_source'];
		var source_preview = $(id + ' img').attr('src');
		var width = $(id + ' img').attr('data-preview-width')
			|| infos['preview_size']['w'] || 400;
		var height = $(id + ' img').attr('data-preview-height')
			|| infos['preview_size']['h'] || 227;
		if (infos['type'] == 'video')
		{
			var video = $('#obj_panel_preview video');
			if (!video.length
			  || video.attr('data-video-id') != selectedId
			  || !video.attr('poster').match(source_preview
				.replace(/^.+?(\d+\-[0-9a-z]{32})\.[a-z]{3,4}$/, '$1')))
			{
				var attributes = 'data-video-id="' + selectedId + '"'
					+ ' width="' + width + '" height="' + height + '"'
					+ ' controls poster="' + source_preview + '"';
				html += '<video ' + attributes + '>';
				html += '<source src="' + source_item + '&' + Math.random()
					+ '" type="' + infos['type_mime'] + '">';
				html += '</video>';
				$('#obj_panel_preview div:first').empty().html(html);
				$('#obj_panel_preview div:first video').prop('volume', 0.5);
			}
		}
		else
		{
			html += '<img data-src="' + source_item + '" width="' + width
				+ '" height="' + height + '" src="' + source_preview + '">';
			$('#obj_panel_preview div:first').empty().html(html);
		}
		$('#obj_panel_preview p').empty().html(infos['title']);

		// Aperçu : icône de l'onglet.
		var icon = $('#obj_panel_infos .obj_panel_submenu li:first img');
		icon.attr('src', icon.attr('src').replace(/(image|video).png$/, infos['type'] + '.png'));

		// Lien vers la galerie.
		if (infos['gallery_link'])
		{
			link = '<a title="' + l10n_gallery_link + '" class="obj_gallery_link"';
			link += ' href="' + infos['gallery_link'] + '"></a>';
			$('#obj_panel_preview h4').append(link);
		}
		else
		{
			$('#obj_panel_preview .obj_gallery_link').remove();
		}

		// EXIF.
		if (infos['exif'] && Object.keys(infos['exif']).length > 0)
		{
			html = '';
			for (var key of Object.keys(infos['exif']))
			{
				html += '<li>' + infos['exif'][key]['name']
					 + ' : <span>' + infos['exif'][key]['value'] + '</span></li>';
			}

			$('#obj_panel_camera .report_classic').hide();
			$('#obj_panel_camera ul').html(html).show();
		}
		else
		{
			$('#obj_panel_camera .report_classic').show();
			$('#obj_panel_camera ul').hide();
		}

		// Mot de passe.
		if (infos['password'])
		{
			if (infos['password_parent'])
			{
				link = '<a href="' + infos['password_parent_link'] + '">'
					+ infos['password_parent_name'] + '</a>';
				html = (infos['password_parent_type'] == 'album')
					? l10n_password_parent_album
					: l10n_password_parent_category;
				html = html.replace(/\%s/, link);
			}
			else
			{
				html = l10n_password;
			}
			$('#obj_panel_submenu_password').show();
			$('#obj_panel_infos_password > p').html(html);
		}
		else
		{
			$('#obj_panel_submenu_password').hide();
			$('#obj_panel_infos_password > p').html('');

			if ($('#obj_panel_submenu_password').hasClass('current'))
			{
				$('#obj_panel_submenu_password').removeClass('current');
				$('#obj_panel_infos .obj_panel_submenu li:first-child').addClass('current');
				$('#obj_panel_infos_password').hide();
				$('#obj_panel_infos .obj_panel_content:first-of-type').css('display', 'flex');
			}
		}

		// Statistiques.
		if (infos['album_link'])
		{
			html = '<a href="' + infos['album_link'] + '">' + infos['album_name'] + '</a>';
			$('#obj_panel_stats_album span').html(html);
		}
		if (infos['ip'])
		{
			$('#obj_panel_stats_ip span').text(infos['ip']);
		}
		html = '<a href="' + infos['user_link'] + '">' + infos['user_nickname'] + '</a>';
		$('#obj_panel_stats_user span').html(html);
		$('#obj_panel_stats_filetype span').text(infos['type_text']);
		$('#obj_panel_stats_filesize span').text(infos['filesize_formated']);
		$('#obj_panel_stats_crtdt span').text(infos['crtdt_formated']);
		$('#obj_panel_stats_adddt span').text(infos['adddt_formated']);
		$('#obj_panel_stats_pubdt span').text(infos['pubdt_formated']);
		$('#obj_panel_stats_expdt span').text(infos['expdt_formated']);
		$('#obj_panel_stats_hits span').text(infos['hits_formated']);
		$('#obj_panel_stats_favorites span').text(infos['favorites_formated']);
		$('#obj_panel_stats_comments span').html(infos['comments_link']
			? '<a href="' + infos['comments_link'] + '">' + infos['comments_formated'] + '</a>'
			: infos['comments_formated']);
		$('#obj_panel_stats_votes span').html(infos['votes_link']
			? '<a href="' + infos['votes_link'] + '">' + infos['votes_formated'] + '</a>'
			: infos['votes_formated']);
		$('#obj_panel_stats_rating span').text(infos['rating_formated']);

		// Statistiques : dimensions.
		var text;
		if ($(id + ' img').attr('data-width') === undefined)
		{
			if (infos['width'] > 0 && infos['height'] > 0)
			{
				text = infos['width'] + ' x ' + infos['height'] + ' ' + l10n_pixels;
			}
			else
			{
				text = '?';
			}
		}
		else
		{
			text = $(id + ' img').attr('data-width')
				+ ' x ' + $(id + ' img').attr('data-height') + ' ' + l10n_pixels;
		}
		$('#obj_panel_stats_size span').text(text);

		// Statistiques : durée.
		var duration = $(id + ' img').attr('data-duration') !== undefined
			? $(id + ' img').attr('data-duration')
			: infos['duration'];
		if (infos['type'] == 'video')
		{
			$('#obj_panel_stats_duration span').text(duration);
			$('#obj_panel_stats_duration').show();
		}
		else
		{
			$('#obj_panel_stats_duration').hide();
		}

		// Modifications : informations diverses.
		$('#edit_hits').val(infos['hits']);
		$('#edit_title').val($('<textarea/>').html(infos['title']).text());
		$('#edit_urlname').val(infos['url']);
		$('#edit_filename').val(infos['filename']);
		$('#edit_desc').val($('<textarea/>').html(infos['description']).text());

		// Modifications : tags.
		$('#edit_tags').val($('<textarea/>').html(infos['tags']).text());

		// Modifications : géolocalisation.
		geolocationItem(true);

		// Modifications : état.
		$('#edit_status option[value="' + (infos['activated'] ? 1 : 0) + '"]')
			.attr('selected', true)
			.prop('selected', true);
		$('#edit_reset_item_pubdt').prop('checked', false);
		change_reset_item_pubdt(infos['activated'], '#edit_reset_item_pubdt');

		// Construction des listes d'albums.
		if ($('#group_move option').length)
		{
			$('#edit_category_parent').html(
				$('#group_move').html().replace(/(<option[^>]+id=")m/g, '$1o')
			);
		}
		else
		{
			var html = get_select_categories('album');
			$('#edit_category_parent').html(html);
			$('#group_move').html(html.replace(/(<option[^>]+id=")o/g, '$1m'));
		}

		// Modifications : album.
		var parent = $('#edit_category_parent option[value="' + infos['cat_id'] + '"]');
		if (parent.length)
		{
			parent
				.attr('id', parent.attr('id').replace('o', 'oc'))
				.attr('selected', true)
				.prop('selected', true);
		}

		// Modifications : propriétaire.
		$('#edit_owner option[value="' + infos['user_id'] + '"]')
			.attr('selected', true)
			.prop('selected', true);

		// Modifications : dates.
		['year', 'month', 'day', 'hour', 'minute', 'second'].forEach(function(dt)
		{
			['crtdt', 'expdt', 'pubdt'].forEach(function(col)
			{
				var i = infos[col + '_' + dt];
				if (i !== '' && dt != 'year')
				{
					i = ('0' + i).slice(-2);
				}
				$('#edit_' + col + ' .dt_' + dt).val(i);
			});
		});

		// Modifications : réglages.
		$('#edit_allow_comments')
			.prop('disabled', infos['parent_commentable'] ? false : true)
			.prop('checked', infos['commentable'] ? true : false);
		$('#edit_allow_votes')
			.prop('disabled', infos['parent_votable'] ? false : true)
			.prop('checked', infos['votable'] ? true : false);
		$('#edit_allow_download')
			.prop('disabled', infos['parent_downloadable'] ? false : true)
			.prop('checked', infos['downloadable'] ? true : false);

		// Modifications : vignette des catégories parentes.
		if (infos.cat_parents)
		{
			var html = '';
			for (var i = 0; i < infos.cat_parents.length; i++)
			{
				if (['album', 'category'].includes(infos.cat_parents[i].cat_type))
				{
					var cat_id = infos.cat_parents[i].cat_id;
					html += '<p class="field">';
					html += '<input';
					if (infos.cat_parents[i].thumb_id == selectedId)
					{
						html += ' checked';
					}
					html += ' id="edit_thumb_' + cat_id + '" name="' + cat_id + '" type="checkbox">';
					html += "\n";
					html += '<label for="edit_thumb_' + cat_id + '">'
						+ infos.cat_parents[i].cat_name + '</label>';
					html += '</p>';
				}
			}
			$('#obj_panel_thumb form div').empty().html(html);
		}
	}

	/**
	 * Indique si une requête Ajax est active.
	 *
	 * @param bool status
	 *
	 * @return void
	 */
	function setAjaxStatus(status)
	{
		if (status && ajaxRequest)
		{
			ajaxRequest.abort();
		}
		ajaxActive = status;
		$('#obj_panel input[type="submit"]').prop('disabled', status);
	}

	/**
	 * Mise à jour d'une catégorie.
	 *
	 * @return void
	 */
	function updateCategory()
	{
		// Général.
		$('#obj_panel_general input[type="submit"]').click(function()
		{
			var dest_id = $('#edit_category_parent').val();
			ajaxUpdate(selectedId, {
				status: $('#edit_status').val(),
				reset_item_pubdt: $('#edit_reset_item_pubdt').prop('checked') ? 1 : 0,
			    parent: dest_id,
				owner: $('#edit_owner').val(),
			    reset_hits: $('#edit_reset_hits').prop('checked') ? 1 : 0
			}, $('#edit_category_parent option[id*="c"]').val() != dest_id);

			return false;
		});

		// Édition.
		$('#obj_panel_edit input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				cat_name: $('#edit_title').val(),
				cat_url: $('#edit_urlname').val(),
				cat_path: $('#edit_dirname').val(),
				cat_desc: $('#edit_desc').val()
			});

			return false;
		});

		// Mot de passe.
		$('#obj_panel_password input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				password_id: $('#edit_password').val()
			});

			return false;
		});

		// Réglages.
		$('#obj_panel_settings input[type="submit"]').click(function()
		{
			var type = itemsInfos[selectedId]['type'];

			ajaxUpdate(selectedId, {
				cat_commentable: $('#edit_allow_comments').prop('checked') ? 1 : 0,
				cat_creatable: $('#edit_allow_create').prop('checked') ? 1 : 0,
				cat_downloadable: $('#edit_allow_download').prop('checked') ? 1 : 0,
				cat_votable: $('#edit_allow_votes').prop('checked') ? 1 : 0,
				cat_uploadable: $('#edit_allow_upload').prop('checked') ? 1 : 0,
				parent_commentable: $('#edit_allow_comments').prop('disabled') ? 0 : 1,
				parent_creatable: $('#edit_allow_create').prop('disabled') ? 0 : 1,
				parent_downloadable: $('#edit_allow_download').prop('disabled') ? 0 : 1,
				parent_votable: $('#edit_allow_votes').prop('disabled') ? 0 : 1,
				parent_uploadable: $('#edit_allow_upload').prop('disabled') ? 0 : 1,
				sortby_1: $('#edit_' + type + '_sortby_1').val(),
				sortby_2: $('#edit_' + type + '_sortby_2').val(),
				sortby_3: $('#edit_' + type + '_sortby_3').val(),
				orderby_1: $('#edit_' + type + '_orderby_1').val(),
				orderby_2: $('#edit_' + type + '_orderby_2').val(),
				orderby_3: $('#edit_' + type + '_orderby_3').val()
			});

			return false;
		});

		// Vignette.
		$('#obj_panel_thumb input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				thumb_new: $('#edit_thumb_new').val(),
				thumb_new_subcats: $('#edit_thumb_new_subcats').prop('checked') ? 1 : 0
			});

			return false;
		});

		// Géolocalisation.
		$('#obj_panel_map input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				latitude: $('#geolocation_latitude').val(),
				longitude: $('#geolocation_longitude').val()
			});

			return false;
		});

		// Suppression.
		$('#obj_panel_delete input[type="submit"]').click(function()
		{
			// Message de confirmation.
			var cnfrm = itemsInfos[selectedId]['type'] == 'album'
				? l10n_confirm_delete_album
				: l10n_confirm_delete_category;
			if (confirm(cnfrm))
			{
				ajaxUpdate(selectedId, {delete: 1}, true);
			}

			return false;
		});
	}

	/**
	 * Mise à jour d'une sélection de catégories.
	 *
	 * @return void
	 */
	function updateGroupCategories()
	{
		// Informations.
		$('#obj_panel_group_edit input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				cat_name: $('#group_edit_title').val(),
				cat_url: $('#group_edit_urlname').val(),
				cat_path: $('#group_edit_dirname').val(),
				cat_desc: $('#group_edit_desc').val()
			});

			return false;
		});

		// État.
		$('#obj_panel_group_status input[type="submit"]').click(function()
		{
			var reset_item_pubdt = 0;
			var status = $('#group_status').val();
			if (status == 2)
			{
				reset_item_pubdt = 1;
				status = 1;
			}
			ajaxUpdate(selectedGroupId, {
				reset_item_pubdt: reset_item_pubdt,
				status: status
			});

			return false;
		});

		// Déplacement.
		$('#obj_panel_group_move input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				parent: $('#group_move').val()
			}, true);

			return false;
		});

		// Propriétaire.
		$('#obj_panel_group_owner input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				owner: $('#group_owner').val()
			});

			return false;
		});

		// Nombre de vues.
		$('#obj_panel_group_views input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				reset_hits: $('#group_reset_hits').prop('checked') ? 1 : 0
			});

			return false;
		});

		// Vignette.
		$('#obj_panel_group_thumb input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				thumb_new: $('#group_thumb_new').val(),
				thumb_new_subcats: $('#group_thumb_new_subcats').prop('checked') ? 1 : 0
			});

			return false;
		});

		// Géolocalisation.
		$('#obj_panel_group_map input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				latitude: $('#group_geolocation_latitude').val(),
				longitude: $('#group_geolocation_longitude').val()
			});

			return false;
		});

		// Suppression.
		$('#obj_panel_group_delete input[type="submit"]').click(function()
		{
			// Message de confirmation.
			if (confirm(l10n_confirm_group_delete))
			{
				ajaxUpdate(selectedGroupId, {delete: 1}, true);
			}

			return false;
		});
	}

	/**
	 * Mise à jour d'une sélection de fichiers.
	 *
	 * @return void
	 */
	function updateGroupItems()
	{
		// Informations.
		$('#obj_panel_group_edit input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				item_name: $('#group_edit_title').val(),
				item_url: $('#group_edit_urlname').val(),
				item_path: $('#group_edit_filename').val(),
				item_desc: $('#group_edit_desc').val()
			});

			return false;
		});

		// Dates.
		$('#obj_panel_group_dates input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				item_crtdt_new: $('#group_edit_crtdt_new').prop('checked') ? 1 : 0,
				item_crtdt: {
					day: $('#group_edit_crtdt .dt_day').val(),
					month: $('#group_edit_crtdt .dt_month').val(),
					year: $('#group_edit_crtdt .dt_year').val(),
					hour: $('#group_edit_crtdt .dt_hour').val(),
					minute: $('#group_edit_crtdt .dt_minute').val(),
					second: $('#group_edit_crtdt .dt_second').val()
				},
				item_pubdt_new: $('#group_edit_pubdt_new').prop('checked') ? 1 : 0,
				item_pubdt: {
					day: $('#group_edit_pubdt .dt_day').val(),
					month: $('#group_edit_pubdt .dt_month').val(),
					year: $('#group_edit_pubdt .dt_year').val(),
					hour: $('#group_edit_pubdt .dt_hour').val(),
					minute: $('#group_edit_pubdt .dt_minute').val(),
					second: $('#group_edit_pubdt .dt_second').val()
				},
				item_expdt_new: $('#group_edit_expdt_new').prop('checked') ? 1 : 0,
				item_expdt: {
					day: $('#group_edit_expdt .dt_day').val(),
					month: $('#group_edit_expdt .dt_month').val(),
					year: $('#group_edit_expdt .dt_year').val(),
					hour: $('#group_edit_expdt .dt_hour').val(),
					minute: $('#group_edit_expdt .dt_minute').val(),
					second: $('#group_edit_expdt .dt_second').val()
				}
			});

			return false;
		});

		// Tags.
		$('#group_edit_tags_delete_all').change(function()
		{
			if ($(this).is(':checked'))
			{
				$('#group_edit_tags_delete').parent().addClass('disabled');
				$('#group_edit_tags_delete').parent().find('a').hide();
				$('#group_edit_tags_delete').prop('disabled', true);
			}
			else
			{
				$('#group_edit_tags_delete').parent().removeClass('disabled');
				$('#group_edit_tags_delete').parent().find('a').show();
				$('#group_edit_tags_delete').prop('disabled', false);
			}
		});
		$('#obj_panel_group_tags input[type="submit"]').click(function()
		{
			var delete_all = $('#group_edit_tags_delete_all').prop('checked') ? 1 : 0;

			// Message de confirmation.
			if (delete_all && !confirm(l10n_confirm_group_tags_delete))
			{
				return false;
			}

			ajaxUpdate(selectedGroupId, {
				tags_add: $('#group_edit_tags_add').val(),
				tags_delete: $('#group_edit_tags_delete').val(),
				tags_delete_all: delete_all
			});

			return false;
		});
		$('#obj_panel_group_tags input[type="reset"]').click(function()
		{
			var e = $('#group_edit_tags_delete_all');
			if (e.is(':checked'))
			{
				e.click();
			}
		});

		// État.
		$('#obj_panel_group_status input[type="submit"]').click(function()
		{
			var reset_item_pubdt = 0;
			var status = $('#group_status').val();
			if (status == 2)
			{
				reset_item_pubdt = 1;
				status = 1;
			}
			ajaxUpdate(selectedGroupId, {
				reset_item_pubdt: reset_item_pubdt,
				status: status
			});

			return false;
		});

		// Déplacement.
		$('#obj_panel_group_move input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, { parent: $('#group_move').val() }, true);

			return false;
		});

		// Nombre de vues.
		$('#obj_panel_group_views input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				views: $('#group_views').val()
			});

			return false;
		});

		// Propriétaire.
		$('#obj_panel_group_owner input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				owner: $('#group_owner').val()
			});

			return false;
		});

		// Géolocalisation.
		$('#obj_panel_group_map input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedGroupId, {
				latitude: $('#group_geolocation_latitude').val(),
				longitude: $('#group_geolocation_longitude').val()
			});

			return false;
		});

		// Mise à jour.
		$('#obj_panel_group_update input[type="submit"]').click(function()
		{
			switch ($('#obj_panel_group_update select').val())
			{
				case 'update' :
					ajaxUpdate(selectedGroupId, {update: 1});
					break;

				case 'delete_resized' :
					ajaxUpdate(selectedGroupId, {delete_resized: 1});
					break;
			}

			return false;
		});

		// Téléchargement.
		$('#obj_panel_group_download input[type="submit"]').click(function()
		{
			$.ajax({
				type: 'POST',
				url: gallery_path + '/ajax.php',
				data:
				{
					anticsrf: anticsrf,
					section: 'grid-update-group-' + section,
					id: selectedGroupId.join(','),
					params: {download: 1}
				},
				xhrFields:
				{
					responseType: 'blob'
				},
				success: function(blob, status, xhr)
				{
					var filename = '';
					var disposition = xhr.getResponseHeader('Content-Disposition');
					if (disposition && disposition.indexOf('attachment') !== -1)
					{
						var matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(disposition);
						if (matches != null && matches[1])
						{
							filename = matches[1].replace(/['"]/g, '');
						}
					}
					if (typeof window.navigator.msSaveBlob !== 'undefined')
					{
						window.navigator.msSaveBlob(blob, filename);
					}
					else
					{
						var URL = window.URL || window.webkitURL;
						var download_url = URL.createObjectURL(blob);
						if (filename)
						{
							var a = document.createElement('a');
							if (typeof a.download === 'undefined')
							{
								window.location.href = download_url;
							}
							else
							{
								a.href = download_url;
								a.download = filename;
								document.body.appendChild(a);
								a.click();
							}
						}
						else
						{
							window.location.href = download_url;
						}
						setTimeout(function () { URL.revokeObjectURL(download_url); }, 100);
					}
				}
			});

			return false;
		});

		// Suppression.
		$('#obj_panel_group_delete input[type="submit"]').click(function()
		{
			// Message de confirmation.
			if (confirm(l10n_confirm_group_delete))
			{
				ajaxUpdate(selectedGroupId, {delete: 1}, true);
			}

			return false;
		});
	}

	/**
	 * Mise à jour d'un fichier.
	 *
	 * @return void
	 */
	function updateItem()
	{
		// Général.
		$('#obj_panel_general input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				status: $('#edit_status').val(),
				reset_item_pubdt: $('#edit_reset_item_pubdt').prop('checked') ? 1 : 0,
			    parent: $('#edit_category_parent').val(),
			    hits: $('#edit_hits').val(),
				owner: $('#edit_owner').val()
			}, true);

			return false;
		});

		// Édition.
		$('#obj_panel_edit input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				item_name: $('#edit_title').val(),
				item_desc: $('#edit_desc').val(),
				item_url: $('#edit_urlname').val(),
				item_path: $('#edit_filename').val()
			});

			return false;
		});

		// Dates.
		$('#obj_panel_dates input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				item_crtdt: {
					day: $('#edit_crtdt .dt_day').val(),
					month: $('#edit_crtdt .dt_month').val(),
					year: $('#edit_crtdt .dt_year').val(),
					hour: $('#edit_crtdt .dt_hour').val(),
					minute: $('#edit_crtdt .dt_minute').val(),
					second: $('#edit_crtdt .dt_second').val()
				},
				item_pubdt: {
					day: $('#edit_pubdt .dt_day').val(),
					month: $('#edit_pubdt .dt_month').val(),
					year: $('#edit_pubdt .dt_year').val(),
					hour: $('#edit_pubdt .dt_hour').val(),
					minute: $('#edit_pubdt .dt_minute').val(),
					second: $('#edit_pubdt .dt_second').val()
				},
				item_expdt: {
					day: $('#edit_expdt .dt_day').val(),
					month: $('#edit_expdt .dt_month').val(),
					year: $('#edit_expdt .dt_year').val(),
					hour: $('#edit_expdt .dt_hour').val(),
					minute: $('#edit_expdt .dt_minute').val(),
					second: $('#edit_expdt .dt_second').val()
				}
			});

			return false;
		});

		// Tags.
		$('#obj_panel_tags input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				tags: $('#edit_tags').val()
			});

			return false;
		});

		// Réglages.
		$('#obj_panel_settings input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				item_commentable: $('#edit_allow_comments').prop('checked') ? 1 : 0,
				item_downloadable: $('#edit_allow_download').prop('checked') ? 1 : 0,
				item_votable: $('#edit_allow_votes').prop('checked') ? 1 : 0,
				parent_commentable: $('#edit_allow_comments').prop('disabled') ? 0 : 1,
				parent_downloadable: $('#edit_allow_download').prop('disabled') ? 0 : 1,
				parent_votable: $('#edit_allow_votes').prop('disabled') ? 0 : 1
			});

			return false;
		});

		// Vignette des catégories parentes.
		$('#obj_panel_thumb input[type="submit"]').click(function()
		{
			var thumb = {};
			$('#obj_panel_thumb input[type="checkbox"]').each(function()
			{
				thumb[$(this).attr('name')] = $(this).prop('checked') ? 1 : 0;
			});

			ajaxUpdate(selectedId, {
				thumb: thumb
			});

			return false;
		});

		// Géolocalisation.
		$('#obj_panel_map input[type="submit"]').click(function()
		{
			ajaxUpdate(selectedId, {
				latitude: $('#geolocation_latitude').val(),
				longitude: $('#geolocation_longitude').val()
			});

			return false;
		});

		// Mise à jour.
		$('#obj_panel_update input[type="submit"]').click(function()
		{
			switch ($('#obj_panel_update select').val())
			{
				case 'update' :
					ajaxUpdate(selectedId, {update: 1});
					break;

				case 'delete_resized' :
					ajaxUpdate(selectedId, {delete_resized: 1});
					break;
			}

			return false;
		});

		// Suppression.
		$('#obj_panel_delete input[type="submit"]').click(function()
		{
			// Message de confirmation.
			if (confirm(l10n_confirm_delete))
			{
				ajaxUpdate(selectedId, {delete: 1}, true);
			}

			return false;
		});
	}
};