/**
 *  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.chat;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolTip;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.ToolTipManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nexuswob.gui.ArrowTooltip;
import org.nexuswob.gui.JOkDialog;
import org.nexuswob.gui.JToolTipBorder;
import org.nexuswob.gui.TableModel3;
import org.nexuswob.util.Cell;
import org.nexuswob.util.Util.Record;
import net.javacomm.client.environment.GUI;
import net.javacomm.client.resource.Resource;
import net.javacomm.multilingual.Babelfish;
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.protocol.ChatUser;
import net.javacomm.window.manager.Control;
import net.javacomm.window.manager.Frames;



class CountUserPanel extends JPanel {

  private static final long serialVersionUID = 8123825495408532218L;
  private JLabel labelNumber = new JLabel();
  private GridBagLayout gridbag = new GridBagLayout();
  private GridBagConstraints con = new GridBagConstraints();
  MultilingualLabel labelOnline = new MultilingualLabel(KEY.LABEL_ONLINE);

  public CountUserPanel() {
    setLayout(gridbag);
    setBackground(Resource.JQUERY_ORANGE);

    con.insets = new Insets(2, 2, 0, 2);
    con.gridwidth = GridBagConstraints.REMAINDER;
    gridbag.setConstraints(labelOnline, con);
    add(labelOnline);
    labelOnline.setForeground(Resource.JQUERY_TEXTBRAUN);

    con.insets = new Insets(1, 2, 2, 2);
    gridbag.setConstraints(labelNumber, con);
    labelNumber.setForeground(Resource.JQUERY_TEXTBRAUN);
    add(labelNumber);
    setBorder(null);
  }



  public void setCount(int c) {
    labelNumber.setText(String.valueOf(c));
  }

}

/**
 * Ein grafischer Überblick über alle Anwender, die in einem Raum sind.
 * 
 * 
 * @author llange
 *
 */
public class JChatuserOnline extends JPanel implements Babelfish {

  /***************************************************************************/
  /*                                                                         */
  /* Innerclass ColorRenderer */
  /*                                                                         */
  /***************************************************************************/

  class ColorRenderer extends JLabel implements TableCellRenderer {

    private static final long serialVersionUID = 1483352116438614471L;

    public ColorRenderer() {
      setOpaque(true);
    }



    @Override
    public Component getTableCellRendererComponent(JTable table, Object str, boolean isSelected,
        boolean hasFocus, int row, int column) {

      try {
        setBackground(new Color(chatuser[row].getBackgroundColor()));
        setForeground(new Color(chatuser[row].getForegroundColor()));
        setText((String) str);
      }
      catch (Exception e) {
        log.info(e.getMessage(), e.getCause());
      }
      return this;
    }

  }

  private class HeaderRenderer extends JLabel implements TableCellRenderer {
    private static final long serialVersionUID = 1483352116438614471L;

    public HeaderRenderer() {
      setOpaque(true);
    }



    @Override
    public Component getTableCellRendererComponent(JTable table, Object str, boolean isSelected,
        boolean hasFocus, int row, int column) {

      if (column == 0) {
        setBorder(new EmptyBorder(0, 0, 0, 0));
      }

      setBackground(Resource.JQUERY_ORANGE);

      setText((String) str);
      return this;
    }
  }

  /***************************************************************************/
  /*                                                                         */
  /* Innerclass MouseAction */
  /*                                                                         */
  /***************************************************************************/

  class MouseAction extends MouseAdapter {

    JChatuserOnline info2;
    int selectedRow;
    JOkDialog okDialog;

    public MouseAction(JChatuserOnline info) {
      info2 = info;
    }



    @Override
    public void mouseReleased(MouseEvent event) {
      Object obj;
      // String nickname; //Vorsicht Nickname ist nicht eindeutig, weil der
      // nickname sich ändern kann
      obj = event.getSource();
      if (obj.equals(table) && (event.getClickCount() >= 2)) {
        if (event.getButton() == MouseEvent.BUTTON1) {
          selectedRow = table.getSelectedRow();
          String nickname = model.getValueAt(selectedRow, 0).toString();
          if (nickname.equals(getNickname())) {
            JOptionPane.showMessageDialog(
                null, "<html>" + "<head/>" + "<body>" + selftalk.toString() + "</body>" + "</html>",
                "1:1 Chat", JOptionPane.WARNING_MESSAGE
            );
          }
          else {
            // Ziel nickname zu diesem User eine Verbindung aufbauen
            changes.firePropertyChange(nickname, Control.NULL, Control.HIT);
          }
        }
      }
    }

  }

  private static final long serialVersionUID = -1258669005473361153L;
  private final static Logger log = LogManager.getLogger(JChatuserOnline.class);
  // private final static String names [] = {"", /*"First Name",
  // "Last Name", "UID"*/};
  private TableModel3 model = new TableModel3();
  private JTable table = new JTable() {

    @Override
    public JToolTip createToolTip() {
      ToolTipManager.sharedInstance().setInitialDelay(200);
      ToolTipManager.sharedInstance().setDismissDelay(4000);
      ArrowTooltip arrow = new ArrowTooltip(cRenderer.getBackground());
      arrow.setComponent(table);
      arrow.setTextAttributes(GUI.regularFont13, cRenderer.getForeground(), cRenderer.getBackground());
      arrow.setBorder(new JToolTipBorder(7, cRenderer.getForeground(), cRenderer.getBackground(), 2));
      return arrow;
    }

  };
  private JScrollPane scrollTable = new JScrollPane();
  private MouseAction mouseAction = new MouseAction(this);
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private JTableHeader header;
  private ColorRenderer cRenderer = new ColorRenderer();
  private CountUserPanel countUserPanel = new CountUserPanel();
  private ChatUser[] chatuser;
  private HeaderRenderer headerrenderer = new HeaderRenderer();
  private String userid;

