/*!
 * Tine 2.0 - Phone 
 * Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 * http://www.gnu.org/licenses/agpl.html AGPL Version 3
 */
/*
 * Tine 2.0
 * 
 * @package     Phone
 * @license     http://www.gnu.org/licenses/agpl.html AGPL3
 * @author      Lars Kneschke <l.kneschke@metaways.de>
 * @copyright   Copyright (c) 2008-2012 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 * TODO         refactor this!
 */
 
Ext.namespace('Tine.Phone');

/**************************** dialer form / function *******************************/

Tine.Phone.Application = Ext.extend(Tine.Tinebase.Application, {
    
    /**
     * holds the users' phones
     * @type {Ext.data.JsonStore}
     */
    userPhonesStore: null,
    
    init: function() {
        // create store (get from initial data)
        this.userPhonesStore = new Ext.data.JsonStore({
            fields: Tine.Voipmanager.Model.SnomPhone,
            // initial data from http request
            data: Tine.Phone.registry.get('Phones'),
            autoLoad: true,
            id: 'id'
        });
        new Tine.Phone.AddressbookGridPanelHook({app: this});
    }
});


/**
 * dial function
 * - opens the dialer window if multiple phones/lines are available
 * - directly calls dial json function if number is set and just 1 phone and line are available
 * 
 * @param string phone number to dial
 * 
 * @todo use window factory later
 * @todo what todo if no lines are available?
 */
Tine.Phone.dialPhoneNumber = function(number) {
    var phonesStore = Tine.Tinebase.appMgr.get('Phone').userPhonesStore;
    var lines = (phonesStore.getAt(0)) ? phonesStore.getAt(0).data.lines : [];
    
    // check if only one phone / one line exists and number is set
    if (phonesStore.getTotalCount() == 1 && lines.length == 1 && number) {
        // call Phone.dialNumber
        Ext.Ajax.request({
            url: 'index.php',
            params: {
                method: 'Phone.dialNumber',
                number: number,
                phoneId: phonesStore.getAt(0).id,
                lineId: lines[0].id 
            },
            success: function(_result, _request){
                // success
            },
            failure: function(result, request){
                // show error message?
            }
        });

    } else {

        // open dialer box (with phone and lines selection)
        var dialerPanel = new Tine.Phone.DialerPanel({
            number: (number) ? number : null
        });
        
        var dialer = Tine.WindowFactory.getWindow({
            title: 'Dial phone number',
            id: 'dialerWindow',
            modal: true,
            width: 400,
            height: 150,
            layout: 'fit',
            plain:true,
            bodyStyle:'padding:5px;',
            closeAction: 'close',
            items: [dialerPanel] 
        });
    }
};

/**
 * register special renderer for direction and destination
 */
Tine.widgets.grid.RendererManager.register('Phone', 'Call', 'direction', function(v) {
    var t = Tine.Tinebase.appMgr.get('Phone').i18n;
    switch(v) {
        case 'in':
            return '<img src="images/call-incoming.png" width="12" height="12" alt="contact" ext:qtip="' + Ext.util.Format.htmlEncode(t._('Incoming call')) + '"/>';
            break;
            
        case 'out':
            return '<img src="images/call-outgoing.png" width="12" height="12" alt="contact" ext:qtip="' + Ext.util.Format.htmlEncode(t._('Outgoing call')) + '"/>';
            break;
    }
});

Tine.widgets.grid.RendererManager.register('Phone', 'Call', 'destination', function(v) {
    if (v.toString().toLowerCase() == 'unknown') {
        var t = Tine.Tinebase.appMgr.get('Phone').i18n;
        return t._('unknown number');
    }
    
    return Ext.util.Format.htmlEncode(v);
});

Tine.widgets.grid.RendererManager.register('Phone', 'Call', 'line_id', function(v) {
    return (v && v.hasOwnProperty('linenumber')) ? v.linenumber : '';
});

Tine.widgets.grid.RendererManager.register('Phone', 'Call', 'contact_id', function(v) {
    return (v && v.hasOwnProperty('n_fn')) ? v.n_fn : '';
});

/***************************** utils ****************************************/

Ext.namespace('Tine.Phone.utils');

/**
 * checks if given argument is syntactically a callable/valid number
 * 
 * @todo: synchrosize this with the asterisk rules
 */
Tine.Phone.utils.isCallable = function(number) {
    return ! number.toString().replace(/^\+|[ \-\/]/g, '').match(/[^0-9]/);
};

