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

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.schema.ISO639;
import net.javacomm.multilingual.schema.KEY;
import net.javacomm.window.manager.Control;



public class JSlot extends JPanel implements ActionListener, Babelfish {

  private final static Logger log = LogManager.getLogger(JSlot.class);
  private static final long serialVersionUID = 6400476578827919774L;
  private MultilingualLabel labelDatei = new MultilingualLabel(KEY.LABEL_DATEI);
  private JTextField textfieldFile = new JTextField();
  private JProgressBar progress = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);
  private MultilingualButton buttonTrennen = new MultilingualButton(KEY.BUTTON_TRENNEN);
  private MultilingualButton buttonAbholen = new MultilingualButton(KEY.STRING_DOWNLOAD);
  private MultilingualString wurdeAbgebrochen = new MultilingualString(KEY.STRING_WURDE_ABGEBROCHEN);
  private MultilingualString wurdeErfolgreich = new MultilingualString(KEY.STRING_WURDE_ERFOLGREICH);

  private GridBagLayout gridbag = new GridBagLayout();
  private GridBagConstraints con = new GridBagConstraints();
  private TitledBorder border = new TitledBorder(new LineBorder(Resource.JQUERY_HELLBLAU, 3, true), "");
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private int kanal = -1;
  // private String filename;
  private int index;

  private final Dimension maxsize = new Dimension(375, 150);

  public JSlot() {
    setLayout(gridbag);

    con.gridx = 0;
    con.gridy = 0;
    con.weightx = 0.0;
    con.gridwidth = 1;
    con.fill = GridBagConstraints.NONE;
    con.insets = new Insets(0, 3, 0, 0);
    con.anchor = GridBagConstraints.WEST;
    gridbag.setConstraints(labelDatei, con);

    add(labelDatei);

    con.insets = new Insets(0, 3, 0, 3);
    con.gridx = 1;
    con.gridy = 0;
    con.weightx = 1.0;
    con.gridwidth = 2;
    con.fill = GridBagConstraints.HORIZONTAL;
    gridbag.setConstraints(textfieldFile, con);
    textfieldFile.setEditable(true);
    // muss true sein wegen Drag and Drop
    textfieldFile.setFocusable(true);
    add(textfieldFile);

    DropTarget droptarget = new DropTarget(
        textfieldFile, DnDConstants.ACTION_COPY_OR_MOVE, new DropTargetAdapter() {
          @Override
          public void drop(DropTargetDropEvent event) {
            Transferable transferable = event.getTransferable();
            if (transferable.isDataFlavorSupported(FileFoundSelection.filefoundFlavor)) {
              event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
              try {
                // String str = (String) transferable.getTransferData
                // (DataFlavor.stringFlavor);
                GefundeneDatei filefound = (GefundeneDatei) transferable
                    .getTransferData(FileFoundSelection.filefoundFlavor);
                DropTargetContext context = event.getDropTargetContext();
                context.dropComplete(true);
                index = filefound.getIndex();
                textfieldFile.setText(filefound.getFilename());
                textfieldFile.select(0, 0);
                textfieldFile.setBackground(UIManager.getColor("TextField.textBackground"));
                textfieldFile.setForeground(UIManager.getColor("TextField.textForeground"));
              }
              catch (UnsupportedFlavorException e) {
                log.warn(e.getMessage());
                event.rejectDrop();
              }
              catch (IOException e) {
                log.warn(e.getMessage());
                event.rejectDrop();
              }
            }
            else {
              event.rejectDrop();
            }
          }
        }
    );



    con.insets = new Insets(3, 3, 3, 0);
    con.anchor = GridBagConstraints.CENTER;
    con.gridx = 0;
    con.gridy = 1;
    con.weightx = 1.0;
    con.gridwidth = 2;
    con.fill = GridBagConstraints.BOTH;

    gridbag.setConstraints(progress, con);
    progress.setStringPainted(true);
    progress.setMinimumSize(new Dimension(240, progress.getMinimumSize().height));
    progress.setPreferredSize(progress.getMinimumSize());

    add(progress);

    con.insets = new Insets(3, 0, 3, 3);
    con.gridx = 2;
    con.gridy = 1;
    con.weightx = 0.0;
    con.gridwidth = 1;
    con.fill = GridBagConstraints.NONE;
    con.anchor = GridBagConstraints.CENTER;
    con.gridwidth = 1;
    gridbag.setConstraints(buttonTrennen, con);

    buttonTrennen.addActionListener((event) -> {
      textfieldFile.setBackground(Resource.JQUERY_RED);
      textfieldFile.setForeground(Color.WHITE);
      setFilename(wurdeAbgebrochen.toString());
      changes.firePropertyChange("JProgressFileTransfer", Control.NULL, Control.DISCONNECT);
    });
    add(buttonTrennen);

    con.insets = new Insets(0, 3, 0, 3);
    con.gridx = 0;
    con.gridy = 2;
    con.weightx = 1.0;
    con.gridwidth = 3;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.anchor = GridBagConstraints.CENTER;

    gridbag.setConstraints(buttonAbholen, con);

    buttonAbholen.addActionListener(this);
    buttonAbholen.setEnabled(true);
    add(buttonAbholen);

    border.setTitlePosition(TitledBorder.TOP);
    setBorder(border);

  }



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

    obj = event.getSource();
    if (obj.equals(buttonTrennen)) {}
    else if (obj.equals(buttonAbholen)) {

      if ((getFilename() == null) || (getFilename().length() == 0)) {
        JOptionPane.showMessageDialog(
            JSlot.this,
            "Ziehe mit der linken Maustaste eine Datei aus der Trefferliste in den Übertragungskanal.",
            "Datei abholen", JOptionPane.INFORMATION_MESSAGE
        );
        return;
      }

      changes.firePropertyChange("JProgressFileTransfer", Control.NULL, Control.TRANSMIT);
    }
  }



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



  public void disconnect() {
    buttonTrennen.setEnabled(false);
  }



  /**
   * 
   * @return die Downloaddatei
   */
  public String getFilename() {
    return textfieldFile.getText();
  }



  /**
   * Jede Downloaddatei hat einen eindeutigen Index
   * 
   * @return ein Zahlenwert
   */
  public int getIndex() {
    return index;
  }



  public int getKanal() {
    return (kanal);
  }



  @Override
  public Dimension getMaximumSize() {
    return maxsize;
  }



  @Override
  public Dimension getPreferredSize() {
    return maxsize;
  }



  public void ready() {
    if ((buttonAbholen.isSelected() == false) && (buttonTrennen.isSelected() == false)) {
      buttonAbholen.setEnabled(true);
    }
  }



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



  public void setFilename(String str) {
    textfieldFile.setText(str);
  }



  /**
   * Bisher wurden p-Prozent übertragen.
   * 
   * 
   * @param p
   *          Prozent [0..100]
   */
  public void setPercent(int p) {
    progress.setValue(p);
    progress.setString(String.valueOf(p) + "%");
    if (progress.getValue() == progress.getMaximum()) {
      progress.setString(String.valueOf(progress.getValue()) + "%");
      textfieldFile.setBackground(Resource.JQUERY_GREEN);
      textfieldFile.setForeground(Color.WHITE);
      setFilename(wurdeErfolgreich.toString());

    }
  }



  public void setSlot(int value) {
    this.kanal = value;
  }



  public void setTitle(String str) {
    border.setTitle(str);
  }



  @Override
  public void setLanguage(ISO639 code) {
    labelDatei.setLanguage(code);
    buttonAbholen.setLanguage(code);
    buttonTrennen.setLanguage(code);
    wurdeAbgebrochen.setLanguage(code);
//    if (textfieldFile.getText().length() > 0) {
//      setFilename(wurdeAbgebrochen.toString());
//    }
//    else {
//      textfieldFile.setBackground(UIManager.getColor("TextField.textBackground"));
//      textfieldFile.setForeground(UIManager.getColor("TextField.textForeground"));
//    }
    wurdeErfolgreich.setLanguage(code);
  }

}
