/**
 *  Copyright © 2022-2025, Luis Andrés Lange <https://javacomm.net>
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *  ----------------------------------------------------------------------------
 *
 *  Exhibit B - "Incompatible With Secondary Licenses" Notice
 *
 *  This Source Code Form is "Incompatible With Secondary Licenses",
 *  as defined by the Mozilla Public License, v. 2.0.
 *
 *  In short:
 *  - This file may be used, modified, and distributed under MPL 2.0 only.
 *  - It may NOT be relicensed under GPL, LGPL, AGPL, or any other Secondary License.
 *
 *  Rationale:
 *  - Ensures that the code remains MPL-2.0.
 *  - Avoids legal conflicts with GPL-licensed libraries (e.g., VideoLAN).
 *  - Maximizes usability for commercial and security-critical applications.
 *
 */
package net.javacomm.client.telko;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nexuswob.gui.InputDocument;
import net.javacomm.client.gui.Verfallsdatum;
import net.javacomm.client.resource.Resource;
import net.javacomm.multilingual.MultilingualButton;
import net.javacomm.multilingual.MultilingualLabel;
import net.javacomm.multilingual.MultilingualString;
import net.javacomm.multilingual.schema.ISO639;
import net.javacomm.multilingual.schema.KEY;
import net.javacomm.share.Constants;
import net.javacomm.transfer.TransferOrganizeConferenceCall;
import net.javacomm.window.manager.Control;
import net.javacomm.window.manager.WMResource;
import net.javacomm.window.manager.WindowManagerInternalFrame;



public class JTelefonkonferenzOrganisierenFrame extends WindowManagerInternalFrame {

  private final static Logger log = LogManager.getLogger(JTelefonkonferenzOrganisierenFrame.class);
  private static final long serialVersionUID = -796792301165442969L;
  public final static int SCREEN_WIDTH = 762;
  public final static int SCREEN_HEIGHT = 630;
  public final static int BREITE = Constants.LEN_KONFERENZ_BESCHREIBUNG;

  private JPanel mainpanel = new JPanel();
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private GridBagLayout gridbag = new GridBagLayout();
  private GridBagConstraints con = new GridBagConstraints();
  private MultilingualLabel derVeranstalterMuss = new MultilingualLabel(KEY.LABEL_DER_VERANSTALTER_MUSS);
  private MultilingualLabel multilingualKonferenzname = new MultilingualLabel(KEY.LABEL_KONFERENZNAME);
  private Verfallsdatum verfallsdatum = new Verfallsdatum();
  private TreeMap<String, String> referencelist = new TreeMap<>();
  private TreeMap<String, String> alleMitglieder = new TreeMap<>();
  private TreeMap<String, String> restlicheMitglieder = new TreeMap<>();
  private JDialog einladenDialog;

  private MultilingualLabel konferenzText = new MultilingualLabel();
  private MultilingualLabel meineKonferenzenOrganisieren = new MultilingualLabel(
      KEY.LABEL_MEINE_KONFERENZEN_ORGANISIEREN
  );

  private TwoPanelList twopanel = new TwoPanelList();
  private MultilingualString multilingualTeilnehmer = new MultilingualString(KEY.LABEL_MITGLIEDER);
  private MultilingualString multilingualBenutzer = new MultilingualString(KEY.LABEL_BENUTZER);
  private MultilingualString back = new MultilingualString(KEY.STRING_BACK);
  private MultilingualString apply = new MultilingualString(KEY.STRING_APPLY);
  private MultilingualString teilnehmerliste = new MultilingualString(KEY.STRING_TEILNEHMERLISTE);
  private MultilingualString einladen = new MultilingualString(KEY.BUTTON_EINLADEN);

  private JSeparator separator = new JSeparator();
  private MultilingualButton buttonSchliessen = new MultilingualButton(KEY.BUTTON_SCHLIESSEN);
  private JTextArea textareaBeschreibung = new JTextArea();
  private JScrollPane scrollpane = new JScrollPane(textareaBeschreibung);