  private String nickname;

  private MultilingualString selftalk = new MultilingualString(KEY.STRING_EINSAME_SEELEN);
  private MultilingualString doubleclick = new MultilingualString(KEY.STRING_DOPPELKLICKEN);

  public JChatuserOnline() {
    super(true);
    model.setHeader("");
    setLayout(new BorderLayout());
    table.setModel(model);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    // table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF);
    header = table.getTableHeader();
    header.setReorderingAllowed(false);
    header.setDefaultRenderer(headerrenderer);
    headerrenderer.setHorizontalAlignment(SwingConstants.CENTER);

    table.addMouseListener(mouseAction);
    table.setDefaultRenderer(String.class, cRenderer);
    cRenderer.setHorizontalAlignment(SwingConstants.CENTER);
    // Double-click to chat.
//    Haz doble clic para chatear.
    table.setToolTipText(doubleclick.toString());
    table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    table.setRowHeight(26);

    scrollTable.setViewportView(table);
    scrollTable.getHorizontalScrollBar().setUnitIncrement(12);
    scrollTable.getVerticalScrollBar().setUnitIncrement(14);

    countUserPanel.setToolTipText("Aktive im Raum");
    add(BorderLayout.NORTH, countUserPanel);
    add(BorderLayout.CENTER, scrollTable);

    scrollTable.setMinimumSize(new Dimension(84, getSize().height));
    scrollTable.setPreferredSize(new Dimension(84, getSize().height));
    scrollTable.setMaximumSize(new Dimension(84, getSize().height));

    scrollTable.setBorder(null);
    scrollTable.getViewport().setBackground(Resource.JQUERY_TEXTBRAUN);

  }



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



  public String getNickname() {
    return nickname;
  }



  /**
   * Der User, der den Raum geöffnet hat.
   * 
   * @return userid
   */
  public String getUserID() {
    return userid;
  }



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



  public void setImage(Frames value) {
    Class<? extends JChatuserOnline> resource = getClass();
    switch(value) {
      case FORUM:
        headerrenderer.setIcon(new ImageIcon(resource.getResource(Resource.EMBRACE_THE_WORLD)));
        break;
      case PAUSENRAUM:
        headerrenderer.setIcon(new ImageIcon(resource.getResource(Resource.PAUSENRAUM45)));
        break;
      case BESPRECHNUNGSRAUM:
        headerrenderer.setIcon(new ImageIcon(resource.getResource(Resource.BESPRECUNGSRAUM_35x26)));
        break;
      case GRUPPENRAUM:
        headerrenderer.setIcon(new ImageIcon(resource.getResource(Resource.GRUPPENRAUM)));
        break;
      default:
    }

  }



  @Override
  public void setLanguage(ISO639 code) {
    countUserPanel.labelOnline.setLanguage(code);
    selftalk.setLanguage(code);
    doubleclick.setLanguage(code);
    table.setToolTipText(doubleclick.toString());
  }



  public void setNickname(String value) {
    nickname = value;
    for (int index = 0; index < model.getRowCount(); index++) {
      if (model.getValueAt(index, 0).toString().equals(value)) {
        model.setValueAt(value, index, 0);
        break;
      }
    }
  }



  public void setUserID(String value) {
    userid = value;
  }



  /**
   * Alle Raummitglieder werden mit ihren Nicknames angezeigt. Die Anzahl der
   * Insassen wird ebenfalls angezeigt.
   * 
   * @param userlist
   *                 eine Liste aller Raummitgleider
   */
  public void setUserList(ChatUser[] userlist) {
    chatuser = userlist;
    model.removeAll();
    int count = userlist.length;
    for (int index = 0; index < count; index++) {
      if (userlist[index].getUserid().equals(getUserID())) {
        setNickname(userlist[index].getNickname());
      }
      Record record = new Record();
      Cell<String> cellNickname = new Cell<>();
      cellNickname.setValue(userlist[index].getNickname());
      record.add(cellNickname);
      model.addRow(record);
    }
    countUserPanel.setCount(count);
  }



  public void updateBackground(String nickname, Color color) {
    for (int row = 0; row < model.getRowCount(); row++) {
      String value = model.getValueAt(row, 0).toString();
      if (value.equals(nickname)) {
        chatuser[row].setBackgroundColor(color.getRGB());
        repaint();
        break;
      }
    }

  }



  /**
   * Der User hat seine Farbe gewechselt
   * 
   * @param color
   */
  public void updateForeground(String userid, Color color) {
    for (int row = 0; row < model.getRowCount(); row++) {
      String value = model.getValueAt(row, 0).toString();
      if (value.equals(userid)) {
        chatuser[row].setForegroundColor(color.getRGB());
        repaint();
        break;
      }
    }

  }

}
