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

import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nexuswob.gui.TableModel3;
import org.nexuswob.util.Cell;
import org.nexuswob.util.Util.Record;
import net.javacomm.multilingual.Babelfish;
import net.javacomm.multilingual.MultilingualString;
import net.javacomm.multilingual.schema.ISO639;
import net.javacomm.multilingual.schema.KEY;
import net.javacomm.transfer.TransferOdxModulPermission;
import net.javacomm.window.manager.Control;



@SuppressWarnings("serial")
public class JScrollModule extends JScrollPane implements Babelfish {

  private final static Logger log = LogManager.getLogger(JScrollModule.class);

  public final static int NICKNAME = 0;
  public final static int MAIL = 1;
  public final static int ODX = 2;
  private JTable table = new JTable();
  private TableModel3 model3 = new TableModel3() {

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
      return columnIndex == ODX;
    }

  };
  private Map<String, String> map = new HashMap<>();
  private TableColumnModel columnModel;
  private JTableHeader header;
  private MultilingualString odx = new MultilingualString(KEY.ODX_220);
  private MultilingualString correo = new MultilingualString(KEY.STRING_MAIL);
  private MultilingualString apodo = new MultilingualString(KEY.LABEL_SPITZNAME);
  private DefaultTableCellRenderer headerRenderer;
  private DefaultCellEditor odxEditor;
  private JCheckBox checkbox = new JCheckBox();
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);

  public JScrollModule() {

    model3.setHeader(apodo.toString(), correo.toString(), odx.toString());
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    table.setModel(model3);
    table.setRowHeight(26);
    table.setFillsViewportHeight(true);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);

    centerHeader();

    columnModel = table.getColumnModel();
    columnModel.getColumn(MAIL).setPreferredWidth(250);
    columnModel.getColumn(NICKNAME).setPreferredWidth(150);

    odxEditor = new DefaultCellEditor(checkbox);
    columnModel.getColumn(ODX).setCellEditor(odxEditor);
    checkbox.setHorizontalAlignment(SwingConstants.CENTER);
    checkbox.addActionListener((event) -> {
      boolean value = !(Boolean) table.getValueAt(table.getSelectedRow(), table.getSelectedColumn());
      String mail = (String) model3.getValueAt(table.getSelectedRow(), MAIL);
      // update senden

      Update update = new Update();
      update.setOdx(value);
      update.setUserid(map.get(mail));

      changes.firePropertyChange(JScrollModule.class.getName(), update, Control.UPDATE_ODX);

    });



    getViewport().setOpaque(true);
    setViewportView(table);
    setOpaque(true);
    setBorder(null);

  }



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



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



  public synchronized void removeAllListener() {
    for (PropertyChangeListener pl : changes.getPropertyChangeListeners()) {
      removeUpdateListener(pl);
    }
    for (ActionListener al : checkbox.getActionListeners()) {
      checkbox.removeActionListener(al);
    }
  }



  /**
   * Die Spaltenüberschriften werden zentriert.
   *
   */
  public void centerHeader() {
    header = table.getTableHeader();
    headerRenderer = (DefaultTableCellRenderer) header.getDefaultRenderer();
    headerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
  }




  /**
   * Zeige die ODX-Berechtigung an.
   *
   * @param odxuser
   *                alle Anwender
   */
  public void setOdx(List<TransferOdxModulPermission> odxuser) {
    model3.removeAll();
    map.clear();


    odxuser.forEach((odx) -> {

      // 1. Zelle
      Record record = new Record();
      map.put(odx.getMail(), odx.getUserid());

      // 2. Zelle
      Cell<String> nickname = new Cell<>();
      nickname.setValue(odx.getNickname());
      record.add(nickname);

      // 3. Zelle
      Cell<String> mail = new Cell<>();
      mail.setValue(odx.getMail());
      record.add(mail);


      // 4. Zelle
      Cell<Boolean> permission = new Cell<>();
      permission.setValue(odx.isOdxAllow());
      record.add(permission);

      model3.addRow(record);

    });

  }

  @Override
  public void setLanguage(ISO639 code) {
    odx.setLanguage(code);
    correo.setLanguage(code);
    apodo.setLanguage(code);
    columnModel.getColumn(ODX).setHeaderValue(odx.toString());
    columnModel.getColumn(MAIL).setHeaderValue(correo.toString());
    columnModel.getColumn(NICKNAME).setHeaderValue(apodo.toString());

  }

  /**
   * In Update sind die Änderungen gespeichert.
   *
   * @author llange
   *
   */
  static class Update {

    private String userid;
    private boolean isOdx;

    Update() {}



    String getUserid() {
      return userid;
    }



    void setUserid(String userid) {
      this.userid = userid;
    }



    boolean isOdx() {
      return isOdx;
    }



    void setOdx(boolean isOdx) {
      this.isOdx = isOdx;
    }

  }

}
