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

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.text.BadLocationException;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.javacomm.client.resource.Resource;
import net.javacomm.multilingual.MultilingualButton;
import net.javacomm.multilingual.MultilingualLabel;
import net.javacomm.multilingual.schema.ISO639;
import net.javacomm.multilingual.schema.KEY;
import net.javacomm.share.Constants;
import net.javacomm.window.manager.Control;
import net.javacomm.window.manager.Frames;
import net.javacomm.window.manager.WM;
import net.javacomm.window.manager.WindowManagerInternalFrame;



/**
 * Dieser Frame zeigt die Lizenzbedingungen an.
 */
public class JInfoPane extends WindowManagerInternalFrame implements HyperlinkListener {

  class InternalAction extends InternalFrameAdapter {

    @Override
    public void internalFrameActivated(InternalFrameEvent event) {
      mainPane.revalidate();
      buttonSchliessen.requestFocus();
    }



    @Override
    public void internalFrameClosed(InternalFrameEvent event) {
      changes.firePropertyChange("JInfoPane", Control.NULL, Control.QUIT);
    }

  }

  private static final long serialVersionUID = 8033663834096696319L;
  private final static Logger log = LogManager.getLogger(JInfoPane.class);
  public final static Dimension PANEL_SIZE = new Dimension(660, 600);
  private GridBagLayout gridbag = new GridBagLayout();
  private GridBagConstraints con = new GridBagConstraints();
  private JPanel mainPane = new JPanel();
  private Class<? extends JInfoPane> resource;
  private MultilingualLabel labelVersion = new MultilingualLabel(KEY.LABEL_VERSION);
  private JLabel labelMozilla = new JLabel();
  private MultilingualButton buttonSchliessen = new MultilingualButton(KEY.BUTTON_SCHLIESSEN);
  private InternalAction internalAction = new InternalAction();
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private JTextPane editor = new JTextPane();

  public JInfoPane() {
    mainPane.setLayout(gridbag);
    addInternalFrameListener(internalAction);
    setContentPane(mainPane);
    resource = getClass();

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

    URL url = resource.getResource(Resource.MOZILLA);
    labelMozilla.setIcon(new ImageIcon(url));
    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.NONE;
    con.weightx = 0.0;
    con.weighty = 1.0;
    con.insets = new Insets(12, 12, 12, 12);
    con.anchor = GridBagConstraints.NORTH;
    gridbag.setConstraints(labelMozilla, con);
    mainPane.add(labelMozilla);

    editor.setEditable(false);
    try(
      InputStream inStream = resource.getResourceAsStream(Resource.LICENSE);
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inStream));
    ) {

      while (bufferedReader.ready()) {
        String line = bufferedReader.readLine();
        editor.getDocument().insertString(editor.getDocument().getLength(), line.concat("\n"), null);
      }
    }
    catch (IOException e) {
      log.error(e.getMessage(), e);
    }
    catch (BadLocationException e) {
      log.info(e.getMessage(), e);
    }

    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.HORIZONTAL;
    con.weightx = 1.0;
    con.weighty = 0.0;
    con.insets = new Insets(0, 12, 0, 12);
    con.anchor = GridBagConstraints.CENTER;
    gridbag.setConstraints(editor, con);
    mainPane.add(editor);

    con.gridx = 0;
    con.gridy++;
    con.gridwidth = 1;
    con.gridheight = 1;
    con.fill = GridBagConstraints.NONE;
    con.weightx = 0.0;
    con.weighty = 1.0;
    con.insets = new Insets(12, 0, 12, 0);
    con.anchor = GridBagConstraints.SOUTH;
    gridbag.setConstraints(buttonSchliessen, con);
    mainPane.add(buttonSchliessen);

    buttonSchliessen.addActionListener(event -> {
      doDefaultCloseAction();
    });
    buttonSchliessen.setFocusPainted(false);

  }



  @Override
  public void activated() {
    try {
      setSelected(true);
    }
    catch (PropertyVetoException e) {}
  }



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



  @Override
  public Dimension getMinimumSize() {
    return PANEL_SIZE;
  }



  @Override
  public Frames getType() {
    return Frames.INFO;
  }



  @Override
  public void hyperlinkUpdate(HyperlinkEvent event) {
    HTMLDocument doc;
    JEditorPane pane;

    if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
      pane = (JEditorPane) event.getSource();
      if (event instanceof HTMLFrameHyperlinkEvent evt) {
        doc = (HTMLDocument) pane.getDocument();
        doc.processHTMLFrameHyperlinkEvent(evt);
      }
      else {
        try {
          pane.setPage(event.getURL());
        }
        catch (IOException e) {
          log.info(e.getMessage(), e.getCause());
        }
      }
    }
  }



  @Override
  public void insertWM(WM frame) {
    // nichts machen
  }



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



  @Override
  public void removeWM(WM frame) {
    // nichts machen
  }



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



  @Override
  public void setLanguage(ISO639 code) {
    buttonSchliessen.setLanguage(code);
    setLanguage(KEY.FRAME_INFO, code);
    labelVersion.setLanguage(code);
    String neuerText = labelVersion.getText().replace("XXX", Constants.VERSION);
    labelVersion.setText(neuerText);
  }

}
