/**
 *  Copyright © 2020-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.administer;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.AbstractAction;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.JToolTip;
import javax.swing.KeyStroke;
import javax.swing.Painter;
import javax.swing.ToolTipManager;
import javax.swing.UIDefaults;
import org.nexuswob.gui.ArrowTooltip;
import org.nexuswob.gui.InputDocument;
import org.nexuswob.gui.JToolTipBorder;
import net.javacomm.client.environment.GUI;
import net.javacomm.client.resource.Resource;
import net.javacomm.multilingual.Babelfish;
import net.javacomm.multilingual.MultilingualButton;
import net.javacomm.multilingual.MultilingualLabel;
import net.javacomm.multilingual.MultilingualString;
import net.javacomm.multilingual.MultilingualTitledBorder;
import net.javacomm.multilingual.schema.ISO639;
import net.javacomm.multilingual.schema.KEY;
import net.javacomm.protocol.Userdata;
import net.javacomm.share.Constants;
import net.javacomm.window.manager.Control;



public class JUser extends JPanel implements Babelfish {

  private static final long serialVersionUID = 4826189195967902608L;
//  private final static Logger log = LogManager.getLogger(JUpdateProfilFrame.class);

  public final static Color FOREGROUND = Resource.JQUERY_TEXTBRAUN;
  public final static Color BACKGROUND = Resource.JQUERY_ORANGE;

  private final GridBagLayout gridbag = new GridBagLayout();
  private final GridBagConstraints con = new GridBagConstraints();

  private final MultilingualLabel labelUID = new MultilingualLabel(KEY.LABEL_BENUTZER_ID);
  private final MultilingualLabel labelPassword = new MultilingualLabel(KEY.LABEL_PASSWORT);
  private final MultilingualLabel labelConfirm = new MultilingualLabel(KEY.LABEL_PASSWORT_BESTAETIGEN);
  private final MultilingualLabel labelNickname = new MultilingualLabel(KEY.LABEL_SPITZNAME);
  private final MultilingualLabel labelMail = new MultilingualLabel(KEY.LABEL_EMAIL);
  private final MultilingualString emailAdresse = new MultilingualString(KEY.STRING_EMAIL_IST_ERFORDERLICH);

  @SuppressWarnings("serial")
  private final JCheckBox boxPassword = new JCheckBox() {

    @Override
    public JToolTip createToolTip() {
      ArrowTooltip arrow = new ArrowTooltip(Resource.JQUERY_TEXTBRAUN);
      arrow.setComponent(boxPassword);
      arrow.setTextAttributes(GUI.regularFont13, Color.WHITE, Resource.JQUERY_TEXTBRAUN);
      arrow.setBorder(new JToolTipBorder(7, BACKGROUND, Resource.JQUERY_TEXTBRAUN));
      return arrow;
    }

  };
  @SuppressWarnings("serial")
  private final JCheckBox boxMail = new JCheckBox() {
    @Override
    public JToolTip createToolTip() {
      ArrowTooltip arrow = new ArrowTooltip(Resource.JQUERY_TEXTBRAUN);
      arrow.setComponent(boxMail);
      arrow.setTextAttributes(GUI.regularFont13, Color.WHITE, Resource.JQUERY_TEXTBRAUN);
      arrow.setBorder(new JToolTipBorder(7, BACKGROUND, Resource.JQUERY_TEXTBRAUN));
      return arrow;
    }
  };

  @SuppressWarnings("serial")
  private final JTextField textFieldUID = new JTextField() {
    @Override
    public JToolTip createToolTip() {
      ArrowTooltip arrow = new ArrowTooltip(Resource.JQUERY_TEXTBRAUN);
      arrow.setComponent(textFieldUID);
      arrow.setTextAttributes(GUI.regularFont13, Color.WHITE, Resource.JQUERY_TEXTBRAUN);
      arrow.setBorder(new JToolTipBorder(7, BACKGROUND, Resource.JQUERY_TEXTBRAUN));
      return arrow;
    }
  };

  @SuppressWarnings("serial")
  private final JTextField textFieldNickname = new JTextField() {
    @Override
    public JToolTip createToolTip() {
      ArrowTooltip arrow = new ArrowTooltip(Resource.JQUERY_TEXTBRAUN);
      arrow.setComponent(textFieldNickname);
      arrow.setTextAttributes(GUI.regularFont13, Color.WHITE, Resource.JQUERY_TEXTBRAUN);
      arrow.setBorder(new JToolTipBorder(7, BACKGROUND, Resource.JQUERY_TEXTBRAUN));
      return arrow;
    }
  };

  private MultilingualString hakenPassword = new MultilingualString(KEY.STRING_HAKEN);
  private MultilingualString hakenMail = new MultilingualString(KEY.STRING_HAKEN_MAIL);
  private final MultilingualString userid = new MultilingualString(KEY.STRING_BENUTZER_ID);
  private final MultilingualString passwortVerschieden = new MultilingualString(
      KEY.STRING_PASSWOERTER_STIMMEN
  );
  private final MultilingualString passwort = new MultilingualString(KEY.STRING_PASSWORT);
  private final MultilingualString spitznameTooltip = new MultilingualString(KEY.STRING_DER_SPITZNAME_IST);
  private final MultilingualString spitznameLang = new MultilingualString(KEY.STRING_SPITZNAME_LANG);
  private final JPasswordField textFieldPassword = new JPasswordField();
  private final JPasswordField textFieldConfirm = new JPasswordField();
  private final JTextField textFieldMail = new JTextField();
  private JUserColor2 slider;
  private final FocusAction focusAction = new FocusAction();
  private Color fg, bg;
  private JUserColor2 slider2;
  private final PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private final JPanel panSouth = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
  private final JUserButton button2 = new JUserButton();
  private final InputDocument docPasswd = new InputDocument(16);
  private final InputDocument docConfirm = new InputDocument(16);
  private final InputDocument docMail = new InputDocument(64);
  private final InputDocument docNickname = new InputDocument(Constants.LEN_NICKNAME);
  private final Userdata profil;

  /**
   * Die Userdaten stammen aus der Datenbank. Änderungen werden in einem neuen
   * Objekt über getUserdata zurückgegeben.
   * 
   * @param user
   */
  public JUser(Userdata user) {
    super(true);
    super.setLayout(gridbag);
    ToolTipManager.sharedInstance().setInitialDelay(200);
    ToolTipManager.sharedInstance().setDismissDelay(3000);
    profil = new Userdata();
    profil.setBackgroundColor(user.getBackgroundColor());
    profil.setMail(user.getEmail());
    profil.setForegroundColor(user.getForegroundColor());
    profil.setNickname(user.getNickname());
    profil.setPassword(user.getPassword());
    profil.setUserid(user.getUserid());
    init2(profil);
  }



  public void addUserListener(PropertyChangeListener l) {
    changes.addPropertyChangeListener(l);
  }



  public void removeUserListener(PropertyChangeListener l) {
    changes.removePropertyChangeListener(l);
  }



  public synchronized void removeAllListener() {
    for (PropertyChangeListener listener : changes.getPropertyChangeListeners()) {
      changes.removePropertyChangeListener(listener);
    }
  }



  private void background(Color color) {
    textFieldUID.setBackground(color);
    textFieldPassword.setBackground(color);
    textFieldConfirm.setBackground(color);
    textFieldMail.setBackground(color);
    textFieldNickname.setBackground(color);
    profil.setBackgroundColor(color.getRGB());
  }



  private void foreground(Color color) {
    textFieldUID.setForeground(color);
    textFieldPassword.setForeground(color);
    textFieldConfirm.setForeground(color);
    textFieldMail.setForeground(color);
    textFieldNickname.setForeground(color);
    profil.setForegroundColor(color.getRGB());
    textFieldUID.setCaretColor(color);
    textFieldPassword.setCaretColor(color);
    textFieldConfirm.setCaretColor(color);
    textFieldMail.setCaretColor(color);
    textFieldNickname.setCaretColor(color);
  }



  /**
   * 
   * Die neuen Userdaten werden in einem neuen Objekt zurückgegeben.
   * 
   * @return USRLOGIN ist ein neu erzeugtes Objekt
   */
  public Userdata getChangeUser() {
    return profil;
  }



  @SuppressWarnings("serial")
  private void init2(Userdata user) {
    con.insets = new Insets(6, 6, 0, 6);
    con.anchor = GridBagConstraints.NORTHWEST;
    con.gridx = 0;

    slider = new JUserColor2(KEY.TITLED_BORDER_VORDERGRUNDFARBE, new Color(user.getForegroundColor()));
    slider2 = new JUserColor2(KEY.TITLED_BORDER_HINTERGRUNDFARBE, new Color(user.getBackgroundColor()));
    con.anchor = GridBagConstraints.WEST;
    gridbag.setConstraints(labelUID, con);
    add(labelUID);

    con.gridx = 1;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.weightx = 1.0;
    gridbag.setConstraints(textFieldUID, con);
    add(textFieldUID);
    textFieldUID.setEditable(false);
    textFieldUID.setText(String.valueOf(user.getUserid()));
    textFieldUID.setToolTipText(userid.toString());
    textFieldUID.getInputMap(JComponent.WHEN_FOCUSED)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER");
    textFieldUID.getActionMap().put("ENTER", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent event) {
        textFieldUID.transferFocus();
      }
    });

    con.fill = GridBagConstraints.NONE;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.gridy = 1;
    con.weightx = 0.0;
    con.gridx = 0;
    gridbag.setConstraints(labelPassword, con);
    add(labelPassword);

    con.gridx = 1;
    con.weightx = 1.0;
    con.fill = GridBagConstraints.HORIZONTAL;
    gridbag.setConstraints(textFieldPassword, con);
    add(textFieldPassword);
    textFieldPassword.addFocusListener(focusAction);
    textFieldPassword.setDocument(docPasswd);
    textFieldPassword.setText(user.getPassword());
    textFieldPassword.getInputMap(JComponent.WHEN_FOCUSED)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER");
    textFieldPassword.getActionMap().put("ENTER", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent event) {
        textFieldConfirm.requestFocusInWindow();
      }
    });

    con.gridx = 2;
    con.weightx = 0.0;
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.WEST;
    gridbag.setConstraints(boxPassword, con);
    add(boxPassword);
    boxPassword.setSelected(true);
    boxPassword.setToolTipText(hakenPassword.toString());
    boxPassword.setFocusPainted(true);

    con.gridy = 2;
    con.gridx = 0;
    con.anchor = GridBagConstraints.WEST;
    gridbag.setConstraints(labelConfirm, con);
    add(labelConfirm);

    con.gridy = 2;
    con.weightx = 1.0;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.gridx = 1;
    gridbag.setConstraints(textFieldConfirm, con);
    add(textFieldConfirm);
    textFieldConfirm.addFocusListener(focusAction);
    textFieldConfirm.setDocument(docConfirm);
    textFieldConfirm.setText(user.getPassword());
    textFieldConfirm.getInputMap(JComponent.WHEN_FOCUSED)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER");
    textFieldConfirm.getActionMap().put("ENTER", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent event) {
        textFieldConfirm.transferFocus();
      }
    });

    con.weightx = 0.0;
    con.fill = GridBagConstraints.NONE;
    con.gridx = 0; // Neue Zeiele
    con.gridy = 4; // Zeilenhöhe
    con.gridwidth = 1; // Neue Zeile mit Rekalibrierung
    gridbag.setConstraints(labelNickname, con);
    add(labelNickname);

    con.weightx = 1.0;
    con.gridx = 1;
    con.fill = GridBagConstraints.HORIZONTAL;
    gridbag.setConstraints(textFieldNickname, con);
    textFieldNickname.setDocument(docNickname);
    textFieldNickname.setText(user.getNickname());
    textFieldNickname.addFocusListener(focusAction);
    textFieldNickname.setToolTipText(spitznameTooltip.toString());
    textFieldNickname.getInputMap(JComponent.WHEN_FOCUSED)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER");
    textFieldNickname.getActionMap().put("ENTER", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent event) {
        textFieldNickname.transferFocus();
      }
    });

    add(textFieldNickname);

    con.weightx = 0.0;
    con.gridx = 0;
    con.gridy = 5;
    con.fill = GridBagConstraints.NONE;
    gridbag.setConstraints(labelMail, con);
    add(labelMail);

    con.weightx = 1.0;
    con.gridx = 1;
    con.fill = GridBagConstraints.HORIZONTAL;
    gridbag.setConstraints(textFieldMail, con);
    textFieldMail.setDocument(docMail);
    textFieldMail.setText(user.getEmail());
    textFieldMail.addFocusListener(focusAction);
    textFieldMail.getInputMap(JComponent.WHEN_FOCUSED)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER");
    textFieldMail.getActionMap().put("ENTER", new AbstractAction() {
      @Override
      public void actionPerformed(ActionEvent event) {
        textFieldMail.transferFocus();
      }
    });
    add(textFieldMail);
    con.weightx = 0.0;
    con.gridx = 2;
    con.fill = GridBagConstraints.NONE;
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.anchor = GridBagConstraints.WEST;
    gridbag.setConstraints(boxMail, con);
    boxMail.setSelected(true);
    boxMail.setToolTipText(hakenMail.toString());
    boxMail.setFocusPainted(true);
    add(boxMail);

    con.gridy = 6;
    con.gridx = 0;
    con.gridwidth = 2;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.NORTHWEST;
    con.insets = new Insets(24, 0, 0, 0);
    gridbag.setConstraints(slider, con);
    add(slider);
    slider.addColorListener((event) -> {
      fg = (Color) event.getNewValue();
      foreground(fg);
    });

    con.gridy = 7; // neu
    con.fill = GridBagConstraints.HORIZONTAL;
    con.insets = new Insets(12, 0, 0, 0);
    gridbag.setConstraints(slider2, con);
    add(slider2);
    slider2.addColorListener((event) -> {
      bg = (Color) event.getNewValue();
      background(bg);
    });

    con.gridy = 8;
    con.gridx = 0;
    con.gridwidth = 2;
    con.anchor = GridBagConstraints.NORTHWEST;
    con.fill = GridBagConstraints.HORIZONTAL;
    JSeparator separator = new JSeparator();
    con.insets = new Insets(24, 12, 0, 0);
    gridbag.setConstraints(separator, con);
    add(separator);

    button2.addButtonListener((event) -> {
      Control value = (Control) event.getNewValue();
      if (value == Control.CLOSE) {
        changes.firePropertyChange(JUser.class.getName(), event.getOldValue(), event.getNewValue());
        return;
      }
      if (profil.getPassword().equals(new String(textFieldConfirm.getPassword()))) {
        if (profil.getEmail().length() > 0) {
          // Administrator legt neuen User an SEND
          changes.firePropertyChange(JUser.class.getName(), event.getOldValue(), event.getNewValue());
        }
        else {
          JOptionPane.showInternalMessageDialog(
              this, emailAdresse.toString(), labelMail.getText(), JOptionPane.ERROR_MESSAGE
          );
        }
      }
      else {

        JOptionPane.showInternalMessageDialog(
            this, this.passwortVerschieden.toString(), passwort.toString(), JOptionPane.ERROR_MESSAGE
        );
      }

    });
    panSouth.add(button2);
    con.fill = GridBagConstraints.HORIZONTAL;
    con.gridy = 9;
    con.gridwidth = 2;
    con.gridx = 0;
    con.weighty = 1.0;
    con.insets = new Insets(24, 0, 0, 0);
    gridbag.setConstraints(panSouth, con);
    add(panSouth);

    fg = new Color(user.getForegroundColor());
    foreground(fg);
    slider.setColor(fg);
    bg = new Color(user.getBackgroundColor());
    background(bg);
    slider2.setColor(bg);
  }



  public boolean isMailWritable() {
    return boxMail.isSelected();
  }



  public void setMailWritable(boolean value) {
    boxMail.setSelected(value);
  }



  public boolean isPasswordWritable() {
    return boxPassword.isSelected();
  }



  public void setPasswordWritable(boolean value) {
    boxPassword.setSelected(value);
  }



  @Override
  public boolean isRequestFocusEnabled() {
    return (true);
  }



  public void setFocus() {
    textFieldPassword.requestFocus();
  }

  /*****************************************************************************/
  /*                                                                           */
  /* Innerclass FocusAction */
  /*                                                                           */
  /*****************************************************************************/

  class FocusAction extends FocusAdapter {

    @Override
    public void focusGained(FocusEvent event) {
      Object obj;

      obj = event.getSource();
      if (obj.equals(boxPassword)) {

      }
      else if (obj.equals(boxMail)) {

      }
    }



    @Override
    public void focusLost(FocusEvent event) {
      Object obj;

      obj = event.getSource();
      if (obj.equals(textFieldMail)) {
        profil.setMail(textFieldMail.getText());
      }
      else if (obj.equals(textFieldNickname)) {
        profil.setNickname(textFieldNickname.getText());
      }
      else if (obj.equals(textFieldPassword)) {
        profil.setPassword(new String(textFieldPassword.getPassword()));
      }
    }

  }

  /*****************************************************************************/
  /*                                                                           */
  /* Class JUserButton */
  /*                                                                           */
  /*****************************************************************************/

  class JUserButton extends JPanel implements ActionListener {

    private static final long serialVersionUID = -1034051255010904206L;
    private final GridLayout grid = new GridLayout(1, 3, 36, 0);
    private final MultilingualButton buttonApplyClose = new MultilingualButton(
        KEY.BUTTON_SPEICHERN_SCHLIESSEN
    );
    private final MultilingualButton buttonSpeichern = new MultilingualButton(KEY.BUTTON_SPEICHERN);
    private final MultilingualButton buttonClose = new MultilingualButton(KEY.BUTTON_SCHLIESSEN);
    private final PropertyChangeSupport changes = new PropertyChangeSupport(this);

    public JUserButton() {
      super(true);
      super.setLayout(grid);

      add(buttonApplyClose);
      buttonApplyClose.addActionListener(this);
      buttonApplyClose.setOpaque(false);

      add(buttonSpeichern);
      buttonSpeichern.addActionListener(this);
      buttonSpeichern.setOpaque(false);

      add(buttonClose);
      buttonClose.addActionListener(this);
      buttonClose.setOpaque(false);

    }



    @Override
    public void actionPerformed(ActionEvent event) {
      Object obj;

      obj = event.getSource();
      if (obj.equals(buttonClose)) {
        changes.firePropertyChange(JUserButton.class.getName(), Control.NULL, Control.CLOSE);
      }
      else if (obj.equals(buttonSpeichern)) {
        changes.firePropertyChange(JUserButton.class.getName(), Control.NULL, Control.SAVE);
      }
      else if (obj.equals(buttonApplyClose)) {
        changes.firePropertyChange(JUserButton.class.getName(), Control.NULL, Control.SAVE_AND_CLOSE);
      }
    }



    public synchronized void addButtonListener(PropertyChangeListener l) {
      changes.addPropertyChangeListener(l);
    }



    public synchronized void removeButtonListener(PropertyChangeListener l) {
      changes.removePropertyChangeListener(l);
    }



    public void setColor(Color fg, Color bg) {
      setBackground(bg);
    }
  }

  static class JUserColor2 extends JPanel {

    private static final long serialVersionUID = -5605136204438897911L;
    private final static int max = 255;
    private final GridBagLayout gridbag = new GridBagLayout();

    private final GridBagConstraints con = new GridBagConstraints();
    private final JSlider redSlider = new JSlider(0, max, 0);
    private final JSlider greenSlider = new JSlider(0, max, 0);
    private final JSlider blueSlider = new JSlider(0, max, 0);

    private final JTextField textFieldRed = new JTextField(3);
    private final JTextField textFieldGreen = new JTextField(3);
    private final JTextField textFieldBlue = new JTextField(3);

//    private final EmptyBorder emptyBorder = new EmptyBorder(6, 6, 6, 6);
    private final MultilingualTitledBorder border;
    private PropertyChangeSupport changeColor = new PropertyChangeSupport(this);
    private Color old;
    private int r, g, b;
    private final FocusAction focusAction = new FocusAction();

    public JUserColor2(KEY key, Color color) {
      border = new MultilingualTitledBorder(key); // ohne EmptyBorder kommt der schattierte Rahmen zum
                                                  // Vorschein
      super.setLayout(gridbag);
      setColor(color);

      UIDefaults sliderDefaults = new UIDefaults();
      sliderDefaults.put("Slider.thumbWidth", 20);
      sliderDefaults.put("Slider.thumbHeight", 20);

      sliderDefaults.put("Slider:SliderThumb.backgroundPainter", new Painter<JComponent>() {
        @Override
        public void paint(Graphics2D g, JComponent c, int w, int h) {
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setStroke(new BasicStroke(2f));
          g.setColor(Resource.JQUERY_RED);
          g.fillOval(1, 1, w - 3, h - 3);
          g.setColor(Resource.JQUERY_HELLBLAU);
          g.drawOval(1, 1, w - 3, h - 3);
        }
      });
      sliderDefaults.put("Slider:SliderTrack.backgroundPainter", new Painter<JComponent>() {
        @Override
        public void paint(Graphics2D g, JComponent c, int w, int h) {
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setStroke(new BasicStroke(2f));
          g.setColor(Resource.JQUERY_BRAUN);
          g.fillRoundRect(0, 6, w - 1, 8, 8, 8);
          g.setColor(Resource.JQUERY_BRAUN);
          g.drawRoundRect(0, 6, w - 1, 8, 8, 8);
        }

      });

      redSlider.setMajorTickSpacing(max);
      redSlider.setMinorTickSpacing(1);
      redSlider.setPaintLabels(false);
      redSlider.setPaintTrack(true);
      redSlider.setForeground(Resource.JQUERY_RED);
      redSlider.addChangeListener((event) -> {
        r = redSlider.getValue();
        textFieldRed.setText(String.valueOf(r));
        Color redcolor = new Color(r, g, b);
        changeColor.firePropertyChange(JUserColor2.class.getName(), old, redcolor);
        old = redcolor;
      });

      con.gridwidth = 1;
      con.anchor = GridBagConstraints.NORTH;
      con.fill = GridBagConstraints.HORIZONTAL;
      con.weightx = 1.0;

      con.insets = new Insets(6, 6, 0, 0);
      gridbag.setConstraints(redSlider, con);
      super.add(redSlider);

      redSlider.putClientProperty("Nimbus.Overrides", sliderDefaults);
      redSlider.putClientProperty("Nimbus.Overrides.InheritDefaults", false);

      con.gridwidth = GridBagConstraints.REMAINDER;
      con.fill = GridBagConstraints.NONE;
      con.weightx = 0.0;
      con.insets = new Insets(6, 6, 0, 6);
      gridbag.setConstraints(textFieldRed, con);
      super.add(textFieldRed);
      textFieldRed.addFocusListener(focusAction);

      greenSlider.setMajorTickSpacing(max);
      greenSlider.setMinorTickSpacing(1);
      greenSlider.setPaintLabels(false); // false nicht anzeigen
      greenSlider.setPaintTrack(true);
      greenSlider.setForeground(Resource.JQUERY_GREEN);
      greenSlider.addChangeListener((event) -> {
        g = greenSlider.getValue();
        textFieldGreen.setText(String.valueOf(g));
        Color greencolor = new Color(r, g, b);
        changeColor.firePropertyChange(JUserColor2.class.getName(), old, greencolor);
        old = greencolor;
      });

      con.gridwidth = 1;
      con.weightx = 1.0;
      con.fill = GridBagConstraints.HORIZONTAL;
      con.insets = new Insets(0, 6, 0, 0);
      gridbag.setConstraints(greenSlider, con);
      super.add(greenSlider);

      UIDefaults greenDefaults = new UIDefaults();
      greenDefaults.put("Slider.thumbWidth", 20);
      greenDefaults.put("Slider.thumbHeight", 20);
      greenDefaults.put("Slider:SliderThumb.backgroundPainter", new Painter<JComponent>() {
        @Override
        public void paint(Graphics2D g, JComponent c, int w, int h) {
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setStroke(new BasicStroke(2f));
          g.setColor(Resource.JQUERY_GREEN);
          g.fillOval(1, 1, w - 3, h - 3);
          g.setColor(Resource.JQUERY_HELLBLAU);
          g.drawOval(1, 1, w - 3, h - 3);
        }
      });
      greenDefaults.put("Slider:SliderTrack.backgroundPainter", new Painter<JComponent>() {
        @Override
        public void paint(Graphics2D g, JComponent c, int w, int h) {
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setStroke(new BasicStroke(2f));
          g.setColor(Resource.JQUERY_BRAUN);
          g.fillRoundRect(0, 6, w - 1, 8, 8, 8);
          g.setColor(Resource.JQUERY_BRAUN);
          g.drawRoundRect(0, 6, w - 1, 8, 8, 8);
        }

      });

      greenSlider.putClientProperty("Nimbus.Overrides", greenDefaults);
      greenSlider.putClientProperty("Nimbus.Overrides.InheritDefaults", false);

      con.gridwidth = GridBagConstraints.REMAINDER;
      con.fill = GridBagConstraints.NONE;
      con.weightx = 0.0;
      con.insets = new Insets(0, 6, 0, 6);
      gridbag.setConstraints(textFieldGreen, con);
      super.add(textFieldGreen);
      textFieldGreen.addFocusListener(focusAction);

      blueSlider.setMajorTickSpacing(max);
      blueSlider.setMinorTickSpacing(1);
      blueSlider.setPaintLabels(false);
      blueSlider.setPaintTrack(true);
      blueSlider.setForeground(Resource.JQUERY_BLAU);
      blueSlider.addChangeListener((event) -> {
        b = blueSlider.getValue();
        textFieldBlue.setText(String.valueOf(b));
        Color bluecolor = new Color(r, g, b);
        changeColor.firePropertyChange(JUserColor2.class.getName(), old, bluecolor);
        old = bluecolor;
      });
      textFieldBlue.addFocusListener(focusAction);

      con.gridwidth = 1;
      con.fill = GridBagConstraints.HORIZONTAL;
      con.weightx = 1.0;
      con.insets = new Insets(0, 6, 0, 0);

      gridbag.setConstraints(blueSlider, con);
      super.add(blueSlider);

      UIDefaults blueDefaults = new UIDefaults();
      blueDefaults.put("Slider.thumbWidth", 20);
      blueDefaults.put("Slider.thumbHeight", 20);
      blueDefaults.put("Slider:SliderThumb.backgroundPainter", new Painter<JComponent>() {
        @Override
        public void paint(Graphics2D g, JComponent c, int w, int h) {
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setStroke(new BasicStroke(2f));
          g.setColor(Resource.JQUERY_BLAU);
          g.fillOval(1, 1, w - 3, h - 3);
          g.setColor(Resource.JQUERY_HELLBLAU);
          g.drawOval(1, 1, w - 3, h - 3);
        }
      });
      blueDefaults.put("Slider:SliderTrack.backgroundPainter", new Painter<JComponent>() {
        @Override
        public void paint(Graphics2D g, JComponent c, int w, int h) {
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setStroke(new BasicStroke(2f));
          g.setColor(Resource.JQUERY_BRAUN);
          g.fillRoundRect(0, 6, w - 1, 8, 8, 8);
          g.setColor(Resource.JQUERY_BRAUN);
          g.drawRoundRect(0, 6, w - 1, 8, 8, 8);
        }

      });

      blueSlider.putClientProperty("Nimbus.Overrides", blueDefaults);
      blueSlider.putClientProperty("Nimbus.Overrides.InheritDefaults", false);

      con.gridwidth = GridBagConstraints.REMAINDER;
      con.weightx = 0.0;
      con.fill = GridBagConstraints.NONE;
      con.insets = new Insets(0, 6, 6, 6);

      gridbag.setConstraints(textFieldBlue, con);
      super.add(textFieldBlue);
      super.setBorder(border);
    }



    public synchronized void addColorListener(PropertyChangeListener l) {
      changeColor.addPropertyChangeListener(l);
    }



    public synchronized void removeColorListener(PropertyChangeListener l) {
      changeColor.removePropertyChangeListener(l);
    }



    public void setColor(Color color) {
      r = color.getRed();
      g = color.getGreen();
      b = color.getBlue();
      textFieldRed.setText(String.valueOf(r));
      textFieldGreen.setText(String.valueOf(g));
      textFieldBlue.setText(String.valueOf(b));
      redSlider.setValue(r);
      greenSlider.setValue(g);
      blueSlider.setValue(b);
      old = new Color(r, g, b);

    }

    /*****************************************************************************/
    /*                                                                           */
    /* Innerclass FocusAction */
    /*                                                                           */
    /*****************************************************************************/

    class FocusAction extends FocusAdapter {

      @Override
      public void focusLost(FocusEvent event) {
        Object obj;
        int value;
        Color color;

        obj = event.getSource();
        if (obj.equals(textFieldRed)) {
          try {
            value = Integer.parseInt(textFieldRed.getText());
            if ((0 <= value) && (value <= max)) {
              redSlider.setValue(value);
              r = value;
              color = new Color(r, g, b);
              changeColor.firePropertyChange(JUserColor2.class.getName(), old, color);
              old = color;
            }
            else {
              textFieldRed.setText(String.valueOf(r));
            }
          }
          catch (NumberFormatException e) {
            textFieldRed.setText(String.valueOf(r));
          }
        }
        else if (obj.equals(textFieldGreen)) {
          try {
            value = Integer.parseInt(textFieldGreen.getText());

            if ((0 <= value) && (value <= max)) {
              greenSlider.setValue(value);
              g = value;
              color = new Color(r, g, b);
              changeColor.firePropertyChange(JUserColor2.class.getName(), old, color);
              old = color;
            }
            else {
              textFieldGreen.setText(String.valueOf(g));
            }
          }
          catch (NumberFormatException e) {
            textFieldGreen.setText(String.valueOf(g));
          }
        }
        else if (obj.equals(textFieldBlue)) {
          try {
            value = Integer.parseInt(textFieldBlue.getText());

            if ((0 <= value) && (value <= max)) {
              blueSlider.setValue(value);
              b = value;
              color = new Color(r, g, b);
              changeColor.firePropertyChange(JUserColor2.class.getName(), old, color);
              old = color;
            }
            else {
              textFieldBlue.setText(String.valueOf(b));
            }
          }
          catch (NumberFormatException e) {
            textFieldBlue.setText(String.valueOf(b));
          }
        }
      }
    }

  }

  @Override
  public void setLanguage(ISO639 code) {
    button2.buttonApplyClose.setLanguage(code);
    button2.buttonClose.setLanguage(code);
    button2.buttonSpeichern.setLanguage(code);
    labelPassword.setLanguage(code);
    labelUID.setLanguage(code);
    labelPassword.setLanguage(code);
    labelConfirm.setLanguage(code);
    labelMail.setLanguage(code);
    labelNickname.setLanguage(code);
    slider.border.setLanguage(code);
    slider2.border.setLanguage(code);
    hakenPassword.setLanguage(code);
    boxPassword.setToolTipText(hakenPassword.toString());
    hakenMail.setLanguage(code);
    boxMail.setToolTipText(hakenMail.toString());
    userid.setLanguage(code);
    textFieldUID.setToolTipText(userid.toString());
    passwortVerschieden.setLanguage(code);
    passwort.setLanguage(code);
    spitznameTooltip.setLanguage(code);
    textFieldNickname.setToolTipText(spitznameTooltip.toString());
    spitznameLang.setLanguage(code);
    emailAdresse.setLanguage(code);

  }

}
