Ext.namespace('Zarafa.plugins.meet.ui');
Zarafa.plugins.meet.ui.AddMeetingDialog = Ext.extend(Zarafa.core.ui.ContentPanel, {

  constructor: function(config){
    config = config || {};
    var subj = 'xsedf';
    if(config.source && config.source.record){
      subj = config.source.record.get('subject')
    }
    config = Ext.applyIf(config, {
      xtype: 'meet_addmeetingdialog',
      layout: 'form',
      title: _('Add meeting'),
      width: 320,
      height: 135,
      style: {
        maxHeight: '135px'
      }, 
      items: [
        {
          xtype: 'displayfield',
          hideLabel: true,
          value: _('Room name:'),
          style: {
            marginTop: '5px',
            marginLeft: '5px'
          },
        },{
          xtype: 'textfield',
          hideLabel: true,
          value: subj,
          ref: 'roomNameBox',
          style: {
            marginTop: '0px',
            marginLeft: '5px',
            paddingRight: '0px',
            width: '95%'
          },
          listeners: {
            blur: this.onRoomNameBlur.bind(this)
          }
        },{
          xtype: 'displayfield',
          hideLabel: true,
          value: _('Room URL:'),
          style: {
            marginTop: '5px',
            marginLeft: '5px'
          },
        },{
          xtype: 'textfield',
          hideLabel: true,
          ref: 'roomUrlBox',
          style: {
            marginTop: '0px',
            marginLeft: '5px',
            paddingRight: '0px',
            width: '95%'
          }
        },{
          xtype: 'button',
          text: _('Add meeting'),
          scope: this,
          handler: this.addMeeting,
          style: {
            marginTop: '0px',
            marginLeft: '5px',
            paddingRight: '0px',
            width: '95%'
          }
        }
      ]
    });

    Zarafa.plugins.meet.ui.AddMeetingDialog.superclass.constructor.call(this, config);
  },

  onRoomNameBlur: function(){
    this.roomUrlBox.setValue(container.getSettingsModel().get('zarafa/v1/plugins/meet/server') + this.roomNameBox.getValue().replace(/[^a-zA-Z0-9\-]/g, '_').replace(/_{2,}/g,  '_').replace(/^_+|_+$/g, ''))
  },
  
  addMeeting: function(){
    if(this.source && this.source.record){
      this.source.record.jitsiCurrentUrl = this.roomUrlBox.getValue();
      var edf = null;
      switch(this.source.record.get('message_class')){
        case 'IPM.Note': //Mail
          edf = this.source.ownerCt.ownerCt.editorField;
          break;
        case 'IPM.Appointment':
          var oloc = this.source.record.get('location');
          if(oloc && !container.getSettingsModel().get('zarafa/v1/plugins/meet/locationoverride')){
            this.source.record.set('location', oloc + ' / ' + this.source.record.jitsiCurrentUrl);
          }else{
            this.source.record.set('location', this.source.record.jitsiCurrentUrl);
          }
          if(!container.getSettingsModel().get('zarafa/v1/plugins/meet/noinvitation')){
            edf = this.source.ownerCt.ownerCt.appointmentTab.editorField;
          }
      }
      if(edf){
        var iurl = this.source.record.jitsiCurrentUrl;
        var itpl = container.getSettingsModel().get('zarafa/v1/plugins/meet/invitationmessage') || '\n%url%\n';
        if(edf.isHtmlEditor()){
          iurl = '<a href=' + iurl + '>' + iurl + '</a>';
          itpl = itpl.replace(/(\r\n|\n|\r)/gm, '<br/>');
        }
        edf.insertAtCursor(itpl.replace(/%url%/g, iurl));
      }
    }
    this.doClose()
  }

});
Ext.reg('meet_addmeetingdialog', Zarafa.plugins.meet.ui.AddMeetingDialog);
Ext.namespace('Zarafa.plugins.meet');

