/*
 *  Copyright 2013 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
 
/**
 * This class is a singleton to handle actions on files
 */
Ext.define('Ametys.explorer.resources.actions.File', {
	singleton: true,
	
	// ------------------------------------------------ //
	//						ADD							//
	// ------------------------------------------------ //
	/**
	 * Upload a new file
	 * @param {String} parentID The id of parent folder
	 * @param {Function} callback The callback function called when the file was uploaded. Has the following parameters:
	 * {String} callback.id The id of the new resource
	 * @param {String} callback.parentID The id of parent folder
	 * @param {Boolean} callback.reload true if a reload is needed.
	 * @param {Object} scope the callback scope
	 */
	add: function (parentID, callback, scope)
	{
		Ametys.explorer.resources.helper.ResourceUpload.open(parentID, null, Ext.bind(this._addCb, this, [callback, scope], true));
	},
	
	/**
	 * @private
	 * Callback function called after #add is processed
     * @param {Object[]} files The files
	 * @param {String} files.id The id of the new resource
	 * @param {String} files.name The name of the new resource
	 * @param {Boolean} files.reload true if a reload is needed.
	 * @param {String} parentID The id of parent folder
     * @param {Boolean} unzip True if the file was unziped on the server
	 * @param {Function} callback The callback function
	 * @param {String} callback.id The id of the new resource
	 * @param {String} callback.parentID The id of parent folder
	 * @param {String} callback.reload true if a reload is needed.
	 * @param {Object} scope the callback scope
	 */
	_addCb: function(files, parentID, reload, unzip, callback, scope)
	{
		var callback = callback || Ext.emptyFn,
			scope = scope || this;
		
		for (let file of files)
		{
            this._addCbNotifyAndSendMessage(file.id, file.name, parentID, reload);
        }
		
		// callback
		callback.apply(scope, [files, parentID, reload, unzip]);
	},
	
	/**
     * @private
     * Callback function called after #add is processed
     * @param {String} id The id of the new resource
     * @param {String} name The name of the new resource
     * @param {String} parentID The id of parent folder
     * @param {Boolean} reload true if a reload is needed.
     * @param {Boolean} unzip True if the file was unziped on the server
     */
    _addCbNotifyAndSendMessage: function(id, name, parentID, reload)
    {
        if (reload || !id)
        {
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.MODIFIED,
                
                targets: {
                    id: Ametys.message.MessageTarget.EXPLORER_COLLECTION,
                    parameters: { ids: [parentID] }
                },
                
                parameters: {
                    major: true // request refresh
                }
            });
        }
        else
        {
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.CREATED,
                
                targets: {
                    id: Ametys.message.MessageTarget.RESOURCE,
                    parameters: { ids: [id]}
                }
            });
        }
        
        Ametys.notify({
            type: 'info',
            title: "{{i18n PLUGINS_EXPLORER_FILE_NOTIFY_ADD_LABEL}}",
            description: Ext.String.format("{{i18n PLUGINS_EXPLORER_FILE_NOTIFY_ADD_DESC}}", name),
            iconGlyph: 'ametysicon-arrow88',
            action: Ext.bind(Ametys.explorer.resources.actions.File.download, this, [id], false)
        });
    },
	
	// ------------------------------------------------ //
	//						RENAME						//
	// ------------------------------------------------ //
	/**
	 * Rename a file
	 * @param {String} id The file id to rename
	 * @param {String} oldName The old name
	 * @param {String} newName The new name
	 * @param {Function} callback The callback function
	 * @param {String} callback.id The id of the renamed file
	 * @param {String} callback.name The new file name
	 * @param {Boolean} callback.success True if the renaming succeeded
	 * @param {Object} scope the callback scope
	 */
	rename: function (id, oldName, newName, callback, scope)
	{
		var name = Ext.String.trim(newName),
			callback = Ext.isFunction(callback) ? callback : Ext.emptyFn,
			scope = scope|| this;
		
		if (name == '' || !/^[^\\/:*?"<>|]*$/.test(name))
		{
			Ametys.Msg.alert(
				"{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME}}",
				"{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME_INVALID_CHARACTERS}}"
			);  
			
			callback.apply(scope, [id, name, false]);
			return;
		}
		
		if (this._getFileExtension (oldName) != this._getFileExtension(name))
		{
			Ametys.Msg.confirm(
				"{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME}}",
				"{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME_EXTENSION}}",
				function(answer)
				{
					if (answer == 'yes')
					{
						this._doRename(id, name, callback, scope);
					}
					else
					{
						callback.apply(scope, [id, name, false]);
					}
				},
				this
			);
		}
		else
		{
			this._doRename(id, name, callback, scope);
		}	
		
		return true;
	},
	
	/**
	 * Rename a file
	 * @param {String} id The file id to rename
	 * @param {String} name The new name
	 * @param {Function} callback The callback function
	 * @param {String} callback.id The id of the renamed file
	 * @param {String} callback.name The new file name
	 * @param {Boolean} callback.success True if the renaming succeeded
	 * @param {Object} scope the callback scope
	 * @private
	 */
	_doRename: function (id, name, callback, scope)
	{
		Ametys.data.ServerComm.callMethod({
			role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO', 
			methodName: 'renameResource',
			parameters: [id, name],
			callback: {
				handler: this._renameCb,
				scope: this,
				arguments: [callback, scope]
			},
			waitMessage: true,
			errorMessage: true
		});
	},
	
	/**
	 * @private
	 * Callback of #_doRename
	 * @param {Object[]} response the server response
	 * @param {Object[]} args the callback args
	 */
	_renameCb: function(response, args)
	{
		var msg = response['message'] || null,
			id =  response['id'],
			name = response['name'];
	
		var callback = args[0] || Ext.emptyFn,
			scope = args[1] || this;
		
		
		if (msg == 'locked')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME_LOCKED}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			
			callback.apply(scope, [id, name, false]);
		}
		else if (msg == 'already-exist')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_RENAME_ALREADY_EXISTS}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			
			callback.apply(scope, [id, name, false]);
		}
		else
		{
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.MODIFIED,
				
				targets: {
					id: Ametys.message.MessageTarget.RESOURCE,
					parameters: { ids: [id]}
				}
			});
			
			callback.apply(scope, [id, name, true]);
		}
	},
	
	/**
	 * Get the extension of a file
	 * @param {String} fileName The file name
	 * @private
	 */
	_getFileExtension: function(fileName)
	{
		var ext = '';
	
		var dotPos = fileName.lastIndexOf('.');
		if (dotPos > -1)
		{
			ext = fileName.substring(dotPos + 1).toLowerCase();
		}
	
		return ext;
	},
	
	// ------------------------------------------------ //
	//						DELETE						//
	// ------------------------------------------------ //
	/**
	 * Delete a file
	 * @param {String} parentID The folder parent id
	 * @param {String[]} ids The file id's to delete
	 * @param {Function} callback The callback function
	 * @param {String} callback.parentID The folder parent id
	 * @param {String[]} callback.ids The id's of the deleted resources
	 * @param {Boolean} callback.success True if the renaming succeeded
	 * @param {Object} scope the callback scope
	 */
	remove: function(parentID, ids, callback, scope)
	{
		Ametys.Msg.confirm("{{i18n PLUGINS_EXPLORER_FILE_HANDLE_DELETE}}", 
			"{{i18n PLUGINS_EXPLORER_FILE_HANDLE_DELETE_CONFIRM}}", 
			function(btn) {
				this._doRemove(btn, parentID, ids, callback, scope)
			},
			this
		);
	},
	
	/**
	 * Internal callback for the #remove function
	 * @param {String} answer The id of the button pressed. See {@link Ext.window.MessageBox#method-show}
	 * @param {String} parentID The folder parent id
	 * @param {String[]} ids The file id's to delete
	 * @param {Function} callback The callback function
	 * @param {String} callback.parentID The folder parent id
	 * @param {String[]} callback.ids id's of the removed resources
	 * @param {Boolean} callback.success 
	 * @param {Object} scope the callback scope
	 * @private
	 */
	_doRemove: function(answer, parentID, ids, callback, scope)
	{
		var callback = Ext.isFunction(callback) ? callback : Ext.emptyFn,
			scope = scope|| this;
		
		if (answer == 'yes')
		{
			var me = this; 
			
			// Sending the deleting message to store target info
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.DELETING,
				
				targets: {
					id: Ametys.message.MessageTarget.RESOURCE,
					parameters: {ids: ids}
				},
				
				callback: function(deletingMsg) {
					
					// Effectively removing the folder
					Ametys.data.ServerComm.callMethod({
						role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO', 
						methodName: 'deleteObject',
						parameters: [ids],
						callback: {
							handler: me._removeCb,
							scope: me,
							arguments: [callback, scope, deletingMsg.getTargets(), parentID, ids]
						},
						waitMessage: true,
						errorMessage: true
					});
				}
			});
		}
		else
		{
			// callback
			callback.apply(scope, [parentID, ids, false]);
		}
	},
	
	/**
	 * @private
	 * Callback of #_doRemove
	 * @param {Object[]} response the server response
	 * @param {Object[]} args the callback args
	 */
	_removeCb: function(response, args)
	{
		var msg = response['message'] || null;
		
		var callback = args[0] || Ext.emptyFn,
			scope = args[1] || this,
			targets = args[2],
			parentID = args[3],
			ids = args[4];
		
		if (msg == 'locked')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_DELETE}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_DELETE_LOCKED}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			
			// callback
			callback.apply(scope, [parentID, ids, false]);
		}
		else
		{
			// Sending the deleted message with stored targets
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.DELETED,
                // FIXME this should be determined based on the response
                parameters: {trashed: true},
				targets: targets
			});
			
			// callback
			callback.apply(scope, [parentID, ids, true]);
		}
	},
	
	// ------------------------------------------------ //
	//						DOWNLOAD					//
	// ------------------------------------------------ //
	/**
	 * Download a file
	 * @param {String} id The id of the file to download
	 */
	download: function(id)
	{
		var args = {
            'id': id,
            'download': "true"
        }
        Ametys.openWindow(Ametys.getPluginDirectPrefix('explorer') + '/resource', args);
	},
	
	
	// ------------------------------------------------ //
	//						EXPORT						//
	// ------------------------------------------------ //
	/**
	 * Export to ZIP archive
	 * @param {String} folder The folder id.
	 * @param {String[]} files The file ids to export
	 */
	exportZIP: function(folder, files)
	{
		var args = "id=" + folder;
		for (var i = 0; i < files.length; i++)
		{
			args += "&file=" + encodeURIComponent(files[i]);
		}
		window.open(Ametys.getPluginDirectPrefix('explorer') + '/files/archive.zip?' + args)
	},
	
	/**
	 * Export to RDF format
	 * _Currently unused : see EXPLORER-108_
	 * @param {String} id The file id to export
	 */
	exportRDF: function(id)
	{
		var args = { 'id': encodeURIComponent(id)};
        Ametys.openWindow(Ametys.getPluginDirectPrefix('explorer') + '/resource/rdf', args)
	},
	
	// ------------------------------------------------ //
	//						HISTORY						//
	// ------------------------------------------------ //
	/**
	 * Show the history of a file
	 * @param {String} id The id of the resource
	 * @param {String} parentId The id of the parent resource. Only used as an argument for the callback. Can be null.
	 * @param {Boolean} allowRestore True to enable the restore action
	 * @param {Function} callback The callback function called when an old version has been restored. Has the following parameters
	 * @param {String} callback.id The id of restored resource
	 * @param {String} callback.parentId The id of the parent resource
	 * @param {Object} scope the callback scope
	 */
	showHistory: function (id, parentId, allowRestore, callback, scope)
	{
		Ametys.explorer.resources.helper.History.open(id, parentId, allowRestore, Ext.bind(this._showHistoryCb, this, [callback, scope], true), this);
	},
	
	/**
	 * @private
	 * Callback called when an old version is restored.
	 * @param {String} id The id of restored resource
	 * @param {String} parentId The id of the parent resource
	 * @param {Function} callback The callback function
	 * @param {String} callback.id The id of restored resource
	 * @param {String} callback.parentId The id of the parent resource
	 * @param {Object} scope the callback scope
	 */
	_showHistoryCb: function(id, parentId, callback, scope)
	{
		var callback = Ext.isFunction(callback) ? callback : Ext.emptyFn,
			scope = scope|| this;
		
		// Sending modified message
		Ext.create("Ametys.message.Message", {
			type: Ametys.message.Message.MODIFIED,
			
			targets: {
				id: Ametys.message.MessageTarget.RESOURCE,
				parameters: { ids: [id]}
			},
			
			parameters: {
				major: true
			}
		});
		
		// callback
		callback.apply(scope, [id, parentId]);
	},
	
	// ------------------------------------------------ //
	//					DUBLIN CORE						//
	// ------------------------------------------------ //
	/**
	 * Edit the dublin core metadata. Open a pop up.
	 * @param {String} id The id of the resource
	 * @param {Function} callback The callback function called when an old version has been restored. Has the following parameters
	 * @param {String} callback.id The id of the edited resource
	 * @param {Object} scope the callback scope
	 */
	editDublinCore: function (id, callback, scope)
	{
		Ametys.explorer.resources.helper.DublinCore.open(id, Ext.bind(this._editDublinCoreCb, this, [callback, scope], true));
	},
	
	/**
	 * @private
	 * Callback function called after #editDublinCore action is processed
	 * @param {String} id The id of modified file
	 * @param {Function} callback The callback function
	 * @param {String} callback.id The id of restored resource
	 * @param {String} callback.parentId The id of the parent resource
	 * @param {Object} scope the callback scope
	 */
	_editDublinCoreCb: function (id, callback, scope)
	{
		var callback = Ext.isFunction(callback) ? callback : Ext.emptyFn,
			scope = scope|| this;
		
		Ext.create("Ametys.message.Message", {
			type: Ametys.message.Message.MODIFIED,
			
			targets: {
				id: Ametys.message.MessageTarget.RESOURCE,
				parameters: { ids: [id]}
			}
		});
		
		// callback
		callback.apply(scope, [id]);
	},
	
	// ------------------------------------------------ //
	//						SEARCH						//
	// ------------------------------------------------ //
	/**
	 * Perform a search on files
	 * @param {String} id The folder id
	 * @param {Function} callback The callback function
	 * @param {Object} callback.values set of key/value pairs representing the values of the fields of the form. See {@link Ext.form.Basic#getValues}
	 */
	search: function(id, callback)
	{
		Ametys.explorer.resources.helper.SearchResources.open (id, callback);
	},
	
	
	// ------------------------------------------------ //
	//				COPY / CUT / PASTE					//
	// ------------------------------------------------ //
	/**
	 * Cut the selected files
	 * @param {String} base The folder id to cut from
	 * @param {String[]} files The files id to move
	 */
	cut: function(base, files)
	{
		/**
		 * @private
		 * @property {String[]} _pasteFiles The id's of the current files to move or copy.
		 */
		this._pasteFiles = files;
		/**
		 * @private
		 * @property {String} _pasteMode The mode of the paste operation: 'cut' or 'copy' 
		 */
		this._pasteMode = 'cut';
		/**
		 * @private
		 * @property {String} _pasteBase The id of the parent folder.
		 */
		this._pasteBase = base;
	},
	
	/**
	 * Paste files into target folder
	 * @param {String} target The folder id to move into
	 * @param {Function} callback The callback function. See {@link #move method} for the callback args.
	 */
	paste: function(target, callback)
	{
		if (!this._pasteFiles)
		{
			return;
		}
		
		if (this._pasteMode == 'cut')
		{
			this.move(target, this._pasteFiles, callback)
		}
		else if (this._pasteMode == 'copy')
		{
			this.doCopy(target, this._pasteFiles, callback)
		}
	},

	/**
	 * Copy files to a target folder
	 * @param {String} base The folder id to copy into
	 * @param {String[]} files The files id to copy
	 */
	copy: function(base, files)
	{
		this._pasteFiles = files;
		this._pasteMode = 'copy';
		this._pasteBase = base;
	},
	
	/**
	 * Move files to a target folder
	 * @param {String} target The folder id to move into
	 * @param {String[]} files The file id's to move
	 * @param {Function} callback The callback function
	 * @param {String} callback.target The folder id to move into
	 * @param {String[]} callback.ids File ids moved effectively
	 */
	move: function(target, files, callback)
	{
		var params = {
			id: files,
			target: target
		};
		
		Ametys.data.ServerComm.callMethod({
			role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO', 
			methodName: 'moveObject',
			parameters: [files, target],
			callback: {
				handler: this._moveCb,
				scope: this,
				arguments: {
					callback: callback,
					target: target
				}
			},
			errorMessage: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_PASTE_ERROR}}"
		});
	},
	
	/**
	 * @private
	 * Callback function invoked after moving objects
	 * @param {Object} response The server result
	 * @param {String} response.message In case of error
	 * @param {String[]} response.moved-objects The ids of effective moved objects
	 * @param {String[]} response.unmoved-objects The ids of unmoved objects
     * @param {Object[]} args Additionnal arguments
     * @param {Function} [args.callback] A callback at the end
     * @param {String[]} args.callback.movedObjects The identifiers of the moved objects
     * @param {String} args.callback.target The target in #move
     * @param {String} [args.target] The target in #move
	 */
	_moveCb: function (response, args)
	{
		if (response.message && response.message == 'locked')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_PASTE}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_PASTE_LOCKED}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			return;
		}
		
		if (response.message && response.message == 'already-exist')
		{
			var unmovedObjects = response["unmoved-objects"];
			
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_PASTE}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_UNPASTE}}" + unmovedObjects.join(", ") + "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_UNPASTE_2}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.WARN
			});
		}
		
		var noRightOjects = response["noright-objects"] || [];
		if (noRightOjects.length > 0)
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_PASTE}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_CUT_NORIGHT}}" + noRightOjects.join(", "),
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
		}
					
		var movedObjects = response["moved-objects"] || [];
		if (movedObjects.length > 0)
		{
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.MOVED,
				
				targets: {
					id: Ametys.message.MessageTarget.RESOURCE,
					parameters: {ids: movedObjects}
				}
			});
		}
		
		if (Ext.isFunction(args.callback))
		{
			args.callback(args.target, movedObjects);
		}
	},
	
	/**
	 * Copy files to a target folder
	 * @param {String} target The folder id to copy into
	 * @param {String[]} files The file id's to copy
	 * @param {Function} callback The callback function
	 * @param {String} callback.target The folder id to copy into
	 * @param {String[]} callback.ids File ids copied effectively
	 */
	doCopy: function(target, files, callback)
	{
		var params = {
			id: files,
			target: target
		};
		
		Ametys.data.ServerComm.callMethod({
			role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO', 
			methodName: 'copyResource',
			parameters: [files, target],
			callback: {
				handler: this._copyCb,
				scope: this,
				arguments: {
					callback: callback,
					target: target
				}
			},
			errorMessage: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_COPY_PASTE_ERROR}}"
		});
	},
	
	/**
	 * @private
	 * Callback function invoked after copying objects
	 * @param {Object} response The server result
	 * @param {String} response.message In case of error
	 * @param {String[]} response.copied-resources The ids of effective copied resources
	 * @param {String[]} response.uncopied-resources The ids of uncopied resources
     * @param {Object[]} args Additionnal arguments
     * @param {Function} [args.callback] A callback at the end
     * @param {String[]} args.callback.copiedResources The identifiers of the copied objects
     * @param {String} args.callback.target The target in #move
     * @param {String} [args.target] The target in #move
	 */
	_copyCb: function (response, args)
	{
		if (response.message && response.message == 'locked')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_COPY_PASTE}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_COPY_PASTE_LOCKED}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			return;
		}
		
		if (response.message && response.message == 'already-exist')
		{
			var uncopiedResources = response["uncopied-resources"];
			
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_COPY_PASTE}}",
				msg: "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_COPY_UNPASTE}}" + uncopiedResources.join(", ") + "{{i18n PLUGINS_EXPLORER_FILE_HANDLE_COPY_UNPASTE_2}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.WARN
			});
		}
		
		var copiedResources = response["copied-resources"] || [];
		if (copiedResources.length > 0)
		{
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.CREATED,
				
				targets: {
					id: Ametys.message.MessageTarget.RESOURCE,
					parameters: {ids: copiedResources}
				}
			});
		}
		
		if (Ext.isFunction(args.callback))
		{
			args.callback(args.target, copiedResources);
		}
	},
	
	//------------------------------------------------------//
	//					SLIDE SHOW							//
	//------------------------------------------------------//
	/**
	 * Show the slideshow for a set of files.
	 * @param {String[]} files the file ids.
	 */
	slideshow: function(files)
	{
		var divEl = Ext.get('div-slideshow');
		if (divEl == null)
		{
			var div = document.createElement('div');
			div.id = 'div-slideshow';
			div.style.display = 'none';
			document.body.appendChild(div);
			divEl = Ext.get('div-slideshow');
		}
		else
		{ 
			divEl.dom.innerHTML = '';
		}
		
		var me = this;
		Ametys.explorer.ExplorerNodeDAO.getExplorerNodes(files, function(resources) {
			
            // Sort images by alphabetical order
            var sortedResources = Ext.Array.sort(resources, function (r1, r2){
					var v1 = r1.getProperties().name;
					var v2 = r2.getProperties().name;
					
					return Ext.String.enhancedCompare(v1, v2);
				});
            
			var rl = sortedResources.length;
			for (var i = 0; i < rl; i++)
			{
				var props = sortedResources[i].getProperties(),
					id = props.id,
					name = props.name || '';
				
				var link = document.createElement('a');
				link.id = 'div-slideshow-' + i;
				link.className = 'pirobox' + (rl == 1 ? '' : '_gall');
				link.rel = rl == 1 ? 'single' : 'gallery';
				link.href = Ametys.getPluginDirectPrefix('explorer') + "/resource?id=" + id;
				link.setAttribute('title', name);
				
				divEl.dom.appendChild(link);
			}
			
			$('.piro_html').remove();
			$('.piro_overlay').remove();
			
			$().piroBox_ext({bg_alpha : 0.5});
			
			$('#div-slideshow-0').click();
		});
	}
});