/*
 *  Copyright 2015 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.
 */

/**
 * Singleton class defining the actions related to the plugins and workpaces tools
 * @private
 */
Ext.define('Ametys.plugins.web.site.CreateSite', {
	singleton: true,
	
	/**
	 * @private
	 * @property {Boolean} _initialized Determine if the dialog box {@link #_box} for creating site is initialized
	 */
	/**
	 * @private
	 * @property {Ext.form.Panel} _form The form panel in the dialog box {@link #_box}
	 */
	/**
	 * @private
	 * @property {Ametys.plugins.web.site.SiteTypesView} _siteTypesDv The data view for types of site
	 */
	/**
	 * @private
	 * @property {Ametys.window.DialogBox} _box The dialog box for creating site
	 */
	
	/**
	 * @private
	 * @property {String} _currentSiteType Id the current selected site type
	 */
	
	/**
	 * Open dialog box for creating a new site
	 * @param {String} siteParentId the id of parent site
	 * @param {Function} callback the callback function in case of success
	 * @param {String} callback.id The id of created site
	 * @param {String} callback.name The name of created site
	 */
	act: function (siteParentId, callback)
	{
		this._cbFn = callback;
		this._siteParentId = siteParentId;
		
		if (!this._delayedInitialize())
	        return;
		
		this._initForm();
		this._box.show();
	},
	
	/**
	 * @private
	 * Initialize the dialog box
	 */
	_delayedInitialize: function ()
	{
		if (this._initialized)
		{
			this._box.defaultButton = 'next';
			return true;
		}
		
		// Form
		this._form = Ext.create('Ext.form.Panel', {
			border: false,
			scrollable: true,
			
			defaults : {
				cls: 'ametys',
				labelWidth: 70,
				msgTarget: 'side',
				xtype: 'textfield'
			},
			
			items : [{
						xtype: 'container',
						cls: 'a-text', 
						html: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_TITLE_HINT}}"
					 },
					 {
						 xtype: 'textfield',
						 fieldLabel: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SITE_NAME}}",
						 ametysDescription: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SITE_NAME_HELP}}",
						 name: 'name',
						 itemId: 'name',
						 allowBlank: false,
						 regex: /^[a-z][a-z0-9\.\-_]*$/,
						 regexText: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SITE_NAME_REGEX_ERROR}}",
						 width: 380
					 },
					 {
						xtype: 'container',
						cls: 'a-text', 
						html: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_MODE_HINT}}"
					 },
					 {
						 xtype: 'radio',
						 boxLabel: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_MODE_EMPTY_SITE}}",
	                	 name: "mode",
	                	 inputValue: "0",
	                	 checked: true,
	                	 style: {
	                		 paddingLeft: '20px'
	                	 }
					 },
					 {
						xtype: 'container',
						cls: 'a-text-light', 
						html: "<em>{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_MODE_EMPTY_SITE_HINT}}</em>",
						style: {
	                		 paddingLeft: '40px'
	                	}
					 },
					 {
						 xtype: 'radio',
						 boxLabel: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_MODE_MODEL_SITE}}",
	                	 name: "mode",
	                	 inputValue: "1",
	                	 style: {
	                		 paddingLeft: '20px'
	                	 }
					 },
					 {
						xtype: 'container',
						cls: 'a-text-light', 
						html: "<em>{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_MODE_MODEL_SITE_HINT}}</em>",
						style: {
	                		 paddingLeft: '40px'
	                	 }
					 }
			]
		});
		
		// Sites types data view
		this._siteTypesDv = Ext.create('Ametys.plugins.web.site.SiteTypesView', {
			
			listeners: {
				'selectionchange': Ext.bind(this._onSelectSiteType, this)
			}
		});
		
		// Sites tree
		this._sitesTree = Ext.create('Ametys.web.site.SitesTree', {
			border: false,
            flex: 1,
            scrollable: true,

			listeners: {
				'selectionchange': Ext.bind(this._onSelectSite, this)
			}
		});
		
		this._box = Ext.create('Ametys.window.DialogBox', {
			title :"{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_TITLE}}",
			iconCls: 'ametysicon-world91',
			
			layout :'card',
			activeItem: 0,
			width: 450,
			minHeight: 300,
			maxHeight: 400,
			freezeHeight: true,
			
			items : [ 
			         this._form,
                     {
                        xtype: 'container',
                        items: [
	                       {
                                xtype: 'component',
		                        cls: 'a-text', 
		                        html: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SITE_TYPE_HINT}}"
                           },
                           this._siteTypesDv
                        ]
                     },
                     {
                        xtype: 'container',
                        layout: {
                            type: 'vbox',
                            align: 'stretch'
                        },

                        items: [
                           {
                                xtype: 'component',
                                cls: 'a-text', 
                                html: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SITE_MODEL_HINT}}"
                           },
                           this._sitesTree
                        ]
                     }
			         
			],
			
			defaultFocus: 'name',
			closeAction: 'hide',
			
			referenceHolder: true,
			defaultButton: 'next',
			
			buttons : [{
				itemId: 'prev-btn',
				text :"{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_PREV_BUTTON}}",
				handler : Ext.bind(this._navHandler, this, [0]),
				disabled: true
			}, {
				reference: 'next',
				itemId: 'next-btn',
				text :"{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_NEXT_BUTTON}}",
				handler : Ext.bind(this._navHandler, this, [1]),
				disabled: false
			}, {
				reference: 'validate',
				itemId: 'ok-btn',
				text :"{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_OK}}",
				handler : Ext.bind(this._ok, this),
				disabled: true
			}, {
				text :"{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_CANCEL}}",
				handler : function () {this._box.hide();},
				scope: this
			}]
		});
		
		this._initialized = true;
		
		return true;
	},
	
	/**
	 * Listener on site type selection
	 * @param {Ext.selection.Model} dv The data view
	 * @param {Ext.data.Model[]} selections The selected types
	 */
	_onSelectSiteType: function (dv, selections)
	{
		this._currentSiteType = selections.length > 0 ? selections[0].get('id') : null;
		this._box.down("button[itemId='ok-btn']").setDisabled(selections.length == 0);
	},
	
	/**
	 * Listener on site selection
	 * @param {Ext.selection.Model} sm The selection model
	 * @param {Ext.data.Model[]} selected The selected records
	 */
	_onSelectSite: function (sm, selected)
	{
		this._box.down("button[itemId='ok-btn']").setDisabled(selected.length == 0);
	},
	
	/**
	 * @private
	 * Handle navigation on dialog box
	 * @param {Number} index The index of navigation button
	 */
	_navHandler: function (index)
	{
		if (index == 1)
		{
			if (!this._form.getForm().isValid())
			{
				return;
			}
			
			var mode = this._form.getForm().findField("mode").getGroupValue();
			index += parseInt(mode);
		}
		
		this._box.getLayout().setActiveItem(index);
		
		this._box.down("button[itemId='prev-btn']").setDisabled(index==0);
		this._box.down("button[itemId='next-btn']").setDisabled(index==1 || index==2);
		
		this._sitesTree.getSelectionModel().deselectAll();
		this._sitesTree.getStore().load();
		this._siteTypesDv.getSelectionModel().deselectAll();

		if (index == 1)
		{
			this._siteTypesDv.getStore().load({
				scope: this,
				callback: Ext.bind(this._selectAndFocusFirstSite, this)
			});
			this._box.defaultButton = 'validate';
		}
		else if (index == 0)
		{
			this._box.defaultButton = 'next';
		}
	},
	
	/**
	 * @private
	 * Select and focus the first site (if any) in the view
	 */
	_selectAndFocusFirstSite: function()
	{
		var firstSiteRecord = this._siteTypesDv.getStore().getAt(0);
		if (firstSiteRecord)
		{
			this._siteTypesDv.select(firstSiteRecord);
			var firstSiteNode = this._siteTypesDv.getNode(firstSiteRecord);
			firstSiteNode.click();
		}
	},
	
	/**
	 * @private
	 * Initialize form
	 */
	_initForm: function ()
	{
		this._box.getLayout().setActiveItem(0);
		
		var form = this._form.getForm();
		
		form.findField('name').setValue('');
		form.findField('name').clearInvalid();
		form.findField('mode').setValue("0");
		
		this._box.down("button[itemId='prev-btn']").setDisabled(true);
		this._box.down("button[itemId='next-btn']").setDisabled(false);
		this._box.down("button[itemId='ok-btn']").setDisabled(true);
		
		this._sitesTree.getSelectionModel().deselectAll();
		this._siteTypesDv.getSelectionModel().deselectAll();
		
		this._currentSiteType = null;
	},
	
	/**
	 * @private
	 * Validates the dialog box clikinf on 'Ok ' button 
	 */
	_ok: function ()
	{
		var form = this._form.getForm();
		
		var siteName = form.findField('name').getValue();
		var mode = parseInt(form.findField("mode").getGroupValue());
		
		if (mode == 0)
		{
			var siteType = this._siteTypesDv.getSelectionModel().getSelection()[0];
			if (siteType != null)
			{
				// Create empty site
				Ametys.data.ServerComm.callMethod({
					role: "org.ametys.web.repository.site.SiteDAO",
					methodName: "createSite",
					parameters: [this._siteParentId, siteName, siteType.getId(), false],
					callback: {
						scope: this,
						handler: this._createSiteCb
					},
					errorMessage: {
						category: this.self.getName(),
						msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SAVE_ERROR}}"
					},
					waitMessage: {
						msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_WAIT_MSG}}",
						target: this._box
					}
				});
			}
		}
		else
		{
			var site = this._sitesTree.getSelectionModel().getSelection()[0];
			if (site != null)
			{
				// Create a site by copy
				Ametys.data.ServerComm.callMethod({
					role: "org.ametys.web.repository.site.SiteDAO",
					methodName: "copySite",
					parameters: [this._siteParentId, siteName, site.getId()],
					callback: {
						scope: this,
						handler: this._createSiteCb
					},
					errorMessage: {
						category: this.self.getName(),
						msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_SAVE_ERROR}}"
					},
					waitMessage:  "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_WAIT_MSG}}"
				});
			}
		}
	},
	
	/**
	 * @private
	 * Callback function called after creating a site
	 * @param {Object} response The server response
	 * @param {Object} args The callback arguments
	 * 
	 */
	_createSiteCb: function (response, args)
	{
		if (response['invalid-name'])
		{
			Ametys.Msg.show({
	    		title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_TITLE}}",
	    		msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_FORBIDDEN_NAME}} '" + response.name + "'",
	    		buttons: Ext.Msg.OK,
	    		icon: Ext.MessageBox.ERROR
	    	});
		}
		else if (response['already-exists'])
		{
			Ametys.Msg.show({
	    		title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_DIALOG_TITLE}}",
	    		msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_HELPER_CREATESITE_ALREADY_EXISTS}} '" + response.name + "'",
	    		buttons: Ext.Msg.OK,
	    		icon: Ext.MessageBox.ERROR
	    	});
		}
		else
		{
			this._box.hide();
			this._cbFn (response.id, response.name, response.parentId);
		}
	}
	
});