/*!
 * Tine 2.0 - Courses 
 * Copyright (c) 2007-2012 Metaways Infosystems GmbH (http://www.metaways.de)
 * http://www.gnu.org/licenses/agpl.html AGPL Version 3
 */
/**
 * Tine 2.0
 * 
 * @package     Courses
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2008 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Courses', 'Tine.Courses.Model');

/**
 * @type {Array}
 * Course model fields
 */
Tine.Courses.Model.CourseArray = Tine.Tinebase.Model.genericFields.concat([
    { name: 'id' },
    { name: 'group_id' },
    { name: 'name' },
    { name: 'type' },
    { name: 'internet' },
    { name: 'fileserver' },
    // group fields
    { name: 'description' },
    { name: 'members' },
    // tine 2.0 notes + tags
    { name: 'notes' },
    { name: 'tags' },
    
    {name: 'attachments', omitDuplicateResolving: true},
]);

/**
 * @type {Tine.Tinebase.Course}
 * record definition
 */
Tine.Courses.Model.Course = Tine.Tinebase.data.Record.create(Tine.Courses.Model.CourseArray, {
    appName: 'Courses',
    modelName: 'Course',
    idProperty: 'id',
    titleProperty: 'name',
    // ngettext('Course', 'Courses', n);
    recordName: 'Course',
    recordsName: 'Courses',
    containerProperty: 'container_id',
    // ngettext('record list', 'record lists', n);
    containerName: 'record list',
    containersName: 'record lists'
});

Tine.Courses.Model.Course.getDefaultData = function() {
    return {
        type: Tine.Courses.registry.get('defaultType')
    };
};

/**
 * get filtermodel of course model
 * 
 * @namespace Tine.Courses.Model
 * @static
 * @return {Array} filterModel definition
 * 
 * TODO only add internet access filter if internet_group config is available
 */ 
Tine.Courses.Model.Course.getFilterModel = function() {
    var app = Tine.Tinebase.appMgr.get('Courses');
    
    return [
        {label: i18n._('Quick Search'),    field: 'query',       operators: ['contains']},
        {label: app.i18n._('Name'),   field: 'name'},
        {
            label: app.i18n._('Internet Access'),
            field: 'internet',
            filtertype: 'tine.widget.keyfield.filter', 
            app: app, 
            keyfieldName: 'internetAccess', 
            defaultOperator: 'in'
        },
        {filtertype: 'foreignrecord', 
            app: app,
            foreignRecordClass: Tine.Tinebase.Model.Department,
            ownField: 'type',
            operators: ['equals']
        }
    ];
};


/**
 * @type {Array}
 * Coursetype model fields
 */
Tine.Courses.Model.CourseTypeArray = [
    { name: 'id' },
    { name: 'name' }
];

/**
 * @type {Tine.Tinebase.CourseType}
 * record definition
 */
Tine.Courses.Model.CourseType = Tine.Tinebase.data.Record.create(Tine.Courses.Model.CourseTypeArray, {
    appName: 'Courses',
    modelName: 'CourseType',
    idProperty: 'id',
    titleProperty: 'name',
    // ngettext('Course Type', 'Course Types', n);
    recordName: 'Course Type',
    recordsName: 'Courses Types'
});
/**
 * Tine 2.0
 * 
 * @package     Courses
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2010 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Courses');

Tine.Courses.MainScreen = Ext.extend(Tine.widgets.MainScreen, {
    activeContentType: 'Course',
    contentTypes: [
        {modelName: 'Course',  requiredRight: null, singularContainerMode: true}
    ]
});

Tine.Courses.CourseFilterPanel = function(config) {
    Ext.apply(this, config);
    Tine.Courses.CourseFilterPanel.superclass.constructor.call(this);
};

Ext.extend(Tine.Courses.CourseFilterPanel, Tine.widgets.persistentfilter.PickerPanel, {
    filter: [{field: 'model', operator: 'equals', value: 'Courses_Model_CourseFilter'}]
});


/**
 * default backend
 */
Tine.Courses.coursesBackend = new Tine.Tinebase.data.RecordProxy({
    appName: 'Courses',
    modelName: 'Course',
    recordClass: Tine.Courses.Model.Course,

    /**
     * deletes multiple records identified by their ids
     * 
     * @param   {Array} records Array of records or ids
     * @param   {Object} options
     * @return  {Number} Ext.Ajax transaction id
     * @success 
     */
    deleteRecords: function(records, options) {
        options = options || {};
        options.params = options.params || {};
        options.params.method = this.appName + '.delete' + this.modelName + 's';
        options.params.ids = this.getRecordIds(records);
        
        // increase timeout to 20 minutes
        options.timeout = 1200000;
        
        return this.doXHTTPRequest(options);
    }
});