Ext.namespace('Tine.Phone');

Tine.Phone.PhoneTreePanel = Ext.extend(Ext.tree.TreePanel, {

    // private
    id: 'phone-tree',
    rootVisible: false,
    border: false,
    collapsible: true,
    baseCls: 'ux-arrowcollapse',
    
    // state stuff
    stateful: true,
    stateId: 'phone-phonetreepanel',
    stateEvents: ['collapse', 'expand', 'click'],
    
    /**
     * holds the users' phones
     * @type {Ext.data.JsonStore}
     */
    store: null,
    
    /**
     * last selected node
     * 
     * @type {Ext.tree.TreeNode} 
     */
    ctxNode: null,
    
    /**
     * initializes the component
     */
    initComponent: function() {
        Tine.Phone.PhoneTreePanel.superclass.initComponent.call(this, arguments);
        
        this.setRootNode(new Ext.tree.TreeNode({
            cls: 'treemain',
            allowDrag: false,
            allowDrop: true,
            id: 'phone-root',
            icon: false
        }));
        
        // create context menu
        var contextMenu = new Ext.menu.Menu({
            items: [
                this.grid.action_editPhoneSettings
            ],
            listeners: {
                scope: this,
                hide: function() {this.ctxNode = null;}
            }
        });
        
        this.on('contextmenu', function(node, event){
            this.ctxNode = node;
            if (node.id != 'phone-root') {
                contextMenu.showAt(event.getXY());
            }
        }, this);

        this.on('click', function(node, event) {
            this.onNodeClick(node, event);
        }, this);
        
        this.store = this.app.userPhonesStore;
    },
        
    /**
     * is called on single click on an node of the phoneTreePanel
     * 
     * @param {Ext.tree.TreeNode} node
     * @param {} event
     */
    onNodeClick: function(node, event) {
        this.ctxNode = node;
        this.grid.store.load();
    },
    
    /**
     * returns the currently selected node
     * 
     * @return {Ext.tree.TreeNode}
     */
    getActiveNode: function() {
        return this.ctxNode || this.getSelectionModel().getSelectedNode();
    },
    
    /**
     * updates the phone tree panel after an crud action and on load
     */
    updateTree: function() {
        // remove all children first
        var rootNode = this.getRootNode();
        rootNode.eachChild(function(child) {
            this.removeChild(child);
        });

        // add phones from store to tree menu
        this.store.each(function(record) {
            var label = (record.data.description == '') 
               ? record.data.macaddress 
               : Ext.util.Format.ellipsis(Ext.util.Format.htmlEncode(record.data.description), 30);
            var node = new Ext.tree.TreeNode({
                id: record.id,
                record: record,
                text: label,
                iconCls: 'PhoneIconCls',
                qtip: Ext.util.Format.htmlEncode(record.data.description),
                leaf: true
            });
            rootNode.appendChild(node);
        }, this);
    },

    /**
     * @see Ext.Component
     */
    getState: function() {
        var root = this.getRootNode();
        
        var state = {
            selected: this.grid.ctxNode ? this.grid.ctxNode.id : null
        };
        
        return state;
    },
    
    
    // private
    initState : function(){
        if(Ext.state.Manager){
            var id = this.getStateId();
            if(id){
                var state = Ext.state.Manager.get(id);
                if (state) {
                    if (this.fireEvent('beforestaterestore', this, state) !== false){
                        this.applyState(Ext.apply({}, state));
                        this.fireEvent('staterestore', this, state);
                    }
                } else {
                    (function(){
                        var root = this.getRootNode();
                        if (root.firstChild) {
                            root.firstChild.select();
                        }
                    }).defer(100, this);
                }
            }
        }
    },
    
    /**
     * applies state to cmp
     * 
     * @param {Object} state
     */
    applyState: function(state) {
        (function() {
            var node = state.selected ? this.getNodeById(state.selected) : this.getRootNode().firstChild;
            if (node) {
                node.select();
            }
        }).defer(100, this);
    }
});/*
 * Tine 2.0
 * 
 * @package     Phone
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2009-2011 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.ns('Tine.Phone');

/**
 * @namespace   Tine.Phone
 * @class       Tine.Phone.AddressbookGridPanelHook
 * 
 * <p>Phone Addressbook Hook</p>
 * <p>
 * </p>
 * 
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * 
 * @constructor
 */