Zarafa.plugins.meet.Plugin = Ext.extend(Zarafa.core.Plugin, {
  
  plugin: undefined,
  
  initPlugin: function(){
    Zarafa.core.data.SharedComponentType.addProperty('plugins.meet.panel');
    Zarafa.core.data.SharedComponentType.addProperty('plugins.meet.addmeetingdialog');
    this.registerInsertionPoint('context.settings.categories', this.createSettingsCategory, this);
    if(!container.getSettingsModel().get('zarafa/v1/plugins/meet/hidetabbarbutton')){
      this.registerInsertionPoint('main.toolbar.actions.last', this.createToolbarButton, this);
    }
    this.registerInsertionPoint('context.calendar.appointmentcontentpanel.toolbar.actions', this.createAddMeetingButton, this);
    this.registerInsertionPoint('context.calendar.appointmentcontentpanel.toolbar.actions', this.createJoinMeetingButton, this);
    this.registerInsertionPoint('context.mail.mailcreatecontentpanel.toolbar.actions', this.createAddMeetingButton, this);
    if(!container.getSettingsModel().get('zarafa/v1/plugins/meet/nolocationfix')){
      var Zarafa_calendar_dialogs_AppointmentTab_doSetLocation_or = Zarafa.calendar.dialogs.AppointmentTab.prototype.doSetLocation;
      Zarafa.calendar.dialogs.AppointmentTab.prototype.doSetLocation = function(){
        if('meetCurrentUrl' in this.record && arguments[0].indexOf(this.record.meetCurrentUrl) < 0){
          if(!container.getSettingsModel().get('zarafa/v1/plugins/meet/locationoverride')){
            arguments[0] += (arguments[0] ? ' / ' : '') + this.record.meetCurrentUrl;
          }else{
            arguments[0] = this.record.meetCurrentUrl;
          }
        }
        Zarafa_calendar_dialogs_AppointmentTab_doSetLocation_or.apply(this, arguments);
      };
      var Zarafa_calendar_dialogs_AppointmentTab_onFieldChange_or = Zarafa.calendar.dialogs.AppointmentTab.prototype.onFieldChange;
      Zarafa.calendar.dialogs.AppointmentTab.prototype.onFieldChange = function(){
        if(arguments[0].getName() == 'location' && 'meetCurrentUrl' in this.record && arguments[1].indexOf(this.record.meetCurrentUrl) < 0){
          //If the user manually removes the url from the location, prevent adding it again if the location gets set
          delete this.record.meetCurrentUrl;
        }
        Zarafa_calendar_dialogs_AppointmentTab_onFieldChange_or.apply(this, arguments);
      };
    }
  }, 
  
  createSettingsCategory: function(){
    return {
      xtype: 'grommunio.meet.settingscategory',
      plugin: this
    };
  },
  
  createToolbarButton: function(){
		return [{
			newMenuIndex: 10,
			xtype: 'button',
			scale: 'large',
			tooltip: 'Meet',
			iconCls: 'icon_meet_32',
			handler: this.onToolbarButtonClick,
			scope: this,
			}];
	},
  
  createAddMeetingButton: function(){
    return {
      xtype: 'button',
      text: _('Add meeting'),
      iconCls: 'icon_meet',
      handler: this.onAddMeetingButtonClick,
      scope: this,
      plugins: ['zarafa.recordcomponentupdaterplugin'],
      tooltip: _('Shift-click for advanced settings'),
      update: function(record, contentReset){
        this.record = record;
        if ((new RegExp(container.getSettingsModel().get('zarafa/v1/plugins/meet/server').replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '[-a-zA-Z0-9()@:%_\+.~#?&\/=]+')).test(record.get('location'))) {
          this.setDisabled(true);
        } else {
          this.setDisabled(false);
        }
      }
    };
  },
  
  createJoinMeetingButton: function(){
    return {
      xtype: 'button',
      text: _('Join webmeeting'),
      iconCls: 'icon_meet',
      handler: this.onJoinMeetingButtonClick,
      scope: this,
      plugins: ['zarafa.recordcomponentupdaterplugin'],
      update: function(record, contentReset){
        this.record = record;
        if (/https?:\/\/[a-zA-Z0-9-\.]+(?:\/[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)?/.test(record.get('location'))) {
          this.setDisabled(false);
        } else {
          this.setDisabled(true);
        }
      }
    };
  },
  
  onAddMeetingButtonClick: function(button,  evt){
    if(evt.shiftKey){
      Zarafa.core.data.UIFactory.openLayerComponent(Zarafa.core.data.SharedComponentType['plugins.meet.addmeetingdialog'], null, {modal : true, source: button});
      return
    }
    var hash = 0, i, chr;
    var agent = container.getUser().getUserName() + navigator.userAgent + (new Date()).valueOf();
    for (i = 0; i < agent.length; i++) {
      chr = agent.charCodeAt(i);
      hash = ((hash << 5) - hash) + chr;
      hash |= 0;
    }
    if(hash < 0) hash += 2147483647;
    var mname = '';
    if(!container.getSettingsModel().get('zarafa/v1/plugins/meet/mname_nosubject')){
      mname += (button.record.get('subject') || 'meet').replace(/[^a-zA-Z0-9\-@\.]/g, '_').replace(/_{2,}/g,  '_').replace(/^_+|_+$/g, '') + '-';
    }
    if(!container.getSettingsModel().get('zarafa/v1/plugins/meet/mname_noorganizer')){
      mname += container.getUser().getUserName().replace(/\./g, "_").replace("@", "_") + '-';
    }
    button.record.meetCurrentUrl = container.getSettingsModel().get('zarafa/v1/plugins/meet/server') + mname + hash.toString(16);
    var edf = null;
    switch(button.record.get('message_class')){
      case 'IPM.Note':
        edf = button.ownerCt.ownerCt.editorField;
        break;
      case 'IPM.Appointment':
        var oloc = button.record.get('location');
        if(oloc && !container.getSettingsModel().get('zarafa/v1/plugins/meet/locationoverride')){
          button.record.set('location', oloc + ' / ' + button.record.meetCurrentUrl);
        }else{
          button.record.set('location', button.record.meetCurrentUrl);
        }
        if(container.getSettingsModel().get('zarafa/v1/plugins/meet/noinvitation')){
          return;
        }
        edf = button.ownerCt.ownerCt.appointmentTab.editorField;
        break
    }
    if(edf){
      var iurl = button.record.meetCurrentUrl;
      var itpl = container.getSettingsModel().get('zarafa/v1/plugins/meet/invitationmessage') || '\n%url%\n';
      if(edf.isHtmlEditor()){
        iurl = '<a href=' + iurl + '>' + iurl + '</a>';
        itpl = itpl.replace(/(\r\n|\n|\r)/gm, '<br/>');
      }
      edf.insertAtCursor(itpl.replace(/%url%/g, iurl));
    }
  },
  
  onJoinMeetingButtonClick: function(button){
    var murl = /https?:\/\/[a-zA-Z0-9-\.]+(?:\/[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)?/.exec(button.record.get('location'))
    if(murl){
      this.openMeeting(murl[0], button.record.get('subject'));
    }
  },
  
  onToolbarButtonClick: function(){
    this.openMeeting(container.getSettingsModel().get('zarafa/v1/plugins/meet/server'), 'Meet');
  }, 
  
  openMeeting: function(meetingurl, meetingname){
    switch(container.getSettingsModel().get('zarafa/v1/plugins/meet/openin')){
      case 'browser':
        window.open(meetingurl);
        break;
      case 'popup':
          window.open(meetingurl, '_blank', 'location=no,height=768,width=1024,scrollbars=yes,status=yes');
        break;
      default:
        Zarafa.core.data.UIFactory.openLayerComponent(
          Zarafa.core.data.SharedComponentType['plugins.meet.panel'],
          null,
          {
            url: meetingurl,
            title: 'Meet',
            iconCls : 'icon_meet',
            tabOrder: (new Date()).valueOf()
          }
        );
        break;
    }
  }, 
  
  bidSharedComponent: function(type, record){
      var bid = -1;
      switch(type){
        case Zarafa.core.data.SharedComponentType['plugins.meet.panel']:
          bid = 1;
          break;
        case Zarafa.core.data.SharedComponentType['plugins.meet.addmeetingdialog']:
          bid = 1;
          break;
      }
      return bid;
  },
  
  getSharedComponent: function(type, record){
    var component;
    switch(type){
      case Zarafa.core.data.SharedComponentType['plugins.meet.panel']:
        return Zarafa.plugins.meet.ui.ContentPanel;
      case Zarafa.core.data.SharedComponentType['plugins.meet.addmeetingdialog']:
        return Zarafa.plugins.meet.ui.AddMeetingDialog;
    }
  },
  
});

Zarafa.onReady(function(){
  container.registerPlugin(new Zarafa.core.PluginMetaData({
    name: 'meet',
    displayName: 'Meet',
    //about: Zarafa.plugins.meet.ABOUT,
    pluginConstructor: Zarafa.plugins.meet.Plugin
  }));
});
Ext.namespace('Zarafa.plugins.meet');
Zarafa.plugins.meet.SettingsCategory = Ext.extend(Zarafa.settings.ui.SettingsCategory, {

  constructor: function(config){
    config = config || {};
    Ext.applyIf(config, {
      title: 'Meet',
      categoryIndex: 9947,
      xtype: 'grommunio.meet.settingscategory',
      iconCls: 'icon_meet',
      items: [{
        xtype: 'grommunio.meet.settingswidget',
        settingsContext: config.settingsContext
      }]
    });
    Zarafa.plugins.meet.SettingsCategory.superclass.constructor.call(this, config);
  }

});
Ext.reg('grommunio.meet.settingscategory', Zarafa.plugins.meet.SettingsCategory);

Zarafa.plugins.meet.SettingsWidget = Ext.extend(Zarafa.settings.ui.SettingsWidget, {

  constructor: function(config){
    config = config || {};
    Ext.applyIf(config, {
      xtype: 'grommunio.meet.settingswidget',
      title: 'Meet',
      layout: 'form',
      items: [
        {
          xtype: 'displayfield',
          hideLabel: true,
          value: _('Open meeting in:')
        },{
          xtype: 'radiogroup',
          ref: 'openInRadio',
          hideLabel: true,
          columns: 1,
          items: [
            {
              xtype: 'radio',
              name: 'openin',
              inputValue: 'web',
              boxLabel: _('Web tab')
            },{
              xtype: 'radio',
              name: 'openin',
              inputValue: 'popup',
              boxLabel: 'Popup'
            },{
              xtype: 'radio',
              name: 'openin',
              inputValue: 'browser',
              boxLabel: _('Browser window')
            }
          ]
        },{
          xtype: 'checkbox',
          ref: 'hideTabbarButtonCheckbox',
          boxLabel: _('Hide the button in the main toolbar'),
          checked: false,
          hideLabel : true,
          style: 'margin-top: 5px',
        },{
          xtype: 'checkbox',
          ref: 'mnameAddSubject',
          boxLabel: _('Add the subject to the room name'),
          checked: true,
          hideLabel : true,
          style: 'margin-top: 5px',
        },{
          xtype: 'checkbox',
          ref: 'mnameAddOrganizer',
          boxLabel: _('Add the organizer name to the room name'),
          checked: true,
          hideLabel : true,
          style: 'margin-top: 5px',
        },{
          xtype: 'checkbox',
          ref: 'locationAddCheckbox',
          boxLabel: _('Add the URL to the meeting location rather than overwriting it'),
          checked: true,
          hideLabel : true,
          style: 'margin-top: 5px',
        },{
          xtype: 'checkbox',
          ref: 'locationFixCheckbox',
          boxLabel: _('Prevent the URL in the meeting location from being overridden automatically (ex: when adding a meetingroom)') + '<span class="k-settings-label-minor">(' + _('If you have problems when creating meetings, try disabling this setting') + ')</span>',
          checked: true,
          hideLabel : true,
          style: 'margin-top: 5px',
        },{
          xtype: 'checkbox',
          ref: 'addInvitationCheckbox',
          boxLabel: _('Add an invitation to the appointment description'),
          checked: true,
          hideLabel : true,
          style: 'margin-top: 5px',
        },{
          xtype: 'displayfield',
          hideLabel: true,
          style: 'margin-top: 5px',
          value: _('Invitation text') + ': <span class="k-settings-label-minor">(' + _('must contain %url% as a placeholder for the meeting link, empty the textbox to reset to default') + ')</span>',
        },{
          xtype: 'textarea',
          ref: 'invitationEditor',
          hideLabel: true,
          grow: true,
          anchor: '100%',
        }
      ]
    });
    Zarafa.plugins.meet.SettingsWidget.superclass.constructor.call(this, config);
  },

  update: function(settingsModel){
    this.openInRadio.setValue(settingsModel.get('zarafa/v1/plugins/meet/openin') || 'web');
    this.hideTabbarButtonCheckbox.setValue(settingsModel.get('zarafa/v1/plugins/meet/hidetabbarbutton'));
    this.locationAddCheckbox.setValue(!settingsModel.get('zarafa/v1/plugins/meet/locationoverride'));
    this.locationFixCheckbox.setValue(!settingsModel.get('zarafa/v1/plugins/meet/nolocationfix'));
    this.addInvitationCheckbox.setValue(!settingsModel.get('zarafa/v1/plugins/meet/noinvitation'));
    this.invitationEditor.setValue(settingsModel.get('zarafa/v1/plugins/meet/invitationmessage') || '');
    this.mnameAddSubject.setValue(!container.getSettingsModel().get('zarafa/v1/plugins/meet/mname_nosubject'));
    this.mnameAddOrganizer.setValue(!container.getSettingsModel().get('zarafa/v1/plugins/meet/mname_noorganizer'));
  },

  updateSettings: function(settingsModel){
    settingsModel.beginEdit();
    if(settingsModel.get('zarafa/v1/plugins/meet/hidetabbarbutton') != this.hideTabbarButtonCheckbox.checked || settingsModel.get('zarafa/v1/plugins/meet/nolocationfix') == this.locationFixCheckbox.checked){
      settingsModel.requiresReload = true;
    }
    settingsModel.set('zarafa/v1/plugins/meet/openin', this.openInRadio.getValue().inputValue);
    settingsModel.set('zarafa/v1/plugins/meet/hidetabbarbutton', this.hideTabbarButtonCheckbox.checked);
    settingsModel.set('zarafa/v1/plugins/meet/locationoverride', !this.locationAddCheckbox.checked);
    settingsModel.set('zarafa/v1/plugins/meet/nolocationfix', !this.locationFixCheckbox.checked);
    settingsModel.set('zarafa/v1/plugins/meet/noinvitation', !this.addInvitationCheckbox.checked);
    settingsModel.set('zarafa/v1/plugins/meet/mname_nosubject', !this.mnameAddSubject.checked);
    settingsModel.set('zarafa/v1/plugins/meet/mname_noorganizer', !this.mnameAddOrganizer.checked);
    if(this.invitationEditor.getValue()){
      if(this.invitationEditor.getValue() != settingsModel.get('zarafa/v1/plugins/meet/invitationmessage')){
        settingsModel.set('zarafa/v1/plugins/meet/invitationmessage', this.invitationEditor.getValue())
      }
    }else{
      settingsModel.remove('zarafa/v1/plugins/meet/invitationmessage');
      settingsModel.requiresReload = true;
    }
    settingsModel.endEdit();
  },

});
Ext.reg('grommunio.meet.settingswidget', Zarafa.plugins.meet.SettingsWidget);
Ext.namespace('Zarafa.plugins.meet.ui');

/**
 * @class Zarafa.plugins.meet.ui.ContentPanel
 * @extends Zarafa.core.ui.ContentPanel
 */
Zarafa.plugins.meet.ui.ContentPanel = Ext.extend(Zarafa.core.ui.ContentPanel, {
  /**
   * @constructor
   * @param config Configuration structure
   */
  constructor : function(config)
  {
    config = config || {};

    Ext.applyIf(config, {
      xtype: 'meet_contentpanel',
      layout : 'fit',
      iconCls: config.iconCls,
      border: false,
      items : [{
        xtype: 'meet_panel',
        url: config.url,
        tabOrder: config.tabOrder
      }]
    });

    Zarafa.plugins.meet.ui.ContentPanel.superclass.constructor.call(this, config);
  }
});
Ext.reg('meet_contentpanel', Zarafa.plugins.meet.ui.ContentPanel);

/**
 * @class Zarafa.plugins.meet.ui.Panel
 * @extends Ext.Panel
 */
Zarafa.plugins.meet.ui.Panel = Ext.extend(Ext.Panel, {
  iframeId : undefined,
  isLoadMaskShown : false,
  loadMask : undefined,
  constructor : function(config)
  {
    config = config || {};
    this.iframeId = 'meet-iframe-'+config.tabOrder;
    this.tag = 'iframe';

    Ext.applyIf(config, {
      xtype: 'meet_panel',
      layout : 'fit',
      header: false,
      html : {
        tag: this.tag,
        id: this.iframeId,
        cls: 'meet-iframe',
        src: config.url,
        style: 'display:block',
        allow: 'microphone *; camera *; display-capture *;'
      },
      listeners: {
        afterrender: this.onAfterRender,
        scope: this
      }
    });

    Zarafa.plugins.meet.ui.Panel.superclass.constructor.call(this, config);
  },

  onAfterRender: function()
  {
    this.showLoadMask();

    var iframe = document.getElementById(this.iframeId);
    var event = (this.tag === 'webview') ? 'contentload' : 'load';

    iframe.addEventListener(event, function(){
      this.hideLoadMask();
    }.createDelegate(this));

  },

  /**
   * Handler for the dialog event of WEBVIEW elements. Will handle alert, prompt,
   * and confirm dialogs
   * @param  {Event} e The dialog event
   */
  handleDialogRequests : function(e)
  {
    // Handle alerts
    if ( e.messageType === 'alert' ) {
      window.alert(e.messageText);
    }

    // Handle confirm dialogs
    else if ( e.messageType === 'confirm' ) {
      var confirmation =  window.confirm(e.messageText);

      if ( confirmation ) {
        e.dialog.ok();
      } else {
        e.dialog.cancel();
      }
    }

    // Handle prompts
    else if ( e.messageType === 'prompt' ){
      var wprompt = window.prompt( e.messageText);

      if ( wprompt === null ){
        e.dialog.cancel();
      } else {
        e.dialog.ok(wprompt);
      }
    }

  },

  /**
   * Handler for the permissionrequest event of WEBVIEW elements. Will handle the request
   * by its type.
   * Possible types are media, geolocation, pointerLock, download, loadplugin and fullscreen.
   * For now we deny geolocation, fullscreen and pointerLock requests.
   * @param {Event} e The permissionrequest event
   */
  handlePermissionRequests : function(e)
  {
    e.preventDefault();
    switch (e.permission) {
      // Allow
      case 'download':
      case 'media':
      case 'loadplugin':
        e.request.allow();
      break;
      // Deny
      case 'pointerLock':
      case 'fullscreen':
      case 'geolocation':
        e.request.deny();
      break;
      // also deny all other, not yet known, requests
      default:
        e.request.deny();
      break;

    }
  },

  /**
   * Handler for the newwindow event of WEBVIEW elements. Will handle new windows, by
   * opening them externally in the browser.
   * @param  {Event} e The newwindow event
   */
  handleNewWindowRequests : function(e)
  {
    e.window.discard();
    //nw.Shell.openExternal(e.targetUrl);
  },

  /**
   * If {@link #showLoadMask} is enabled, this function will display
   * the {@link #loadMask}.
   * @param {Boolean} errorMask True to show an error mask instead of the loading mask.
   * @protected
   */
  showLoadMask : function(errorMask)
  {
    if (this.isLoadMaskShown === true) {
      return;
    }
    if (!this.loadMask) {
      this.loadMask = new Zarafa.common.ui.LoadMask(this.ownerCt.el);
    }

    if (errorMask) {
      this.loadMask.showError();
    } else {
      this.loadMask.show();
      this.isLoadMaskShown = true;
    }
  },

  /**
   * If {@link #showLoadMask} is enabled, and {@link #showLoadMask} has been
   * called to display the {@link #loadMask} this function will disable the
   * loadMask.
   * @protected
   */
  hideLoadMask : function()
  {
    if (this.isLoadMaskShown === false) {
      return;
    }

    if (this.loadMask) {
      this.loadMask.hide();
      this.isLoadMaskShown = false;
    }
  }

});
Ext.reg('meet_panel', Zarafa.plugins.meet.ui.Panel);