/**
 * default backend
 */
Tine.Courses.courseTypeBackend = new Tine.Tinebase.data.RecordProxy({
    appName: 'Courses',
    modelName: 'CourseType',
    recordClass: Tine.Courses.Model.CourseType
});
/**
 * Tine 2.0
 * 
 * @package     Courses
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2012 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Courses');

/**
 * Course grid panel
 */
Tine.Courses.CourseGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    // model generics
    recordClass: Tine.Courses.Model.Course,
    evalGrants: false,
    
    // grid specific
    defaultSortInfo: {field: 'name', direction: 'ASC'},
    gridConfig: {
        autoExpandColumn: 'name'
    },
    
    /**
     * init Tine.Courses.CourseGridPanel
     */
    initComponent: function() {
        this.recordProxy = Tine.Courses.coursesBackend;
        
        this.gridConfig.columns = this.getColumns();
        
        Tine.Courses.CourseGridPanel.superclass.initComponent.call(this);
    },
    
    /**
     * returns cm
     */
    getColumns: function(){
        return [{
            id: 'name',
            header: this.app.i18n._("Name"),
            width: 200,
            sortable: true,
            dataIndex: 'name'
        },{
            id: 'type',
            header: this.app.i18n._("Type"),
            width: 150,
            sortable: true,
            dataIndex: 'type',
            renderer: this.courseTypeRenderer
        }
        ];
    },
    
    /**
     * course type renderer
     * 
     * @param {} value
     * @return {}
     */
    courseTypeRenderer: function(value) {
        return (value.name);
    },
    
    /**
     * update access of course(s)
     * 
     * @param {Ext.Action} button
     * @param {} event
     */
    updateAccessHandler: function(button, event) {
        
        var courses = this.grid.getSelectionModel().getSelections();
        var toUpdateIds = [];
        for (var i = 0; i < courses.length; ++i) {
            toUpdateIds.push(courses[i].data.id);
        }
        
        Ext.Ajax.request({
            params: {
                method: 'Courses.updateAccess',
                ids: toUpdateIds,
                type: button.type,
                access: button.access
            },
            success: function(_result, _request) {
                this.store.load();
            },
            failure: function(result, request){
                Ext.MessageBox.alert(
                    this.app.i18n._('Failed'), 
                    this.app.i18n._('Some error occured while trying to update the courses.')
                );
            },
            scope: this
        });
    }
});
/**
 * Tine 2.0
 * 
 * @package     Tine
 * @subpackage  Widgets
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 */

Ext.namespace('Tine.Courses');

/**
 * Generic 'Credentials' dialog
 * 
 * @namespace   Tine.widgets.dialog
 * @class       Tine.Courses.AddMemberDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * @constructor
 * @param       {Object} config The configuration options.
 */
Tine.Courses.AddMemberDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {

    /**
     * @private
     */
    windowNamePrefix: 'AddMemberWindow_',
    loadRecord: false,
    tbarItems: [],
    evalGrants: false,
    mode: 'local',
    recordClass: Tine.Admin.Model.User,
    
    /**
     * needed for request
     */
    courseData: null,
    
    /**
     * returns dialog
     */
    getFormItems: function() {
        return {
            bodyStyle: 'padding:5px;',
            buttonAlign: 'right',
            labelAlign: 'top',
            border: false,
            layout: 'form',
            defaults: {
                xtype: 'textfield',
                anchor: '90%',
                listeners: {
                    scope: this,
                    specialkey: function(field, event) {
                        if (event.getKey() == event.ENTER) {
                            this.onApplyChanges();
                        }
                    }
                }
            },
            items: [{
                fieldLabel: this.app.i18n._('First Name'), 
                name: 'accountFirstName',
                allowBlank: false
            },{
                fieldLabel: this.app.i18n._('Last Name'), 
                name: 'accountLastName',
                allowBlank: false
            }]
        };
    },
    
    /**
     * executed after record got updated from proxy
     * 
     * @private
     */
    onRecordLoad: function() {
        // interrupt process flow till dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        var title = this.windowTitle || this.app.i18n._('Add new member to course');
        this.window.setTitle(title);
        
        this.getForm().loadRecord(this.record);
        
        this.loadMask.hide();
        
        this.getForm().findField('accountFirstName').focus(true, 100);
    },
    
    /**
     * generic apply changes handler
     */
    onApplyChanges: function() {
        this.onRecordUpdate();
        if (this.isValid()) {
            this.loadMask.show();
            Tine.Courses.addNewMember(this.record.data, this.courseData, function(response, exception) {
                Tine.log.debug('Tine.Courses.CourseEditDialog::onMembersImport');
                Tine.log.debug(arguments);
                
                this.loadMask.hide();
                
                if (response) {
                    this.fireEvent('update', response);
                    this.window.close();
                } else {
                    Tine.Tinebase.ExceptionHandler.handleRequestException((exception.error) ? exception.error : exception);
                }
            }, this);
            
        } else {
            Ext.MessageBox.alert(i18n._('Errors'), i18n._('Please fix the errors noted.'));
        }
    }
});