Tine.Phone.AddressbookGridPanelHook = function(config) {
    Tine.log.info('initialising phone addressbook hooks');
    Ext.apply(this, config);
    
    // NOTE: due to the action updater this action is bound the the adb grid only!
    this.phoneMenu = new Ext.menu.Menu({
    });
    
    this.callContactAction = new Ext.Action({
        text: this.app.i18n._('Call contact'),
        iconCls: 'PhoneIconCls',
        disabled: this.useActionUpdater ? true : false,
        scope: this,
        actionUpdater: this.useActionUpdater ? this.updateAction : Ext.emptyFn,
        menu: this.phoneMenu,
        listeners: {
            scope: this,
            render: this.useActionUpdater ? this.onRender : Ext.emptyFn
        }
    });
    
    this.callContactBtn = Ext.apply(new Ext.SplitButton(this.callContactAction), {
        scale: 'medium',
        rowspan: 2,
        iconAlign: 'top',
        arrowAlign:'right'
    }),

    // register in toolbar + contextmenu
    Ext.ux.ItemRegistry.registerItem(this.keyPrefix + '-Contact-GridPanel-ActionToolbar-leftbtngrp', this.callContactBtn, 30);
    Ext.ux.ItemRegistry.registerItem(this.keyPrefix + '-Contact-GridPanel-ContextMenu', this.callContactAction, 80);
};

Ext.apply(Tine.Phone.AddressbookGridPanelHook.prototype, {
    
    /**
     * do we use the grids action updater
     * 
     * @type Boolean
     */
    useActionUpdater: true,
    
    /**
     * contact to call
     * 
     * @type Tine.Addressbook.Model.Contact
     */
    contact: null,
    
    /**
     * @property app
     * @type Tine.Phone.Application
     * @private
     */
    app: null,
    
    /**
     * hook registry prefix
     * @type String
     */
    keyPrefix: 'Addressbook',
    
    /**
     * @property callContactAction
     * @type Ext.Action
     * @private
     */
    callContactAction: null,
    
    /**
     * @property callContactBtn
     * @type Ext.Button
     * @private
     */
    callContactBtn: null,
    
    /**
     * @property ContactGridPanel
     * @type Tine.Addressbook.ContactGridPanel
     * @private
     */
    ContactGridPanel: null,
    
    /**
     * @property phoneMenu
     * @type Ext.menu.Menu
     * @private
     */
    phoneMenu: null,
    
    /**
     * get addressbook contact grid panel
     */
    getContactGridPanel: function() {
        if (! this.ContactGridPanel) {
            this.ContactGridPanel = Tine.Tinebase.appMgr.get('Addressbook').getMainScreen().getCenterPanel();
        }
        
        return this.ContactGridPanel;
    },
    
    /**
     * calls a contact
     * @param {Button} btn 
     */
    onCallContact: function(btn) {
        var number;

        var contact = this.contact ? this.contact : this.getContactGridPanel().grid.getSelectionModel().getSelected();
        
        if (! contact) {
            return;
        }
        
        if (!Ext.isEmpty(contact.get(btn.field))) {
            number = contact.get(btn.field);
        } else if(!Ext.isEmpty(contact.data.tel_work)) {
            number = contact.data.tel_work;
        } else if (!Ext.isEmpty(contact.data.tel_cell)) {
            number = contact.data.tel_cell;
        } else if (!Ext.isEmpty(contact.data.tel_cell_private)) {
            number = contact.data.tel_cell_private;
        } else if (!Ext.isEmpty(contact.data.tel_home)) {
            number = contact.data.tel_home;
        }

        Tine.Phone.dialPhoneNumber(number);
    },
    
    /**
     * add to action updater the first time we render
     */
    onRender: function() {
        var actionUpdater = this.getContactGridPanel().actionUpdater,
            registeredActions = actionUpdater.actions;
            
        if (registeredActions.indexOf(this.callContactAction) < 0) {
            actionUpdater.addActions([this.callContactAction]);
        }
    },
    
    /**
     * updates call menu
     * 
     * @param {Ext.Action} action
     * @param {Object} grants grants sum of grants
     * @param {Object} records
     */
    updateAction: function(action, grants, records) {
        if (action.isHidden()) {
            return;
        }

        this.phoneMenu.removeAll();
        action.setDisabled(true);

        if (records.length == 1) {
            var contact = records[0];

            if (! contact) {
                return false;
            }
            
            if(!Ext.isEmpty(contact.data.tel_work)) {
                this.phoneMenu.add({
                   text: this.app.i18n._('Work') + ' ' + contact.data.tel_work + '',
                   scope: this,
                   handler: this.onCallContact,
                   field: 'tel_work'
                });
                action.setDisabled(false);
            }
            if(!Ext.isEmpty(contact.data.tel_home)) {
                this.phoneMenu.add({
                   text: this.app.i18n._('Home') + ' ' + contact.data.tel_home + '',
                   scope: this,
                   handler: this.onCallContact,
                   field: 'tel_home'
                });
                action.setDisabled(false);
            }
            if(!Ext.isEmpty(contact.data.tel_cell)) {
                this.phoneMenu.add({
                   text: this.app.i18n._('Cell') + ' ' + contact.data.tel_cell + '',
                   scope: this,
                   handler: this.onCallContact,
                   field: 'tel_cell'
                });
                action.setDisabled(false);
            }
            if(!Ext.isEmpty(contact.data.tel_cell_private)) {
                this.phoneMenu.add({
                   text: this.app.i18n._('Cell private') + ' ' + contact.data.tel_cell_private + '',
                   scope: this,
                   handler: this.onCallContact,
                   field: 'tel_cell_private'
                });
                action.setDisabled(false);
            }
        }
    },
    
    /**
     * set contact for action and update phoneMenu items
     * 
     * @param {Tine.Addressbook.Model.Contact} contact
     */
    setContactAndUpdateAction: function(contact) {
        this.contact = contact;
        this.updateAction(this.callContactAction, null, [contact]);
    }
});
/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2012-2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Phone');

