/*
 * Copyright (c) 2014
 *
 * @author Vincent Petry
 * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
 *
 * This file is licensed under the Affero General Public License version 3
 * or later.
 *
 * See the COPYING-README file.
 *
 */
/**
 * 这个文件是用来 初始化 filelist 的 相关数据
 * 本列表 采用 apps/files/ 的标准filelist 展示；
 * @returns {undefined}
 */
/* global dragOptions, folderDropOptions, OC */
(function() {

	if (!OCA.Files) {
		/**
		 * Namespace for the files app
		 * @namespace OCA.Files
		 */
		OCA.Files = {};
	}
     
	/**
	 * @namespace OCA.Files.App
	 */
	OCA.Files.App = {
		/**
		 * Navigation control
		 *
		 * @member {OCA.Files.Navigation}
		 */
		navigation: null,

		/**
		 * File list for the "All files" section.
		 *
		 * @member {OCA.Files.FileList}
		 */
		fileList: null,

		/**
		 * Backbone model for storing files preferences
		 */
		_filesConfig: null,

		/**
		 * Initializes the files app
		 */
		initialize: function() {
			this.navigation = new OCA.Files.Navigation($('#app-navigation'));
			this.$showHiddenFiles = $('input#showhiddenfilesToggle');
			var showHidden = $('#showHiddenFiles').val() === "1";
			this.$showHiddenFiles.prop('checked', showHidden);


			if ($('#fileNotFound').val() === "1") {
				OC.Notification.show(t('files', 'File could not be found'), {type: 'error'});
			}

			this._filesConfig = new OC.Backbone.Model({
				showhidden: showHidden
			});

			var urlParams = OC.Util.History.parseUrlQuery();                        
			 
			this.files = OCA.Files.Files;
                        /*加入初始化Gallery模块*/
                        Gallery.utility = new Gallery.Utility();
                       //Gallery.view = new Gallery.View();
                        Gallery.token = Gallery.utility.getPublicToken();
                        Gallery.ieVersion = Gallery.utility.getIeVersion();
                        Gallery.filesClient = new OC.Files.Client({
                                host: Gallery.utility.getWebdavHost(),
                                port: OC.getPort(),
                                root: Gallery.utility.getWebdavRoot(),
                                useHTTPS: OC.getProtocol() === 'https'
                        });
                       /*设置为同步请求 获取配置信息*/     
                       $.ajaxSettings.async = false; 
                       $.getJSON(Gallery.utility.buildGalleryUrl('config', '', {}))
                        .then(function (config) {                             
                              Gallery.config = new Gallery.Config(config);                           
                              /*设置可以上传的文件类型
                              $("#file_upload_start").attr("accept", OCA.Files.DuoFile.mediaType());*/
                        });  
                        if (!this.fileList) {
                            var fileActions = this._createFileActions();
                        
                            //window.FileList =  register recent list for sidebar section
                            this.fileList = new OCA.Files.RecentFileList(
                                   $("#app-content-document"), {
                                            dragOptions: dragOptions,
                                            folderDropOptions: folderDropOptions,
                                            fileActions: fileActions,                                            
                                            filesClient: Gallery.filesClient, //OC.Files.getClient(),                                              
                                            shown: true,
                                            multiSelectMenu: [
                                                {
							name: 'download',
							displayName:  t('files', 'Download'),
							iconClass: 'icon-download',
						},
						{
							name: 'delete',
							displayName: t('files', 'Delete'),
							iconClass: 'icon-delete',
						},
						{
							name: 'copyMove',
							displayName:  t('files', 'Move or copy'),
							iconClass: 'icon-external',
						}
						
					],
                                            enableUpload: true,
                                            config: this._filesConfig,
                                            maxChunkSize: OC.appConfig.files && OC.appConfig.files.max_chunk_size                                      
                                    }
                            );
                            var currentLocation = window.location.href.split('=')[1] || '/';
                            this.fileList._setCurrentDir(currentLocation, false);
                        }   
                      
			//OC.Plugins.attach('OCA.Files.App', this);
                       /*FileList 在 document-plugins。js 里面 初始化*/
                        window.FileList  = this.fileList;
                       // this.fileList = FileList;
                        this.files.initialize();
                        //console.log(this.fileList )
			this._setupEvents();
			// trigger URL change event handlers
			this._onPopState(urlParams);

			$('#quota.has-tooltip').tooltip({
				placement: 'top'
			});

			this._debouncedPersistShowHiddenFilesState = _.debounce(this._persistShowHiddenFilesState, 1200);

			//OCP.WhatsNew.query(); // for Xfcloud server
		},
                _createFileActions: function () {
			// inherit file actions from the files app
			var fileActions = new OCA.Files.FileActions();
			// note: not merging the legacy actions because legacy apps are not
			// compatible with the sharing overview and need to be adapted first
			fileActions.registerDefaultActions();
			fileActions.merge(OCA.Files.fileActions);

			if (!this._globalActionsInitialized) {
				// in case actions are registered later
				this._onActionsUpdated = _.bind(this._onActionsUpdated, this);
				OCA.Files.fileActions.on('setDefault.plugin-recent', this._onActionsUpdated);
				OCA.Files.fileActions.on('registerAction.plugin-recent', this._onActionsUpdated);
				this._globalActionsInitialized = true;
			}

			// when the user clicks on a folder, redirect to the corresponding
			// folder in the files app instead of opening it directly
			fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
				OCA.Files.App.setActiveView('files', {silent: true});
				var path = OC.joinPaths(context.$file.attr('data-path'), filename);
				OCA.Files.App.fileList.changeDirectory(path, true, true);
			});
			fileActions.setDefault('dir', 'Open');
			return fileActions;
		},
 
		/**
		 * Destroy the app
		 */
		destroy: function() {
			this.navigation = null;
			this.fileList.destroy();
			this.fileList = null;
			this.files = null;
			OCA.Files.fileActions.off('setDefault.app-files', this._onActionsUpdated);
			OCA.Files.fileActions.off('registerAction.app-files', this._onActionsUpdated);
			window.FileActions.off('setDefault.app-files', this._onActionsUpdated);
			window.FileActions.off('registerAction.app-files', this._onActionsUpdated);
		},

		_onActionsUpdated: function(ev) {
			// forward new action to the file list
			if (ev.action) {
				this.fileList.fileActions.registerAction(ev.action);
			} else if (ev.defaultAction) {
				this.fileList.fileActions.setDefault(
					ev.defaultAction.mime,
					ev.defaultAction.name
				);
			}
		},

		/**
		 * Returns the container of the currently visible app.
		 *
		 * @return app container
		 */
		getCurrentAppContainer: function() {
			return this.navigation.getActiveContainer();
		},

		/**
		 * Sets the currently active view
		 * @param viewId view id
		 */
		setActiveView: function(viewId, options) {
			this.navigation.setActiveItem(viewId, options);
		},

		/**
		 * Returns the view id of the currently active view
		 * @return view id
		 */
		getActiveView: function() {
			return this.navigation.getActiveItem();
		},

		/**
		 *
		 * @returns {Backbone.Model}
		 */
		getFilesConfig: function() {
			return this._filesConfig;
		},

		/**
		 * Setup events based on URL changes
		 */
		_setupEvents: function() {
			OC.Util.History.addOnPopStateHandler(_.bind(this._onPopState, this));

			// detect when app changed their current directory
			$('#app-content').delegate('>div', 'changeDirectory', _.bind(this._onDirectoryChanged, this));
			$('#app-content').delegate('>div', 'afterChangeDirectory', _.bind(this._onAfterDirectoryChanged, this));
			$('#app-content').delegate('>div', 'changeViewerMode', _.bind(this._onChangeViewerMode, this));

			$('#app-navigation').on('itemChanged', _.bind(this._onNavigationChanged, this));
			this.$showHiddenFiles.on('change', _.bind(this._onShowHiddenFilesChange, this));
		},

		/**
		 * Toggle showing hidden files according to the settings checkbox
		 *
		 * @returns {undefined}
		 */
		_onShowHiddenFilesChange: function() {
			var show = this.$showHiddenFiles.is(':checked');
			this._filesConfig.set('showhidden', show);
			this._debouncedPersistShowHiddenFilesState();
		},

		/**
		 * Persist show hidden preference on the server
		 *
		 * @returns {undefined}
		 */
		_persistShowHiddenFilesState: function() {
			var show = this._filesConfig.get('showhidden');
			$.post(OC.generateUrl('/apps/files/api/v1/showhidden'), {
				show: show
			});
		},

		/**
		 * Event handler for when the current navigation item has changed
		 */
		_onNavigationChanged: function(e) {
			var params;
			if (e && e.itemId) {
				params = {
					view: typeof e.view === 'string' && e.view !== '' ? e.view : e.itemId,
					dir: e.dir ? e.dir : '/'
				};
				this._changeUrl(params.view, params.dir);
				OC.Apps.hideAppSidebar($('.detailsView'));
				this.navigation.getActiveContainer().trigger(new $.Event('urlChanged', params));
			}
		},

		/**
		 * Event handler for when an app notified that its directory changed
		 */
		_onDirectoryChanged: function(e) {
			if (e.dir) {
				this._changeUrl(this.navigation.getActiveItem(), e.dir, e.fileId);
			}
		},

		/**
		 * Event handler for when an app notified that its directory changed
		 */
		_onAfterDirectoryChanged: function(e) {
			if (e.dir && e.fileId) {
				this._changeUrl(this.navigation.getActiveItem(), e.dir, e.fileId);
			}
		},

		/**
		 * Event handler for when an app notifies that it needs space
		 * for viewer mode.
		 */
		_onChangeViewerMode: function(e) {
			var state = !!e.viewerModeEnabled;
			if (e.viewerModeEnabled) {
				OC.Apps.hideAppSidebar($('.detailsView'));
			}
			$('#app-navigation').toggleClass('hidden', state);
			$('.app-files').toggleClass('viewer-mode no-sidebar', state);
		},

		/**
		 * Event handler for when the URL changed
		 */
		_onPopState: function(params) {
			params = _.extend({
				dir: '/',
				view: 'files'
			}, params);
			var lastId = this.navigation.getActiveItem();
			if (!this.navigation.itemExists(params.view)) {
				params.view = 'files'; 
			}
			this.navigation.setActiveItem(params.view, {silent: true});
			if (lastId !== this.navigation.getActiveItem()) {
				$("#app-content-document").trigger(new $.Event('show'));
			}
			$("#app-content-document").trigger(new $.Event('urlChanged', params));
		},

		/**
		 * Encode URL params into a string, except for the "dir" attribute
		 * that gets encoded as path where "/" is not encoded
		 *
		 * @param {Object.<string>} params
		 * @return {string} encoded params
		 */
		_makeUrlParams: function(params) {
			var dir = params.dir;
			delete params.dir;
			return 'dir=' + OC.encodePath(dir) + '&' + OC.buildQueryString(params);
		},

		/**
		 * Change the URL to point to the given dir and view
		 */
		_changeUrl: function(view, dir, fileId) {
			var params = {dir: dir};
			if (view !== 'files') {
				params.view = view;
			} else if (fileId) {
				params.fileid = fileId;
			}
			var currentParams = OC.Util.History.parseUrlQuery();
			if (currentParams.dir === params.dir && currentParams.view === params.view && currentParams.fileid !== params.fileid) {
				// if only fileid changed or was added, replace instead of push
				OC.Util.History.replaceState(this._makeUrlParams(params));
			} else {
				OC.Util.History.pushState(this._makeUrlParams(params));
			}
		}
	};
})();

$(document).ready(function() {
	// wait for other apps/extensions to register their event handlers and file actions
	// in the "ready" clause
	_.defer(function() {
		OCA.Files.App.initialize();
	});
});
