/*!
 * Tine 2.0 - CoreData 
 * Copyright (c) 2007-2016 Metaways Infosystems GmbH (http://www.metaways.de)
 * http://www.gnu.org/licenses/agpl.html AGPL Version 3
 */
/*
 * Tine 2.0
 *
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
Ext.ns('Tine.CoreData');


/**
 * core data grid/edit dialog manager
 *
 *  @singleton
 */
Tine.CoreData.Manager = function() {
    var grids = {},
        editDialogs = {},
        toolbars = {};

    return {

        /**
         * create grid for given core data id
         *
         * @param configRecord
         * @param options
         * @returns Ext.form.Field|null
         */
        getGrid: function (id, options) {
            if (grids.hasOwnProperty(id)) {
                constr = grids[id].constr;
                if (! options) {
                    options = grids[id].options;
                }
            } else {
                Tine.log.warn('Id not registered in CoreData manager: ' + id);
            }

            return Ext.isFunction(constr) ? new constr(options) : null;
        },

        /**
         * create grid for given core data id
         *
         * @param configRecord
         * @param options
         * @returns Ext.form.Field|null
         */
        getEditDialog: function (id, options) {
            if (editDialogs.hasOwnProperty(id)) {
                constr = editDialogs[type];
            }
            return Ext.isFunction(constr) ? new constr(options) : null;
        },

        /**
         * create grid for given core data id
         *
         * @param configRecord
         * @param options
         * @returns Ext.form.Field|null
         *
         * TODO is this needed?
         */
        getToolbar: function (id, options) {
            if (toolbars.hasOwnProperty(id)) {
                constr = toolbars[type];
                if (! options) {
                    options = toolbars[id].options;
                }
            } else {
                Tine.log.warn('Id not registered in CoreData manager: ' + id);
            }

            return Ext.isFunction(constr) ? new constr(options) : null;
        },

        /**
         * register grid for given core data
         *
         *  @static
         *  @param id string
         *  @param constructor Function
         *  @param options
         */
        registerGrid: function (id, constructor, options) {
            grids[id] = {
                constr: constructor,
                options: options
            };
        },

        /**
         * register toolbar for given core data
         *
         *  @static
         *  @param id string
         *  @param constructor Function
         *  @param options
         *
         *  TODO is this needed?
         */
        registerToolbar: function (id, constructor, options) {
            toolbars[id] = {
                constr: constructor,
                options: options
            };
        },

        /**
         * register edit dialog for given core data
         *
         *  @static
         *  @param id string
         *  @param constructor Function
         */
        registerEditDialog: function (id, constructor) {
            editDialogs[id] = constructor;
        }
    };
}();
/**
 * Tine 2.0
 *
 * @package     CoreData
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine', 'Tine.CoreData');

/**
 * @namespace   Tine.CoreData
 * @class       Tine.CoreData.TreePanel
 * @extends     Tine.Tinebase.Application
 * CoreData TreePanel<br>
 *
 * @author      Philipp Schüle <p.schuele@metaways.de>
 *
 * TODO allow to customize tree layout (remove parent nodes (/general, /applications, maybe even the application nodes)
 */
Tine.CoreData.TreePanel = function (config) {
    Ext.apply(this, config);
    this.id = 'TreePanel';
    Tine.CoreData.TreePanel.superclass.constructor.call(this);
};
Ext.extend(Tine.CoreData.TreePanel, Ext.tree.TreePanel, {

    autoScroll: true,
    border: false,

    /**
     * init this treePanel
     */
    initComponent: function () {
        if (!this.app) {
            this.app = Tine.Tinebase.appMgr.get('CoreData');
        }

        var generalChildren = this.getCoreDataNodes('/general'),
            applicationChildren = this.getCoreDataNodes('/applications');

        this.root = {
            path: '/',
            cls: 'tinebase-tree-hide-collapsetool',
            text: this.app.i18n._('Core Data'),
            expanded: true,
            children: [{
                path: '/general',
                id: 'general',
                expanded: true,
                text: this.app.i18n._('General Data'),
                hidden: (generalChildren.length == 0),
                children: generalChildren
            }, {
                path: '/applications',
                id: 'applications',
                expanded: true,
                text: this.app.i18n._('Application Data'),
                children: applicationChildren
            }]
        };

        this.on('click', this.onClick, this);

        Tine.CoreData.TreePanel.superclass.initComponent.call(this);
    },

    /**
     * get core data nodes
     *
     * @param path
     * @returns Array
     */
    getCoreDataNodes: function (path) {
        if (! Tine.CoreData.registry.get('coreData')) {
            return [];
        }

        var applicationNodes = [],
            coreDataNodes = {}; // applications => [core data nodes]

        Ext.each(Tine.CoreData.registry.get('coreData')['results'], function (coreData) {
            if ((path === '/applications' && coreData.application_id.name !== 'Tinebase') ||
                (path === '/general' && coreData.application_id.name === 'Tinebase')) {

                var coreDataApp = Tine.Tinebase.appMgr.get(coreData.application_id.name);

                if (! coreDataNodes[coreData.application_id.name]) {
                    coreDataNodes[coreData.application_id.name] = [];
                    applicationNodes.push({
                        path: path + '/' + coreData.application_id.id,
                        id: coreData.application_id.id,
                        text: coreDataApp.i18n._(coreData.application_id.name),
                        attributes: coreData.application_id
                    });
                }

                coreDataNodes[coreData.application_id.name].push({
                    path: path + '/' + coreData.application_id.id + '/' + coreData.id,
                    id: coreData.id,
                    text: coreDataApp.i18n._(coreData.label),
                    leaf: true,
                    attributes: coreData
                });
            }
        }, this);

        if (path === '/general') {
            return (coreDataNodes['Tinebase']) ? coreDataNodes['Tinebase'] : [];
        } else {
            Ext.each(applicationNodes, function(node) {
                node.children = coreDataNodes[node.attributes.name]
            });
            return applicationNodes;
        }
    },

    /**
     * on node click
     *
     * @param {} node
     * @param {} e
     */
    onClick: function (node, e) {
        // switch content type and set north + center panels
        if (node.attributes.attributes && node.attributes.attributes.id && node.leaf) {
            Tine.log.debug('Tine.CoreData.TreePanel::onClick');
            Tine.log.debug(node);

            var mainscreen = this.app.getMainScreen();

            mainscreen.activeContentType = node.attributes.attributes.id;
            mainscreen.activate();
            mainscreen.getCenterPanel().getStore().reload();
        } else {
            return false;
        }
    }
});
/* 
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 216 Metaways Infosystems GmbH (http://www.metaways.de)
 */

