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

//------------------ Open JCR node -----------------------//
/**
 * Class managing the "Open JCR node" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.OpenJcrNode',
{
    singleton: true,
    
    /**
     * Open the corresponding JCR node.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
     */
    act: function(controller)
    {
        var target = controller.getMatchingTargets()[0];
        if (target != null)
        {
            var nodePath = target.getParameters().jcrPath;
            if (nodePath != null)
            {
                var workspaceName = Ametys.repository.RepositoryApp.getCurrentWorkspace();
                Ametys.repository.tool.NodePropertiesTool.open(nodePath, workspaceName);
            }
        }
    }
});

//------------------ ADD OBJECT -----------------------//
/**
 * Class managing the "add AmetysObject" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.AddObject',
{
    singleton: true,
    
    /**
     * @property {String} _parentId The parent object ID.
     * @private
     */
    _parentId: null,
    
    /**
     * @property {Boolean} _initialized True when the dialog is initialized.
     * @private
     */
    _initialized: false,
    
    /**
     * @property {Ext.form.Basic} _form The Basic form.
     * @private
     */
    _form: null,
    
    /**
     * @property {Ametys.window.DialogBox} box The action dialog box.
     * @private
     */
    box: null,
    
    /**
     * Show the object creation dialog after creating it if necessary.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
     */
    act: function(controller)
    {
        var target = controller.getMatchingTargets()[0];
        
        if (target != null)
        {
            this._parentId = target.getParameters().id;
            
            if (!this.delayedInitialize())
            {
                return;
            }
            
            this.box.show();
            this._initForm();
        }
    },
    
    /**
     * Create the object creation dialog.
     * @return {Boolean} True if correctly initialized.
     * @private
     */
    delayedInitialize: function()
    {
        if (this._initialized)
        {
            return true;
        }
        
        var formPanel = Ext.create('Ext.form.Panel', {
            defaultType: 'textfield',
            defaults: {
                cls: 'ametys',
                msgTarget: 'side',
                labelAlign: 'right',
                labelSeparator: '',
                labelWidth: 60,
                width: '100%'
            },
            
            border: false,
            items: [{
                xtype: 'component',
                cls: 'a-text',
                html: "{{i18n PLUGINS_REPOSITORY_ADD_AMETYS_OBJECT_BOX_HINT}}"
            }, {
                fieldLabel : "{{i18n PLUGINS_REPOSITORY_ADD_AMETYS_OBJECT_BOX_NAME_LABEL}}",
                name: 'name',
                inputWidth: 200,
                allowBlank: false
            }, {
                fieldLabel : "{{i18n PLUGINS_REPOSITORY_ADD_AMETYS_OBJECT_BOX_TYPE_LABEL}}",
                id: 'type',
                inputWidth: 200,
                allowBlank: false
            }]
        });
        
        this._form = formPanel.getForm();
        
        this.box = Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_REPOSITORY_ADD_AMETYS_OBJECT_BOX_TITLE}}",
            iconCls: "ametysicon-ametys",
            
            width: 400,
            scrollable: true,
            
            items: [ formPanel ],
            defaultFocus: 'name',
            
            closeAction: 'hide',

            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons: [{
            	reference: 'validate',
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_OK}}",
                handler: this.ok,
                scope: this
            }, {
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_CANCEL}}",
                handler: this.cancel,
                scope: this
            }]
        });
        
        this._initialized = true;
        
        return true;
    },
    
    /**
     * Initialize the form.
     * @private
     */
    _initForm: function()
    {
        this._form.findField('name').setValue('');
        this._form.findField('name').focus();
        this._form.findField('type').setValue('');
        this._form.clearInvalid();
    },
    
    /**
     * Handle the OK button by submitting the form.
     * @private
     */
    ok: function()
    {
        if (!this._form.isValid())
        {
            return;
        }
        
        var name = this._form.findField('name').getValue();
        var type = this._form.findField('type').getValue();
        
        // Add object.
        Ametys.data.ServerComm.callMethod({
            role: 'org.ametys.plugins.repository.workspace.AmetysObjectDao', 
            methodName: 'addAmetysObject',
            parameters: [this._parentId, name, type],
            callback: {
                handler: this._okCb,
                scope: this
            },
            errorMessage: "{{i18n PLUGINS_REPOSITORY_ERROR_MSG_ADD_AMETYS_OBJECT}}"
        });
    },
    
    /**
     * Callback fired when the object has been added.
     * @param {Object} result Information on the created object.
     * @param {Array} args The callback arguments.
     * @private 
     */
    _okCb: function(result, args)
    {
        this.box.hide();
        
        var targets = [{
            id: Ametys.message.MessageTarget.AMETYS_OBJECT,
            parameters: {
                ids: [result.id],
                workspaceName: 'default' // TODO Do not hardcode the workspace.
            }
        }];
        
        if (result.jcrAo && result.jcrPath)
        {
            targets.push({
                id: Ametys.message.MessageTarget.REPOSITORY_NODE,
                parameters: {
                    paths: [result.jcrPath],
                    workspaceName: 'default' // TODO Do not hardcode the workspace.
                }
            });
        }
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.CREATED,
            targets: targets
        });
    },
    
    /**
     * Handle the cancel dialog button: hides the dialog box.
     * @private
     */
    cancel: function()
    {
        this.box.hide();
    }
    
});