/**
 * @namespace   Tine.Phone
 * @class       Tine.Phone.CallEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Call Compose Dialog</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Phone.CallEditDialog
 */

Tine.Phone.CallGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    
    /**
     * the panel holds the phones available for the user
     * 
     * @type {Ext.tree.TreePanel}
     */
    phoneTreePanel: null,
    
    /**
     * 
     * @type {Ext.Action}
     */
    editPhoneSettingsAction: null,
    
    /**
     * initializes the component
     */
    initComponent: function() {
        Tine.Phone.CallGridPanel.superclass.initComponent.call(this);
        this.initPhoneTreePanel();
    },
    
    /**
     * @private
     */
    initActions: function() {
        this.action_editPhoneSettings = new Ext.Action({
            text: this.app.i18n._('Edit phone settings'),
            iconCls: 'PhoneIconCls',
            handler: this.onEditPhoneSettings.createDelegate(this),
            scope: this,
            actionUpdater: function(action, grants, records) {
                if (this.phoneTreePanel.getActiveNode()) {
                    this.action_editPhoneSettings.setDisabled(0);
                } else {
                    this.action_editPhoneSettings.setDisabled(1);
                }
            }
        });
        
        this.action_dialNumber = new Ext.Action({
            text: this.app.i18n._('Dial number'),
            tooltip: this.app.i18n._('Initiate a new outgoing call'),
            handler: this.onDialNumber,
            iconCls: 'action_DialNumber',
            scope: this,
            actionUpdater: function(action, grants, records) {
                if (records.length != 1) {
                    this.action_dialNumber.setDisabled(1);
                } else {
                    this.action_dialNumber.setDisabled(0);
                }
            }
        });
        
        // register actions in updater
        this.actionUpdater.addActions([
            this.action_editPhoneSettings,
            this.action_dialNumber
        ]);
        this.getActionToolbar();
    },
    
    /**
     * row doubleclick handler
     * 
     * @param {} grid
     * @param {} row
     * @param {} e
     */
    onRowDblClick: function(grid, row, e) {
        this.onDialNumber(grid, row, e);
    },
    
    /**
     * get action toolbar
     * 
     * @return {Ext.Toolbar}
     */
    getActionToolbar: function() {
        if (! this.actionToolbar) {
            this.actionToolbar = new Ext.Toolbar({
                items: [{
                    xtype: 'buttongroup',
                    plugins: [{
                        ptype: 'ux.itemregistry',
                        key:   this.app.appName + '-' + this.recordClass.prototype.modelName + '-GridPanel-ActionToolbar-leftbtngrp'
                    }],
                    items: [
                        Ext.apply(new Ext.Button(this.action_editPhoneSettings), {
                            scale: 'medium',
                            rowspan: 2,
                            iconAlign: 'top'
                        }),
                        Ext.apply(new Ext.Button(this.action_dialNumber), {
                            scale: 'medium',
                            rowspan: 2,
                            iconAlign: 'top'
                        })
                    ]
                }]
            });
        }
        
        if (this.filterToolbar && typeof this.filterToolbar.getQuickFilterField == 'function') {
            this.actionToolbar.add('->', this.filterToolbar.getQuickFilterField());
        }
        
        return this.actionToolbar;
    },
     
    /**
     * add custom items to context menu
     * 
     * @return {Array}
     */
    getContextMenuItems: function() {
        var items = [
            '-',
            this.action_dialNumber
            ];
        
        return items;
    },
    
    /**
     * is called on dial a number
     */
    onDialNumber: function() {
        var record = this.grid.getSelectionModel().getSelected();
        var number = record ? record.get('destination') : false;
        Tine.Phone.dialPhoneNumber(number);
    },
    
    /**
     * initializes the phone tree panel
     */
    initPhoneTreePanel: function() {
        this.phoneTreePanel = new Tine.Phone.PhoneTreePanel({
            app: this.app,
            title: this.app.i18n._('Phones'),
            grid: this
        });
        
        var westPanel = this.app.getMainScreen().getWestPanel().getPortalColumn();
        westPanel.add(this.phoneTreePanel);
        
        this.phoneTreePanel.updateTree();
    },
    
    /**
     * called before store queries for data
     */
    onStoreBeforeload: function(store, options) {
        Tine.Phone.CallGridPanel.superclass.onStoreBeforeload.apply(this, arguments);
        var node = this.phoneTreePanel.getActiveNode();
        if (node && node.hasOwnProperty('attributes')) {
            var r = node.attributes.record;
            if (! options.params) options.params = {};
            options.params.filter = [
                {field: 'phone_id', operator: 'AND', value: [{field: ':id', operator: 'equals', value: r.get('id')}]}
            ];
        }
        
    },
    
    /**
     * is called on edit phone button click
     */
    onEditPhoneSettings: function() {
        var node = this.phoneTreePanel.getActiveNode();
        if (node) {
            var rp = Tine.Phone.myphoneBackend;
                rp.recordReader = function(response) {
                    var record = new Tine.Phone.Model.MyPhone(Ext.decode(response.responseText));
                    var recordId = record.get(record.idProperty);
                    record.id = recordId ? recordId : 0;
                    return record;
                };
                
            var popupWindow = Tine.Voipmanager.SnomPhoneEditDialog.openWindow({
                    recordProxy: rp,
                    record: node.attributes.record,
                    appName: 'Phone',
                    modelName: 'MyPhone'
                });
            
        } else {
            Ext.Msg.show({
                title: this.app.i18n._('No phone selected'), 
                msg: this.app.i18n._('Please select the desired phone in the tree!'),
                icon: Ext.MessageBox.INFO,
                buttons: Ext.Msg.OK,
                scope: this
            });
        }
    }
});