  private MultilingualLabel labelBeschreibung = new MultilingualLabel(KEY.STRING_BESCHREIBUNG);
  private MultilingualLabel labeltext = new MultilingualLabel(KEY.LABEL_DIE_BESCHREIBUNG_WIRD);

  private JComboBox<String> comboKonferenzname = new JComboBox<>();
  private InternalFrameAdapter internalFrameAction = new InternalFrameAdapter() {

    @Override
    public void internalFrameClosed(InternalFrameEvent event) {
      changes
          .firePropertyChange(JTelefonkonferenzOrganisierenFrame.this.getName(), Control.NULL, Control.CLOSE);
    }

  };
  private MultilingualButton buttonModify = new MultilingualButton(KEY.BUTTON_AENDERN);
  private ActionListener modifyListener = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
      if (comboKonferenzname.getSelectedItem() == null) return;
      changes.firePropertyChange(
          JTelefonkonferenzOrganisierenFrame.this.getName(), Control.NULL, Control.MODIFY
      );
    }

  };
  /**
   * Ein Platzhalter für alle Maskenelemente. Die Teilnehmerliste muss nach einem
   * Speichern neu angepasst werden.
   */
  private Map<String, TransferOrganizeConferenceCall> maske = new TreeMap<>();
  private DocumentListener documentAdapter = new DocumentListener() {

    private String text;
    private String beschreibung;

    @Override
    public void changedUpdate(DocumentEvent event) {
      check(event);
    }



    private void check(DocumentEvent event) {
      try {
        beschreibung = maske.get(getSelectedKonferenzname()).getBeschreibung();
        text = textareaBeschreibung.getText();
        if (text.equals(beschreibung)) {
          buttonModify.setForeground(WMResource.DISABLED_BUTTON_FOREGROUND);
          buttonModify.setBackground(WMResource.DISABLED_BUTTON_BACKGROUND);
          for (ActionListener al : buttonModify.getActionListeners()) {
            buttonModify.removeActionListener(al);
          }
          return;
        }
        if (buttonModify.getActionListeners().length == 0) {
          buttonModify.addActionListener(modifyListener);
          buttonModify.setForeground(WMResource.ENABLED_BUTTON_FOREGROUND);
          buttonModify.setBackground(WMResource.ENABLED_BUTTON_BACKGROUND);
        }
      }
      catch (KonferenznameException e) {
        log.info(e.getMessage());
        return;
      }
    }



    @Override
    public void insertUpdate(DocumentEvent event) {
      check(event);
    }



    @Override
    public void removeUpdate(DocumentEvent event) {
      check(event);
    }

  };
  private ZonedDateTime expiryDate;

  @SuppressWarnings("serial")
  public JTelefonkonferenzOrganisierenFrame() {

    setMaximizable(true);
    setResizable(true);
    setIconifiable(false);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    setClosable(true);

    setSize(SCREEN_WIDTH, SCREEN_HEIGHT); // +30

    mainpanel.setLayout(gridbag);
    mainpanel.setMinimumSize(new Dimension(0, 0));

    // 1. Reihe
    con.gridx = 0;
    con.gridy = 0;
    con.gridwidth = 1;
    con.insets = new Insets(12, 0, 0, 0);
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.CENTER;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(multilingualKonferenzname, con);
    mainpanel.add(multilingualKonferenzname);

    // 2. Reihe
    con.gridx = 0;
    con.gridy = 1;
    con.gridwidth = 1;
    con.insets = new Insets(0, 12, 12, 0);
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.WEST;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(comboKonferenzname, con);
    mainpanel.add(comboKonferenzname);
    comboKonferenzname.setMaximumRowCount(7);

    con.gridx = 1;
    con.gridy = 1;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.insets = new Insets(0, 12, 0, 12);
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.NORTH;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(meineKonferenzenOrganisieren, con);
    mainpanel.add(meineKonferenzenOrganisieren);

    // 3. Reihe

    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.insets = new Insets(6, 0, 0, 0);
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.CENTER;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(labelBeschreibung, con);
    mainpanel.add(labelBeschreibung);

    // 4. Reihe
    con.gridx = 0;
    con.gridy = 3;
    con.gridwidth = 1;
    con.gridheight = 2;
    con.insets = new Insets(0, 12, 0, 0);
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.NORTH;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(scrollpane, con);
    mainpanel.add(scrollpane);
    scrollpane.setMaximumSize(new Dimension(BREITE, 90));
    scrollpane.setMinimumSize(new Dimension(BREITE, 90));
    scrollpane.setPreferredSize(new Dimension(BREITE, 90));
    textareaBeschreibung.setDocument(new InputDocument(Constants.LEN_KONFERENZ_BESCHREIBUNG));
    textareaBeschreibung.setLineWrap(true);
    textareaBeschreibung.setWrapStyleWord(true);
    textareaBeschreibung.getInputMap(JComponent.WHEN_FOCUSED)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "TAB");
    textareaBeschreibung.getActionMap().put("TAB", new AbstractAction() {

      @Override
      public void actionPerformed(ActionEvent event) {
        textareaBeschreibung.transferFocus();
      }

    });

    // 4. Reihe
    con.gridx = 1;
    con.gridy = 3;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.insets = new Insets(0, 12, 0, 12);
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.CENTER;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(buttonModify, con);
    mainpanel.add(buttonModify);
    buttonModify.setForeground(WMResource.DISABLED_BUTTON_FOREGROUND);
    buttonModify.setBackground(WMResource.DISABLED_BUTTON_BACKGROUND);

    // 5. Reihe
    con.gridx = 1;
    con.gridy = 4;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.insets = new Insets(0, 12, 12, 12);
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.SOUTHWEST;
    con.weightx = 1.0;
    con.weighty = 0.0;
    gridbag.setConstraints(labeltext, con);
    mainpanel.add(labeltext);
    labeltext.setIcon(new ImageIcon(getClass().getResource(Resource.LEFT_ARROW_34x26)));

    // 6. Reihe
    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 2;
    con.insets = new Insets(24, 12, 0, 12);
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.WEST;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(verfallsdatum, con);
    mainpanel.add(verfallsdatum);
    verfallsdatum.addVerfallsdatumListener(event -> {

      Control value = (Control) event.getNewValue();

      switch(value) {
        case CONFIRM:
          // positiv
          expiryDate = (ZonedDateTime) event.getOldValue();
          changes.firePropertyChange(event);
          break;
        case EXPIRY_DATE:
          ZonedDateTime neueZeit = (ZonedDateTime) event.getOldValue();
          verfallsdatum.setDisabledConfirmButton(
              neueZeit
                  .equals(maske.get(comboKonferenzname.getSelectedItem().toString()).getZonedAblaufdatum())
          );
          break;
        default:
          break;
      }

    });

    // 7. Reihe
    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 2;
    con.insets = new Insets(36, 12, 0, 12);
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.WEST;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(twopanel, con);
    mainpanel.add(twopanel);
    twopanel.addTeilnehmerListener(event -> {
      // ist die Teilnehmerliste identisch mit der referenceliste

      Control value = (Control) event.getNewValue();
      switch(value) {
        case MODIFY:
          compareReferencelist(referencelist, twopanel.getLeftlist());
          break;
        case INVITE:
          changes.firePropertyChange(event);
          break;
        default:
          throw new UnsupportedOperationException(value.toString());
      }

    });

    // 8. Reihe
    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 2;
    con.insets = new Insets(24, 12, 12, 12);
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.CENTER;
    con.weightx = 0.0;
    con.weighty = 0.0;
    gridbag.setConstraints(separator, con);
    mainpanel.add(separator);

    // 9. Reihe
    con.gridx = 1;
    con.gridy++;
    con.gridwidth = 1;
    con.insets = new Insets(12, 12, 12, 12);
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.NORTHEAST;
    con.weightx = 0.0;
    con.weighty = 1.0;
    gridbag.setConstraints(buttonSchliessen, con);
    mainpanel.add(buttonSchliessen);
    buttonSchliessen.addActionListener(event -> {

      if (isSetInviteButton()) {

        Object[] options = new Object[] {back.toString(), apply.toString()};

        JOptionPane pane = new JOptionPane(
            teilnehmerliste.toString(), JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null,
            options
        );
        einladenDialog = pane.createDialog(JTelefonkonferenzOrganisierenFrame.this, einladen.toString());
        einladenDialog.setVisible(true);

        String value = (String) pane.getValue();

        if (value.equals(back.toString())) {
          return;
        }
        else if (value.equals(apply.toString())) {
          changes.firePropertyChange(
              JTelefonkonferenzOrganisierenFrame.class.getName(), Control.NULL, Control.INVITE
          );
          try {
            setClosed(true);
          }
          catch (PropertyVetoException e) {
            log.error(e.getMessage(), e);
          }
        }
        return;
      }

      try {
        setClosed(true);
      }
      catch (PropertyVetoException e) {
        log.error(e.getMessage(), e);
      }
    });

    setContentPane(mainpanel);

    addInternalFrameListener(internalFrameAction);

  }



  public synchronized void addTelefonkonferenzListener(PropertyChangeListener listener) {
    changes.addPropertyChangeListener(listener);
  }



  /**
   *
   *
   * @param referencelist
   *                        alle Teilnehmer nach der Konferenzauswahl
   * @param teilnehmerliste
   *                        alle aktuellen Teilnehmer
   */
  private void compareReferencelist(TreeMap<String, String> referencelist, List<String> teilnehmerliste) {
    if (teilnehmerliste.size() == 0) {
      setInviteButton(false);
      return;
    }
    if (referencelist.size() != teilnehmerliste.size()) {
      setInviteButton(true);
      return;
    }
    if (!teilnehmerliste.containsAll(referencelist.keySet())) {
      setInviteButton(true);
      return;
    }
    setInviteButton(false);
  }



  /**
   * Die Konferenzbeschreibung.
   *
   * @return ein Text
   */
  public String getBeschreibung() {
    return textareaBeschreibung.getText();
  }



  @Override
  public Dimension getMinimumSize() {
    return new Dimension(600, JTelefonkonferenzOrganisierenFrame.SCREEN_HEIGHT);
  }



  /**
   * Die Referenzliste vor einem Speichern.
   * 
   * @return
   */
  public TreeMap<String, String> getReferenceList() {
    return referencelist;
  }



  /**
   * Alle restlichen Benutzer vor einem Speichern.
   * 
   * @return
   */
  public TreeMap<String, String> getRestlicheMitglieder() {
    return restlicheMitglieder;
  }



  /**
   * Die ausgewählte Konferenz. Der Konferenzname kann {@code null} sein.
   *
   * @return der Konferenzname
   * @throws KonferenznameException
   *                                wird geworfen, wenn der Name {@code null} ist
   */
  public String getSelectedKonferenzname() throws KonferenznameException {
    Object konferenzname = comboKonferenzname.getSelectedItem();
    if (konferenzname == null) throw new KonferenznameException("konferenzname is not present");
    return konferenzname.toString();
  }



  /**
   * Die aktuelle Teilnehmerliste in der Maske.
   *
   * @return alle Teilnehmerpaare (Nicknames/Userid)
   *
   * @throws KonferenznameException
   */
  public TreeMap<String, String> getTeilnehmerliste() throws KonferenznameException {
    TreeMap<String, String> teilnehmer = new TreeMap<>();
    List<String> nicknames = twopanel.getLeftlist(); // die Liste kann leer sein
    for (String nickname : nicknames) {
      teilnehmer.put(nickname, alleMitglieder.get(nickname)); // finde Userid
    }
    return teilnehmer;
  }



  public ZonedDateTime getVerfallsdatum() {
    return expiryDate;
  }



  /**
   * Ist der Einladen-Knopf aktiv?
   *
   * @return {@code true}, der Knopf ist aktiv
   */
  boolean isSetInviteButton() {
    return twopanel.getEnabledButton();
  }



  public synchronized void removeAllListener() {

    for (ItemListener il : comboKonferenzname.getItemListeners()) {
      comboKonferenzname.removeItemListener(il);
    }

    textareaBeschreibung.getDocument().removeDocumentListener(documentAdapter);
    buttonModify.removeActionListener(modifyListener);

    for (PropertyChangeListener pl : changes.getPropertyChangeListeners()) {
      changes.removePropertyChangeListener(pl);
    }
    removeInternalFrameListener(internalFrameAction);
    verfallsdatum.removeAllListener();
    twopanel.removeAllListener();
  }



  public synchronized void removeTelefonkonferenzListener(PropertyChangeListener listener) {
    changes.removePropertyChangeListener(listener);
  }



  /**
   * Eine Konferenz wird ausgewählt.
   *
   * @param konferenzname
   *                      der Konferenzname
   */
  public void selectKonferenz(String konferenzname) {
    comboKonferenzname.setSelectedItem(konferenzname);
  }



  /**
   * Alle Konferenzteilnehmer werden übergeben.
   *
   *
   * @param teilnehmer
   *                   die Teilnehmer, n-Paare (Nickname, Userid)
   */
  private void setAlleTeilnehmer(TreeMap<String, String> teilnehmer) {

    // TODO jede Konferenz hat ihre Referenzliste
    // das muss berücksichtigt werden

    referencelist.clear();
    referencelist.putAll(teilnehmer);
    alleMitglieder.putAll(teilnehmer);
    ArrayList<String> teilnehmerNicknames = new ArrayList<>(teilnehmer.keySet());
    twopanel.clearLeftlist();
    twopanel.setLeftlist(teilnehmerNicknames);

    // Vergleich anstellen
    compareReferencelist(referencelist, twopanel.getLeftlist());

  }



  @Override
  public void setBackgroundGradient(Color top, Color bottom) {
    windowManager.setBackgroundGradient(top, bottom);
  }



  /**
   * Diese Methode wird aufgerufen, wenn der Besprechungstext gespeichert werden
   * konnte.
   *
   *
   * @param konferenzname
   *                         der Konferenzname
   * @param besprechungstext
   *                         der gespeicherte Besprechungstext
   */
  public void setBesprechung(String konferenzname, String besprechungstext) {
    TransferOrganizeConferenceCall value = maske.get(konferenzname);
    value.setBeschreibung(besprechungstext);
    buttonModify.setForeground(WMResource.DISABLED_BUTTON_FOREGROUND);
    buttonModify.setBackground(WMResource.DISABLED_BUTTON_BACKGROUND);
    buttonModify.removeActionListener(modifyListener);
  }



  /**
   * Alle Maskenelemente werden übergeben.
   *
   * @param data
   *             die Maskeninhalte
   *
   */
  public void setData(List<TransferOrganizeConferenceCall> data) {

    alleMitglieder.clear();
    textareaBeschreibung.getDocument().removeDocumentListener(documentAdapter);
    for (ItemListener il : comboKonferenzname.getItemListeners()) {
      comboKonferenzname.removeItemListener(il);
    }

    maske.clear();
    for (TransferOrganizeConferenceCall transfer : data) {
      comboKonferenzname.addItem(transfer.getKonferenzname());
      maske.put(transfer.getKonferenzname(), transfer);
    }
    // Init-Werte
    try {

      String konferenzname = getSelectedKonferenzname();

      // Fordere restliche Mitglieder an.
      changes.firePropertyChange(
          JTelefonkonferenzOrganisierenFrame.this.getName(), Control.NULL, Control.REMAINING_MEMBERS
      );

      textareaBeschreibung.setText(maske.get(konferenzname).getBeschreibung());
      textareaBeschreibung.getDocument().addDocumentListener(documentAdapter);
      verfallsdatum.setVerfallsdatum(maske.get(konferenzname).getZonedAblaufdatum());
      TreeMap<String, String> teilnehmer = maske.get(konferenzname).getTeilnehmer();
      setAlleTeilnehmer(teilnehmer);
      // referencelist

      comboKonferenzname.addItemListener(event -> {
        if (event.getStateChange() == ItemEvent.SELECTED) {
          textareaBeschreibung.setText(maske.get(event.getItem().toString()).getBeschreibung());
          verfallsdatum.setVerfallsdatum(maske.get(event.getItem().toString()).getZonedAblaufdatum());
          alleMitglieder.clear();
          changes.firePropertyChange(
              JTelefonkonferenzOrganisierenFrame.this.getName(), Control.NULL, Control.REMAINING_MEMBERS
          );
          try {
            setAlleTeilnehmer(maske.get(getSelectedKonferenzname()).getTeilnehmer());
          }
          catch (KonferenznameException e) {}

        }
      });
    }
    catch (KonferenznameException e) {
      // Alle Komponenten deaktivieren oder deren Listener
//      textareaBeschreibung.getDocument().removeDocumentListener(documentAdapter);
      verfallsdatum.setDisableVerfallsdatum();
    }

  }



  /**
   * Die Teilnehmerliste wurde gerade gespeichert.
   *
   */
  public void setInviteButton(boolean enabled) {
    twopanel.setEnabledButton(enabled);
  }



  @Override
  public void setLanguage(ISO639 code) {
    derVeranstalterMuss.setLanguage(code);
    verfallsdatum.setLanguage(code);
    multilingualKonferenzname.setLanguage(code);
    konferenzText.setLanguage(KEY.LABEL_ERSTELLE_UEBER, code);

    setLanguage(KEY.STRING_ORGANISIEREN, code); // Fenstertitel

    multilingualTeilnehmer.setLanguage(code);
    twopanel.setLeftlistName(multilingualTeilnehmer.toString());
    multilingualBenutzer.setLanguage(code);
    twopanel.setRightlistName(multilingualBenutzer.toString());
    twopanel.setLanguage(code);

//    knopfleiste.setLanguage(code);
    meineKonferenzenOrganisieren.setLanguage(code);
    labelBeschreibung.setLanguage(code);
    labeltext.setLanguage(code);
    buttonSchliessen.setLanguage(code);

    buttonModify.setLanguage(code);
    back.setLanguage(code);
    apply.setLanguage(code);
    teilnehmerliste.setLanguage(code);
    einladen.setLanguage(code);

  }



  /**
   * Der Organisator hat die Konferenz eingerichtet.
   *
   * @param organisator
   *                    ein Nickname
   */
  public void setOrganisatorNickname(String organisator) {
    twopanel.setVeto(organisator);
  }



  /**
   * Die Methode wird nach dem Speichern einer neuen Teilnehmerliste aufgerufen.
   *
   *
   * @param konferenzname
   *                       die Konferenz
   * @param nicknameUserid
   *                       die gerade neu gespeicherte Teilnehmerliste
   */
  public void setReferenzliste(String konferenzname, TreeMap<String, String> nicknameUserid) {
    setAlleTeilnehmer(nicknameUserid);
    // maske neu anpassen
    maske.get(konferenzname).setTeilnehmer(nicknameUserid);
  }



  /**
   * Alle möglichen Mitglieder, die Teilnehmer einer Konferenz werden können.
   *
   * @param konferenzraum
   *                      der Konferenzname
   * @param nickameUserid
   *                      n-Paare (Nickname/Userid)
   *
   */
  public void setRestlicheMitglieder(String konferenzraum, Map<String, String> nickameUserid) {
    restlicheMitglieder = new TreeMap<>(nickameUserid);
    alleMitglieder.putAll(nickameUserid);
    twopanel.clearRightlist();
    Set<String> nicknames = nickameUserid.keySet();
    twopanel.setRightlist(new ArrayList<>(nicknames));

  }



  /**
   * Diese Methode wird aufgerufen, wenn dass Verfallsdatum gespeichert werden
   * konnte.
   *
   *
   * @param konferenzname
   *                      der Konferenzname
   * @param datetime
   *                      das neue Ablaufdatum
   */
  public void setVerfallsdatum(String konferenzname, ZonedDateTime datetime) {
    TransferOrganizeConferenceCall value = maske.get(konferenzname);
    value.setZonedAblaufdatum(datetime);
    verfallsdatum.setDisabledConfirmButton(true);
  }

}