//------------------ REMOVE OBJECT -----------------------//
/**
 * Class managing the "remove AmetysObject" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.RemoveObject',
{
    singleton: true,
    
    /**
     * Launch the remove AmetysObject action.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    act: function(controller)
    {
        var target = controller.getMatchingTargets()[0];
        
        if (target != null)
        {
            var id = target.getParameters().id;
            
            Ext.MessageBox.confirm(
                "{{i18n PLUGINS_REPOSITORY_REMOVE_AMETYS_NODE_BOX_TITLE}}",
                "{{i18n PLUGINS_REPOSITORY_REMOVE_AMETYS_NODE_BOX_HINT}} <br/>" + id,
                function(button) {
                    if (button == 'yes') {
                        this._doAct(target.getParameters());
                    }
                },
                this
            );
        }
    },
    
    /**
     * Send the remove object message to the server.
     * @param {Object} obj Information on the AmetysObject to delete.
     * @private
     */
    _doAct: function(obj)
    {
        var me = this;
        
        var targets = [{
            id: Ametys.message.MessageTarget.AMETYS_OBJECT,
            parameters: {
                ids: [obj.id]
            }
        }];
        
        if (obj.jcrAo && obj.jcrPath)
        {
            targets.push({
                id: Ametys.message.MessageTarget.REPOSITORY_NODE,
                parameters: {
                    paths: [obj.jcrPath],
                    workspaceName: 'default' // TODO Do not hardcode the workspace.
                }
            });
        }
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.DELETING,
            
            targets: targets,
            callback: function(deletingMsg) {
                Ametys.data.ServerComm.callMethod({
                    role: 'org.ametys.plugins.repository.workspace.AmetysObjectDao', 
                    methodName: 'removeAmetysObject',
                    parameters: [obj.id],
                    callback: {
                        handler: me._doActCb,
                        scope: me,
                        arguments: {
                            id: obj.id,
                            targets: deletingMsg.getTargets()
                        }
                    },
                    errorMessage: "{{i18n PLUGINS_REPOSITORY_ERROR_MSG_REMOVE_AMETYS_OBJECT}}"
                });
            }
        });
    },
    
    /**
     * Callback fired when the object has been removed.
     * @param {Object} result The action result.
     * @param {Array} args The callback arguments.
     * @private 
     */
    _doActCb: function(result, args)
    {
        // Send the deleted message with stored targets
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.DELETED,
            targets: args.targets
        });
    }
});

//------------------ UNLOCK -----------------------//
/**
 * Class managing the "unlock node" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.UnlockObject',
{
    singleton: true,
    
    /**
     * Launch the unlock AmetysObject action.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    act: function(controller)
    {
        var target = controller.getMatchingTargets()[0];
        
        if (target != null)
        {
            var id = target.getParameters().id;
            
	        Ametys.data.ServerComm.callMethod({
	            role: 'org.ametys.plugins.repository.workspace.AmetysObjectDao', 
	            methodName: 'unlockAmetysObject',
	            parameters: [id],
	            callback: {
	                handler: this._actCb,
	                scope: this,
                    arguments: {
                        id: id
                    }
	            },
	            errorMessage: "{{i18n PLUGINS_REPOSITORY_ERROR_MSG_UNLOCK_AMETYS_OBJECT}}"
	        });
        }
    },
    
    /**
     * Callback fired when the AmetysObject has been unlocked.
     * @param {Object} result The action result.
     * @param {Array} args The callback arguments.
     * @private 
     */
    _actCb: function(result, args)
    {
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.MODIFIED,
            targets: {
                id: Ametys.message.MessageTarget.AMETYS_OBJECT,
                parameters: {
                    ids: [args.id]
                }
            }
        });
    }
});