/*
 * Tine 2.0
 * 
 * @package     Phone
 * @license     http://www.gnu.org/licenses/agpl.html AGPL3
 * @author      Lars Kneschke <l.kneschke@metaways.de>
 * @copyright   Copyright (c) 2008-2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Phone');

/**
 * dialer form
 * 
 * @todo use macaddress or description/name as display value?
 */
Tine.Phone.DialerPanel = Ext.extend(Ext.form.FormPanel, {
    
    id: 'dialerPanel',
    translation: null,
    
    // initial phone number
    number: null,
    
    // config settings
    defaults: {
        xtype: 'textfield',
        anchor: '100%',
        allowBlank: false
    },
    bodyStyle: 'padding:5px;',
    buttonAlign: 'right',
        
    phoneStore: null,
    linesStore: null,
    
    // private
    initComponent: function(){
        
        this.translation = new Locale.Gettext();
        this.translation.textdomain('Phone');
        
        // set stores
        this.phoneStore = Tine.Tinebase.appMgr.get('Phone').userPhonesStore;
        
        //this.setLineStore(this.phoneStore.getAt(0).id);
        this.setLineStore(null);
        
        /***************** form fields *****************/
        
        this.items = [new Tine.widgets.customfields.CustomfieldsCombo({
                fieldLabel: this.translation._('Phone'),
                store: this.phoneStore,
                mode: 'local',
                editable: false,
                stateful: true,
                stateEvents: ['select'],
                displayField:'description',
                valueField: 'id',

                id: 'phoneId',
                name: 'phoneId',
                triggerAction: 'all',
                listeners: {
                    scope: this,
                    
                    // reload lines combo on change
                    select: function(combo, newValue, oldValue){
                        //console.log('set line store for ' + newValue.data.id);
                        this.setLineStore(newValue.data.id);
                    }
                }
            }),{
                xtype: 'combo',
                fieldLabel: this.translation._('Line'),
                name: 'lineId',
                displayField:'linenumber',
                valueField: 'id',
                mode: 'local',
                store: this.linesStore,
                triggerAction: 'all',
                disabled: (this.linesStore.getCount() <= 1)
            },{
                fieldLabel: this.translation._('Number'),
                name: 'phoneNumber'
            }
        ];
        
        /******************* action buttons ********************/
        
        // cancel action
        this.cancelAction = new Ext.Action({
            text: this.translation._('Cancel'),
            iconCls: 'action_cancel',
            handler : function(){
                Ext.getCmp('dialerWindow').close();
            }
        });
            
        // dial action
        this.dialAction = new Ext.Action({
            scope: this,
            text: this.translation._('Dial'),
            iconCls: 'action_DialNumber',
            handler : function(){
                var form = this.getForm();
                
                if (form.isValid()) {
                    Ext.Ajax.request({
                        url: 'index.php',
                        params: {
                            method: 'Phone.dialNumber',
                            number: form.findField('phoneNumber').getValue(),
                            phoneId: form.findField('phoneId').getValue(),
                            lineId: form.findField('lineId').getValue() 
                        },
                        success: function(_result, _request){
                            Ext.getCmp('dialerWindow').close();
                        },
                        failure: function(response, request){
                            var responseText = Ext.util.JSON.decode(response.responseText);
                            Ext.Msg.show({
                               title:   this.translation._('Error'),
                               msg:     (responseText.data.message) ? responseText.data.message : this.translation._('Not possible to dial.'),
                               icon:    Ext.MessageBox.ERROR,
                               buttons: Ext.Msg.OK
                            });
                        },
                        scope: this
                    });
                }
            }
        });

        this.buttons = [
            this.cancelAction,
            this.dialAction
        ];
        
        /************** other initialisation ****************/
        
        this.initMyFields.defer(300, this);

        Tine.Phone.DialerPanel.superclass.initComponent.call(this);
    },
    
    /**
     * init form fields
     * 
     * @todo add prefered phone/line selections
     */
    initMyFields: function() {
        // focus number field or set initial value
        if (this.number != null) {
            this.getForm().findField('phoneNumber').setValue(this.number);
        } else {
            this.getForm().findField('phoneNumber').focus();
        }

        // get combos
        var phoneCombo = this.getForm().findField('phoneId');
        var lineCombo = this.getForm().findField('lineId');
        
        // select first combo values
        if(! phoneCombo.getState() && this.phoneStore.getAt(0)) {
            phoneCombo.setValue(this.phoneStore.getAt(0).id);
        } else {
            // update line store again (we need this, because it is changed when dlg is opened the second time)
            this.setLineStore(phoneCombo.getValue());
        }
        var firstLine = this.linesStore.getAt(0);
        if (firstLine) {
            this.getForm().findField('lineId').setValue(firstLine.id);
        }
    },
    
    /**
     * get values from phones store
     */
    setLineStore: function(phoneId) {
        
        if (this.linesStore == null) {
           this.linesStore = new Ext.data.Store({});
        } else {
            // empty store
            this.linesStore.removeAll();
        }
        
        var form = this.getForm();
        
        if (phoneId == null) {
            if (form) {
                phoneId = form.findField('phoneId').getValue();
            } else if (this.phoneStore.getAt(0)){
                // get first phone
                phoneId = this.phoneStore.getAt(0).id;
            } else {
                return;
            }
        }

        var phone = this.phoneStore.getById(phoneId);

        if(phone) {
            for(var i=0; i<phone.data.lines.length; i++) {
                var lineRecord = new Tine.Voipmanager.Model.SnomLine(phone.data.lines[i], phone.data.lines[i].id);
                this.linesStore.add(lineRecord);
            }
        }
        
        // disable lineCombo if only 1 line available
        if (form) {
            var lineCombo = form.findField('lineId');
            var count = this.linesStore.getCount();
            lineCombo.setDisabled(count <= 1);
            
            if (count) {
                // set first line
                lineCombo.setValue(this.linesStore.getAt(0).id);
            }
        }
    }
});