Ext.ns('Tine.CoreData');

/**
 * CoreData west panel
 * 
 * @namespace   Tine.CoreData
 * @class       Tine.CoreData.WestPanel
 * @extends     Tine.widgets.mainscreen.WestPanel
 * 
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * 
 * @constructor
 * @xtype       tine.calendar.mainscreenwestpanel
 */
Tine.CoreData.WestPanel = Ext.extend(Tine.widgets.mainscreen.WestPanel, {
    
    //cls: 'cal-tree',
    
    getAdditionalItems: function() {
        return [
            new Tine.CoreData.TreePanel({
                height: 'auto'
            })
        ];
    }
});
/**
 * Tine 2.0
 * 
 * @package     CoreData
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2016 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine', 'Tine.CoreData');

/**
 * @namespace   Tine.CoreData
 * @class       Tine.CoreData.Application
 * @extends     Tine.Tinebase.Application
 * CoreData Application Object <br>
 * 
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.CoreData.Application = Ext.extend(Tine.Tinebase.Application, {
});

// default mainscreen
Tine.CoreData.MainScreen = Ext.extend(Tine.widgets.MainScreen, {

    /**
     * get north panel for given contentType
     *
     * template method to be overridden by subclasses to modify default behaviour
     *
     * @param {String} contentType
     * @return {Ext.Panel}
     */
    getNorthPanel: function(contentType) {
        contentType = contentType || this.getActiveContentType();

        if (! this[contentType + 'ActionToolbar']) {

            if (contentType === '') {
                // return empty toolbar
                this[contentType + 'ActionToolbar'] = new Ext.Toolbar({
                    items: []
                });

            } else {
                this[contentType + 'ActionToolbar'] = Ext.isFunction(this[contentType + this.centerPanelClassNameSuffix].getActionToolbar)
                    ? this[contentType + this.centerPanelClassNameSuffix].getActionToolbar()
                    : Tine.CoreData.Manager.getToolbar(contentType);
            }
        }

        return this[contentType + 'ActionToolbar'];
    },

    /**
     * get center panel for given contentType / core data
     *
     * template method to be overridden by subclasses to modify default behaviour
     *
     * @param {String} contentType
     * @return {Ext.Panel}
     */
    getCenterPanel: function(contentType) {
        contentType = contentType || this.getActiveContentType();

        if (! this[contentType + this.centerPanelClassNameSuffix]) {

            if (contentType === '') {
                // show some information text or remove this as mainscreen is responsibilty of core data models/apps
                this[contentType + this.centerPanelClassNameSuffix] = new Ext.Panel({
                    // TODO improve wording/styling
                    html: this.app.i18n._('Please select core data from tree ...')
                });
            } else {
                // try to find grid in Core Data Manager
                this[contentType + this.centerPanelClassNameSuffix] = Tine.CoreData.Manager.getGrid(contentType);
            }
        }

        return this[contentType + this.centerPanelClassNameSuffix];
    },

    /**
     * get west panel for given contentType
     *
     * template method to be overridden by subclasses to modify default behaviour
     *
     * @return {Ext.Panel}
     *
     * overwrites parent to remove active content type here
     *
     * TODO remove code duplication
     */
    getWestPanel: function() {
        var wpName = 'WestPanel';

        if (! this[wpName]) {
            var wpconfig = {
                app: this.app,
                //contentTypes: this.contentTypes,
                //contentType: contentType,
                listeners: {
                    scope: this,
                    selectionchange: function() {
                        var cp = this.getCenterPanel();
                        if(cp) {
                            try {
                                var grid = cp.getGrid();
                                if(grid) {
                                    var sm = grid.getSelectionModel();
                                    if(sm) {
                                        sm.clearSelections();
                                        cp.actionUpdater.updateActions(sm.getSelectionsCollection());
                                    }
                                }
                            } catch (e) {
                                // do nothing - no grid
                            }
                        }
                    }
                }
            };
            try {
                if(Tine[this.app.name].hasOwnProperty(wpName)) this[wpName] = new Tine[this.app.appName][wpName](wpconfig);
                else this[wpName] = new Tine.widgets.mainscreen.WestPanel(wpconfig);
            } catch (e) {
                Tine.log.error('Could not create westPanel');
                Tine.log.error(e.stack ? e.stack : e);
                this[wpName] = new Ext.Panel({html: 'ERROR'});
            }
        }
        return this[wpName];
    },
});