//------------------ ADD METADATA -----------------------//
/**
 * Class managing the "add metadata" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.AddMetadata',
{
    singleton: true,
    
    /**
     * @private
     * Info on the object to add the metadata to.
     */
    _objectInfo: null,
    
    /**
     * @private
     * True when the dialog is initialized.
     */
    _initialized: false,
    
    /**
     * @private
     * The dialog box {@link Ext.form.Panel}.
     */
    _formPanel: null,
    
    /**
     * @private
     * The dialog box.
     */
    box: null,
    
    /**
     * Launch the "add metadata" action.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    act: function(controller)
    {
        var target = controller.getMatchingTargets()[0];
        
        if (target != null)
        {
            this._objectInfo = target.getParameters();
            
            if (!this.delayedInitialize())
            {
                return;
            }
            
            this.box.show();
            this._initForm();
        }
    },
    
    /**
     * Create the metadata creation dialog box.
     * @private
     */
    delayedInitialize: function()
    {
        if (this._initialized)
        {
            return true;
        }
        
        this._formPanel = Ext.create('Ext.form.Panel', {
            defaultType: 'textfield',
            defaults: {
                cls: 'ametys',
                msgTarget: 'side',
                labelAlign: 'right',
                labelSeparator: '',
                labelWidth: 70,
                width: '100%'
            },
            
            border: false,
            items: [{
                xtype: 'component',
                cls: 'a-text',
                html: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_HINT}}"
            }, {
            	itemId: 'name',
                xtype: 'textfield',
                fieldLabel : "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_NAME_LABEL}}",
                name: 'name',
                allowBlank: false
            }, {
                xtype: 'combobox',
                fieldLabel: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_TYPE_LABEL}}",
                name: 'type',
                
                editable: false,
                triggerAction: 'all',
                
                // TODO Put a display value?
                queryMode: 'local',
                store: ['String','Long','Double','Date','Boolean'],
                
                emptyText: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_TYPE_COMBO_EMPTY}}",
                allowBlank: false,
                listeners: {
                    select: {fn: this._drawValueField, scope: this}
                }
            }]
        });
        
        this.box = Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_TITLE}}",
            iconCls: 'ametysicon-list6',
            
            width: 400,
            maxHeight: 300,
            scrollable: true,
            
            items: [ this._formPanel ],
            
            defaultFocus: 'name',
            closeAction: 'hide',
            
            referenceHolder: true,
            defaultButton: 'validate',

            buttons: [{
            	reference: 'validate',
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_OK}}",
                handler: this.ok,
                scope: this
            }, {
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_CANCEL}}",
                handler: this.cancel,
                scope: this
            }]
        });
        
        this._initialized = true;
        
        return true;
    },
    
    /**
     * Listens for value combobox change and draw the value input field accordingly.
     * @param {Ext.form.field.ComboBox} combo The type combobox.
     * @param {Array} records The selected records.
     * @param {Object} eOpts Options added to the addListener
     * @private
     */
    _drawValueField: function(combo, records, eOpts)
    {
        var form = this._formPanel.getForm();
        
        var valueFd = form.findField('fieldValue');
        if (valueFd != null)
        {
            this._formPanel.remove(valueFd);
        }
        
        var hourFd = form.findField('hour');
        if (hourFd != null)
        {
            this._formPanel.remove(hourFd);
        }
        
        this._formPanel.items.each(function(item, index, len) {
            if (item.name == 'container')
            {
                this._formPanel.remove(item);
            }
        }, this);
        
        var type = combo.getValue();
        
        switch (type)
        {
            case 'Date':
                var valueFd = Ext.create('Ext.form.field.Date', {
                    hideLabel: true,
                    inputWidth: 98,
                    name: 'fieldValue',
                    submitFormat: 'Y-m-d\\TH:i:s', 
                    allowBlank: false
                });
                
                var timeFd = Ext.create('Ext.form.field.Time', {
                    hideLabel: true,
                    inputWidth: 97,
                    name: 'hour',
                    format: 'H:i:s',
                    value: '00:00:00',
                    increment: 5
                });
                
                var inputFd = Ext.create('Ext.form.FieldContainer', {
                    fieldLabel: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_VALUE_LABEL}}",
                    name: 'container',
                    layout: {
                        type: 'hbox'
                    },
                    border: false,
                    items: [
                        valueFd,
                        {xtype: 'splitter'},
                        timeFd
                    ]
                });
                
                this._formPanel.add(inputFd);
                
                break;
                
            case 'Boolean':
                var valueFd = Ext.create('Ext.form.field.ComboBox', {
                    fieldLabel: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_VALUE_LABEL}}",
                    editable: false,
                    name: 'fieldValue',
                    triggerAction: 'all',
                    store: ['true', 'false'],
                    allowBlank: false
                });
                this._formPanel.add(valueFd);
                break;
                
            case 'Long':
                var valueFd = Ext.create('Ext.form.field.Number', {
                    fieldLabel : "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_VALUE_LABEL}}",
                    name: 'fieldValue',
                    allowBlank: false,
                    allowDecimals: false
                });
                this._formPanel.add(valueFd);
                break;
                
            case 'Double':
                var valueFd = Ext.create('Ext.form.field.Number', {
                    fieldLabel : "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_VALUE_LABEL}}",
                    name: 'fieldValue',
                    allowBlank: false,
                    submitLocaleSeparator: false
                });
                this._formPanel.add(valueFd);
                break;
                
            default:
                var valueFd = Ext.create('Ext.form.field.Text', {
                    fieldLabel : "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_BOX_VALUE_LABEL}}",
                    name: 'fieldValue',
                    allowBlank: false
                });
                this._formPanel.add(valueFd);
                break;
        }
    },
    
    /**
     * Initialize the form.
     * @private
     */
    _initForm: function()
    {
        var form = this._formPanel.getForm();
        
        form.findField('name').setValue('');
        form.findField('type').setValue('');
        form.clearInvalid();
        
        var valueFd = form.findField('fieldValue');
        if (valueFd != null)
        {
            this._formPanel.remove(valueFd);
        }
        
        var hourFd = form.findField('hour');
        if (hourFd != null)
        {
            this._formPanel.remove(hourFd);
        }
    },
    
    /**
     * Handle the OK button by submitting the form.
     * @private
     */
    ok: function()
    {
        var form = this._formPanel.getForm();
        
        if (!form.isValid())
        {
            return;
        }
        
        var values = form.getValues();
        var value = values.fieldValue;
        
        var timeField = form.findField('hour');
        
        // Case of a date-time field.
        if (timeField != null)
        {
            // Date value, without time.
            value = form.findField('fieldValue').getValue();
            
            var time = timeField.getValue();
            
            // Set the time components into the date value.
            value.setHours(time.getHours());
            value.setMinutes(time.getMinutes());
            value.setSeconds(time.getSeconds());
            value.setMilliseconds(time.getMilliseconds());
        }
        
        form.submit({
            url: Ametys.getPluginDirectPrefix('repository') + '/repository/set-metadata',
            params: {
                id: this._objectInfo.id,
                name: values.name,
                type: values.type.toUpperCase(),
                value: value,
                cPath: '',
                rtPath: '',
                filefieldid: form.findField('fieldValue').getId() // FIXME what ?
            },
            success: this._success,
            failure: this._failure,
            scope: this
        });
    },
    
    /**
     * Callback fired when the metadata has been successfully added.
     * @param {Ext.form.Basic} form The form that requested the action.
     * @param {Ext.form.action.Action} action The Action class.
     * @private
     */
    _success: function(form, action)
    {
        this.box.hide();
        
        var targets = [{
            id: Ametys.message.MessageTarget.AMETYS_OBJECT,
            parameters: {
                ids: [this._objectInfo.id]
            }
        }];
        
        if (this._objectInfo.jcrAo && this._objectInfo.jcrPath)
        {
            targets.push({
                id: Ametys.message.MessageTarget.REPOSITORY_NODE,
                parameters: {
                    paths: [this._objectInfo.jcrPath],
                    workspaceName: 'default' // TODO Do not hardcode the workspace.
                }
            });
        }
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.MODIFIED,
            targets: targets
        });
    },
    
    /**
     * Callback fired when the metadata creation has failed.
     * @param {Ext.form.Basic} form The form that requested the action.
     * @param {Ext.form.action.Action} action The Action class.
     * @private
     */
    _failure: function(form, action)
    {
        Ametys.log.ErrorDialog.display({
            title: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_ERROR_TITLE}}",
            text: "{{i18n PLUGINS_REPOSITORY_CREATE_METADATA_ERROR_TEXT}}",
            details: action.result ? action.result.message : ''
        });
    },
    
    /**
     * Handle the cancel button by hiding the dialog box.
     * @private
     */
    cancel: function()
    {
        this.box.hide();
    }
});