/**
 * credentials dialog popup / window
 */
Tine.Courses.AddMemberDialog.openWindow = function (config) {
    var window = Tine.WindowFactory.getWindow({
        width: 260,
        height: 160,
        name: Tine.Courses.AddMemberDialog.windowNamePrefix + Ext.id(),
        contentPanelConstructor: 'Tine.Courses.AddMemberDialog',
        contentPanelConstructorConfig: config,
        modal: true
    });
    return window;
};
/**
 * Tine 2.0
 * 
 * @package     Courses
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2012 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Courses');

Tine.Courses.CourseEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    /**
     * @private
     */
    windowNamePrefix: 'CourseEditWindow_',
    appName: 'Courses',
    recordClass: Tine.Courses.Model.Course,
    recordProxy: Tine.Courses.coursesBackend,
    evalGrants: false,
    displayNotes: true,

    /**
     * initComponent
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Courses');
        
        this.action_import = new Ext.Action({
            iconCls: 'action_import',
            disabled: true,
            text: this.app.i18n._('Import course members'),
            plugins: [new Ext.ux.file.BrowsePlugin({})],
            scope: this,
            handler: this.onFileSelect
        });
        
        this.action_addNewMember = new Ext.Action({
            iconCls: 'action_add',
            disabled: true,
            text: this.app.i18n._('Add new member'),
            scope: this,
            handler: this.onAddNewMember
        });
        
        this.tbarItems = [
            this.action_import,
            this.action_addNewMember
        ];
        Tine.Courses.CourseEditDialog.superclass.initComponent.call(this);
    },
    
    /**
     * onFileSelect
     * 
     * @param {} fileSelector
     * 
     * TODO wrap this into a uploadAction widget
     */
    onFileSelect: function(fileSelector) {
        
        var files = fileSelector.getFileList();
        this.loadMask.show();
        var upload = new Ext.ux.file.Upload({
            file: files[0],
            fileSelector: fileSelector
        });
        
        upload.on('uploadcomplete', function(uploader, record){
            var tempFile = record.get('tempFile');
            Ext.Ajax.request({
                scope: this,
                timeout: 1200000, // 20 minutes
                params: {
                    method: 'Courses.importMembers',
                    tempFileId: tempFile.id,
                    groupId: this.record.data.group_id,
                    courseId: this.record.data.id
                },
                success: this.onMembersImport,
                failure: function() {}
            });
            
        }, this);
        
        upload.on('uploadfailure', function(uploader, record){
            
        }, this);
        
        this.loadMask.show();
        var uploadKey = Tine.Tinebase.uploadManager.queueUpload(upload);
        var fileRecord = Tine.Tinebase.uploadManager.upload(uploadKey);
    },
    
    /**
     * onAddNewMember
     */
    onAddNewMember: function(fileSelector) {
        Tine.Courses.AddMemberDialog.openWindow({
            courseData: this.record.data,
            app: this.app,
            listeners: {
                scope: this,
                'update': this.onMembersImport
            }
        });
    },
    
    /**
     * update members grid
     */
    onMembersImport: function(response) {
        Tine.log.debug('Tine.Courses.CourseEditDialog::onMembersImport');
        Tine.log.debug(response);
        
        var members = (response.responseText) ? Ext.util.JSON.decode(response.responseText) : response;
        if (members.results.length > 0) {
            this.membersStore.loadData({results: members.results});
        }
        this.loadMask.hide();
    },
    
    /**
     * overwrite update toolbars function (we don't have record members yet)
     */
    updateToolbars: function() {
    },
    
    /**
     * onRecordLoad
     */
    onRecordLoad: function() {
        var members = this.record.get('members') || [];
        if (members.length > 0) {
            this.membersStore.loadData({results: members});
        }
        
        // only activate import and ok buttons if editing existing course / user has the appropriate right
        var disabled = ! this.record.get('id') 
            || ! Tine.Tinebase.common.hasRight('manage', 'Admin', 'accounts')
            || ! Tine.Tinebase.common.hasRight('add_new_user', 'Courses');
        this.action_import.setDisabled(disabled);
        this.action_addNewMember.setDisabled(disabled);
        this.action_saveAndClose.setDisabled(!Tine.Tinebase.common.hasRight('manage', 'Admin', 'accounts'));
        
        Tine.Courses.CourseEditDialog.superclass.onRecordLoad.call(this);
    },
    
    /**
     * onRecordUpdate
     */
    onRecordUpdate: function() {
        Tine.Courses.CourseEditDialog.superclass.onRecordUpdate.call(this);
        
        this.record.set('members', '');
        
        var members = [];
        this.membersStore.each(function(_record){
            members.push(_record.data.id);
        });
        
        this.record.set('members', members);
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        var internetAccessDeactivated = (! Tine.Courses.registry.get('config').internet_group || 
            Tine.Courses.registry.get('config').internet_group.value === null);
        
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            defaults: {
                hideMode: 'offsets'
            },
            activeTab: 0,
            border: false,
            items:[{
                title: this.app.i18n.ngettext('Course', 'Courses', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: 1
                    },
                    items: [[{
                        fieldLabel: this.app.i18n._('Course Name'), 
                        name:'name',
                        allowBlank: false
                    }, {
                        xtype:'reccombo',
                        name: 'type',
                        allowBlank: false,
                        fieldLabel: this.app.i18n._('Course / School Type'),
                        displayField: 'name',
                        store: new Ext.data.Store({
                           fields: Tine.Courses.Model.CourseType,
                           proxy:  Tine.Courses.courseTypeBackend,
                           reader: Tine.Courses.courseTypeBackend.getReader(),
                           sortInfo: {field: 'name', direction: 'ASC'}
                        })
                    }, {
                        name: 'description',
                        fieldLabel: this.app.i18n._('Description'),
                        grow: false,
                        preventScrollbars:false,
                        xtype: 'textarea',
                        height: 60
                    }, new Tine.Tinebase.widgets.keyfield.ComboBox({
                        fieldLabel: this.app.i18n._('Internet Access'),
                        app: 'Courses',
                        keyFieldName: 'internetAccess',
                        value: 'FILTERED',
                        name: 'internet',
                        hideLabel: internetAccessDeactivated,
                        hidden: internetAccessDeactivated
                    })
                    ]]
                }, {
                    // activities and tags
                    layout: 'accordion',
                    animate: true,
                    region: 'east',
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    items: [
                    new Tine.widgets.tags.TagPanel({
                        app: 'Courses',
                        border: false,
                        bodyStyle: 'border:1px solid #B5B8C8;'
                    })]
                }]
            }, {
                title: this.app.i18n._('Members'),
                layout: 'fit',
                items: [this.getMembersGrid()]
            }, new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: this.appName + '_Model_' + this.recordClass.getMeta('modelName')
            })]
        };
    },
    
    /**
     * get the members grid panel
     * 
     * @return {GridPanel} membersGrid
     */
    getMembersGrid: function() {
        if (! this.membersGrid) {
            this.membersStore =  new Ext.data.JsonStore({
                root: 'results',
                totalProperty: 'totalcount',
                id: 'id',
                fields: Tine.Tinebase.Model.Account
            });
            
            var columns = [{
                id: 'data',
                header: this.app.i18n._("Login"),
                width: 200,
                dataIndex: 'data',
                renderer: function(value) {
                    return (value.account_id) ? i18n._('unknown') : value;
                }
            }];
            
            var action_resetPwd = new Ext.Action({
                text: i18n._('Reset Password'),
                scope: this,
                handler: function(_button, _event) {
                    this.loadMask.show();
                    var accountObject = this.membersGrid.getSelectionModel().getSelected().data;
                    Ext.Ajax.request( {
                        params : {
                            method    : 'Courses.resetPassword',
                            account   : accountObject.id,
                            password  : this.record.data.name,
                            mustChange: true
                        },
                        scope: this,
                        success: function() {
                            this.loadMask.hide();
                        }
                    });
                },
                iconCls: 'action_password'
            });
            
            this.membersGrid = new Tine.widgets.account.PickerGridPanel({
                store: this.membersStore,
                contextMenuItems: [action_resetPwd],
                configColumns: columns,
                enableTbar: Tine.Tinebase.common.hasRight('add_existing_user', 'Courses')
            });
        }
        return this.membersGrid;
    }
});

/**
 * Courses Edit Popup
 */
Tine.Courses.CourseEditDialog.openWindow = function (config) {
    var id = (config.record && config.record.id) ? config.record.id : 0;
    var window = Tine.WindowFactory.getWindow({
        width: 800,
        height: 470,
        name: Tine.Courses.CourseEditDialog.prototype.windowNamePrefix + id,
        contentPanelConstructor: 'Tine.Courses.CourseEditDialog',
        contentPanelConstructorConfig: config
    });
    return window;
};
