/*
 * This file is part of Arduino.
 *
 * Arduino is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * As a special exception, you may use this file as part of a free software
 * library without restriction.  Specifically, if other files instantiate
 * templates or use macros or inline functions from this file, or you compile
 * this file and link it with other files to produce an executable, this
 * file does not by itself cause the resulting executable to be covered by
 * the GNU General Public License.  This exception does not however
 * invalidate any other reasons why the executable file might be covered by
 * the GNU General Public License.
 *
 * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
 */

package cc.arduino.view;

import processing.app.Base;
import processing.app.BaseNoGui;

import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.*;
import java.nio.file.Paths;

public class NotificationPopup extends JDialog {

  private final ComponentAdapter parentMovedListener;

  public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, String message) {
    super(parent, false);
    initComponents();

    updateLocation(parent);
    parentMovedListener = new ComponentAdapter() {
      @Override
      public void componentMoved(ComponentEvent e) {
        updateLocation(parent);
      }
    };
    parent.addComponentListener(parentMovedListener);

    text.setText("<html><body style=\"font-family:sans-serif;font-size:12pt\">" + message + "</body></html>");

    text.addHyperlinkListener(hyperlinkListener);
    text.addHyperlinkListener(e -> {
      if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
        return;
      }
      close();
    });

    addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosed(WindowEvent e) {
        parent.removeComponentListener(parentMovedListener);
      }
    });

    Base.registerWindowCloseKeys(getRootPane(), e -> close());

    MouseAdapter closeOnClick = new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        close();
      }
    };
    addMouseListener(closeOnClick);
    text.addMouseListener(closeOnClick);
    icon.addMouseListener(closeOnClick);
  }

  private void updateLocation(Frame parent) {
    Point parentLocation = parent.getLocation();

    int parentX = Double.valueOf(parentLocation.getX()).intValue();
    int parentY = Double.valueOf(parentLocation.getY()).intValue();
    setLocation(parentX, parentY + parent.getHeight() - getHeight());
  }

  public void close() {
    dispatchEvent(new WindowEvent(NotificationPopup.this, WindowEvent.WINDOW_CLOSING));
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    icon = new javax.swing.JLabel();
    text = new javax.swing.JEditorPane();
    closeButton = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    setAlwaysOnTop(true);
    setFocusable(false);
    setFocusableWindowState(false);
    setUndecorated(true);
    setPreferredSize(new java.awt.Dimension(350, 70));
    setResizable(false);
    setSize(new java.awt.Dimension(350, 70));
    getContentPane().setLayout(null);

    icon.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "arduino_small.png").toFile().getAbsolutePath()));
    getContentPane().add(icon);
    icon.setBounds(10, 10, 50, 50);

    text.setEditable(false);
    text.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 0, true));
    text.setContentType("text/html"); // NOI18N
    text.setOpaque(false);
    getContentPane().add(text);
    text.setBounds(70, 10, 270, 50);

    closeButton.setIcon(new ImageIcon(Paths.get(BaseNoGui.getContentFile("lib").getAbsolutePath(), "theme", "close.png").toFile().getAbsolutePath()));
    closeButton.setBorder(null);
    closeButton.setBorderPainted(false);
    closeButton.setHideActionText(true);
    closeButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        closeButtonActionPerformed(evt);
      }
    });
    getContentPane().add(closeButton);
    closeButton.setBounds(328, 0, 22, 22);

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
    close();
  }//GEN-LAST:event_closeButtonActionPerformed

  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {

        /* Create and display the dialog */
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        NotificationPopup dialog = new NotificationPopup(new JFrame(), System.out::println, "<a href='arduinoide://boardsmanager'>test</a> test test test test test test test test\n" +
          " test test test test test test test test test test test");
        dialog.addWindowListener(new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        dialog.setVisible(true);
      }
    });
  }

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton closeButton;
  private javax.swing.JLabel icon;
  private javax.swing.JEditorPane text;
  // End of variables declaration//GEN-END:variables

}

@@ -2059,32 +2059,144 @@
 parent);%0A      %7D
+%0A%0A      @Override%0A      public void componentResized(ComponentEvent e) %7B%0A        updateLocation(parent);%0A      %7D
 %0A    %7D;%0A    pare

Update notification popup was not sticking to bottom left corner when windows was resized. Fixes #4068