//------------------ REMOVE PROPERTY -----------------------//
/**
 * Class managing the "remove property" action.
 * @private
 */
Ext.define('Ametys.workspace.repository.actions.RemoveMetadata',
{
    singleton: true,
    
    /**
     * Launch the remove node action.
     * @param {String} objectId The Ametys object id
     * @param {String} workspaceName The workspace name.
     * @param {String} compositePath The path to the parent composite. Can be null.
     * @param {String} metadataName The metadata name.
     * @param {Function} [callback] The callback function to invoke after deletion success
     */
    act: function(objectId, workspaceName, compositePath, metadataName, callback)
    {
        Ametys.data.ServerComm.callMethod({
            role: 'org.ametys.plugins.repository.workspace.AmetysObjectDao',
            methodName: 'removeMetadata',
            parameters: [objectId, compositePath, metadataName],
            callback: {
                handler: this._doActCb,
                scope: this,
                arguments: {
                    id: objectId,
                    workspaceName: workspaceName,
                    metadataName: metadataName,
                    callback : callback
                }
            },
            errorMessage: "{{i18n PLUGINS_REPOSITORY_DELETE_METADATA_ERROR}}"
        });
    },
    
    /**
     * Callback fired when the property has been removed.
     * @param {Object} result The action result.
     * @param {Array} args The callback arguments.
     * @private 
     */
    _doActCb: function(result, args)
    {
        if (Ext.isFunction(args.callback))
        {
            args.callback();
        }
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.MODIFIED,
            parameters: {
                major: true
            },
            targets: {
                id: Ametys.message.MessageTarget.AMETYS_OBJECT,
                parameters: {
                    ids: [args.id],
                    workspaceName: args.workspaceName
                }
            }
        });
    }
});

//------------------ EXECUTE QUERY -----------------------//
/**
 * Class managing the "execute query" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.ExecuteQuery',
{
    singleton: true,
    
    /**
     * @private
     * True when the dialog is initialized.
     */
    _initialized: false,
    
    /**
     * @private
     * The dialog box {@link Ext.form.Panel}.
     */
    _formPanel: null,
    
    /**
     * @private
     * The dialog box.
     */
    box: null,
    
    /**
     * Launch the execute query action.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    act: function(controller)
    {
        if (!this.delayedInitialize())
        {
            return;
        }
        
        this.box.show();
    },
    
    /**
     * Create the query dialog box.
     * @private
     */
    delayedInitialize: function()
    {
        if (this._initialized)
        {
            return true;
        }
        
        this._formPanel = Ext.create('Ext.form.Panel', {
           defaultType: 'textfield',
           fieldDefaults: {
                cls: 'ametys',
                width: '100%',
                labelSeparator: '',
                msgTarget: 'side'
            },
            
            border: false,
            scrollable: true,
            items: [{
                xtype: 'component',
                cls: 'a-text',
                html:  "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_QUERY_PROMPT_TEXT}}"
            },{
            	itemId: 'query',
                xtype: 'textarea',
                hideLabel: true,
                height: 50,
                name: 'query',
                allowBlank: false
            }, {
                xtype: 'component',
                cls: 'a-text-light',
                html: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_QUERY_EXAMPLE_ABBREV}} //element(*, ametys:content)[@ametys:contributor = 'ametys']"
            }]
        });
        
        this.box = Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_QUERY_PROMPT_TITLE}}",
            iconCls: 'ametysicon-magnifier41',
            
            width: 500,
            scrollable: true,
            
            items: [ this._formPanel ],
            
            defaultFocus: 'query',
            closeAction: 'hide',
            
            referenceHolder: true,
            defaultButton: 'validate',

            
            buttons: [{
            	reference: 'validate',
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_OK}}",
                handler: this.ok,
                scope: this
            }, {
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_CANCEL}}",
                handler: this.cancel,
                scope: this
            }]
        });
        
        this._initialized = true;
        
        return true;
    },
    
    /**
     * Handle the OK button by submitting the form.
     * @private
     */
    ok: function()
    {
        var form = this._formPanel.getForm(); 
        if (!form.isValid())
        {
            return;
        }
        
        var values = form.getValues();
        
        this.box.hide();
        
        Ext.create('Ametys.message.Message', {
            type: 'repository-query-executed',
            targets: {
                type: 'repository-ametys-query',
                parameters: {
                    query: values.query
                }
            }
        });
    },
    
    /**
     * Handle the cancel button by hiding the dialog box.
     * @private
     */
    cancel: function()
    {
        this.box.hide();
    }
});

//------------------ RESOLVE IDENTIFIER -----------------------//
/**
 * Class managing the "Resolve AmetysObject by ID" action.
 * @private
 */
Ext.define('Ametys.plugins.repository.actions.ResolveIdentifier',
{
    singleton: true,
    
    /**
     * @private
     * True when the dialog is initialized.
     */
    _initialized: false,
    
    /**
     * @private
     * The dialog box {@link Ext.form.Panel}.
     */
    _formPanel: null,
    
    /**
     * @private
     * The dialog box.
     */
    box: null,
    
    /**
     * Launch the resolve identifier action.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    act: function(controller)
    {
        if (!this.delayedInitialize())
        {
            return;
        }
        
        this.box.show();
        
        var idField = this.box.getComponent('identifier');
        idField.setValue('');
        idField.clearInvalid();
    },
    
    /**
     * Create the node creation dialog.
     * @private
     */
    delayedInitialize: function()
    {
        if (this._initialized)
        {
            return true;
        }
        
        this._formPanel = Ext.create('Ext.form.Panel', {
            defaults: {
                cls: 'ametys',
                width: '100%',
                msgTarget: 'side'
            },
            border: false,
            items: [{
                    xtype: 'component',
                    cls: 'a-text',
                    html: "{{i18n PLUGINS_REPOSITORY_RESOLVE_ID_PROMPT_TEXT}}"
                    
                },{
	                xtype: 'textfield',
	                name: 'id',
	                hideLabel : true,
	                allowBlank: false
	            }]
        });
        
        this.box = Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_REPOSITORY_RESOLVE_ID_PROMPT_TITLE}}",
            iconCls: 'ametysicon-search16',
            
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            scrollable: true,
            width: 330,
            
            items: [{
                    xtype: 'component',
                    cls: 'a-text',
                    html: "{{i18n PLUGINS_REPOSITORY_RESOLVE_ID_PROMPT_TEXT}}"
                    
                },{
                    xtype: 'textfield',
                    cls: 'ametys',
                    hideLabel: true,
                    name: 'identifier',
                    itemId: 'identifier',
                    allowBlank: false,
                    msgTarget: 'side'
                }],

            defaultFocus: 'identifier',
            closeAction: 'hide',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons: [{
            	reference: 'validate',
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_OK}}",
                handler: this.ok,
                scope: this
            }, {
                text: "{{i18n plugin.repositoryapp:PLUGINS_REPOSITORYAPP_DIALOG_BOX_CANCEL}}",
                handler: this.cancel,
                scope: this
            }]
        });
        
        this._initialized = true;
        
        return true;
    },
    
    /**
     * Handle the OK button by submitting the form.
     * @private
     */
    ok: function()
    {
        var idField = this.box.getComponent('identifier');
        if (!idField.isValid())
        {
            return;
        }
        
        var identifier = idField.getValue();
        
        // Get the object from its identifier.
        Ametys.data.ServerComm.callMethod({
            role: 'org.ametys.plugins.repository.workspace.AmetysObjectDao', 
            methodName: 'getAmetysObject',
            parameters: [identifier],
            callback: {
                handler: this._okCb,
                scope: this
            },
            errorMessage: "{{i18n PLUGINS_REPOSITORY_ERROR_MSG_SOLVE_ID}}"
        });
    },
    
    /**
     * Callback fired when the request has ended.
     * @param {Object} objInfo The object info or null if not found.
     * @param {Array} args The callback arguments.
     * @private 
     */
    _okCb: function(objInfo, args)
    {
        if (objInfo == null)
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_REPOSITORY_RESOLVE_ID_PROMPT_TITLE}}",
                msg: "{{i18n PLUGINS_REPOSITORY_RESOLVE_ID_UNKNOWN}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.INFO
            });
            return;
        }
        
        this.box.hide();
        
        // Open object tool.
        Ametys.plugins.repository.tool.AmetysObjectMetadataTool.open(objInfo.id);
    },
    
    /**
     * Handle the cancel button by hiding the dialog box.
     * @private
     */
    cancel: function()
    {
        this.box.hide();
    }
    
});