package de.craften.ui.swingmaterial.toast;

import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.PropertySetter;
import org.jdesktop.core.animation.timing.TimingTargetAdapter;
import org.jdesktop.core.animation.timing.interpolators.SplineInterpolator;
import org.jdesktop.swing.animation.timing.sources.SwingTimerTimingSource;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

/**
 * A bar that displays toasts.
 *
 * @see <a href="https://www.google.com/design/spec/components/snackbars-toasts.html">Snackbars and toasts</a>
 */
public class ToastBar extends JComponent {
    private final SwingTimerTimingSource timer;
    private Queue<Toast> toasts = new LinkedList<>();
    private Toast currentToast = null;
    private boolean animationRunning = false;

    public ToastBar() {
        setLayout(null);
        timer = new SwingTimerTimingSource();
        timer.init();

        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                if (currentToast != null) {
                    currentToast.setSize(getWidth(), currentToast.getHeight());
                }
            }
        });
    }

    /**
     * Displays the toast or queues it for display if another toast is already displayed.
     *
     * @param toast toast
     */
    public void display(Toast toast) {
        toasts.add(toast);
        if (toasts.size() == 1) {
            displayNextToast();
        }
    }

    private void displayNextToast() {
        if (animationRunning) {
            return;
        }

        currentToast = toasts.poll();
        if (currentToast != null) {
            add(currentToast);
            currentToast.setSize(getWidth(), 48);

            animationRunning = true;
            new Animator.Builder(timer)
                    .setDuration(250, TimeUnit.MILLISECONDS)
                    .setEndBehavior(Animator.EndBehavior.HOLD)
                    .setInterpolator(new SplineInterpolator(0.1, 0.3, 0.45, 1))
                    .addTarget(PropertySetter.getTarget(currentToast, "yOffset", getHeight(), 0))
                    .build().start();
            new Animator.Builder(timer)
                    .setStartDelay(250 + 3000, TimeUnit.MILLISECONDS)
                    .setDuration(250, TimeUnit.MILLISECONDS)
                    .setEndBehavior(Animator.EndBehavior.HOLD)
                    .setInterpolator(new SplineInterpolator(0.55, 0, 0.9, 0.7))
                    .addTarget(PropertySetter.getTarget(currentToast, "yOffset", 0, getHeight() + 1))
                    .addTarget(new TimingTargetAdapter() {
                        @Override
                        public void end(Animator source) {
                            if (currentToast != null) {
                                remove(currentToast);
                                currentToast = null;
                            }

                            new javax.swing.Timer(1000, new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    animationRunning = false;
                                    displayNextToast();
                                }
                            }).start();
                        }
                    })
                    .build().start();
        }
    }

    public static void main(String[] args) {
        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());
        final ToastBar toastBar = new ToastBar();
        toastBar.setPreferredSize(new Dimension(200, 48));
        content.add(toastBar, BorderLayout.SOUTH);

        content.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                toastBar.display(new TextToast("Hello!"));
                System.out.println("Added toast");
            }
        });

        JFrame window = new JFrame();
        window.setContentPane(content);
        window.setSize(200, 200);
        window.setVisible(true);
    }
}

@@ -400,17 +400,111 @@
 ava.awt.
-*
+event.ActionEvent;%0Aimport java.awt.event.ActionListener;%0Aimport java.awt.event.ComponentAdapter
 ;%0Aimport
@@ -519,17 +519,30 @@
 t.event.
-*
+ComponentEvent
 ;%0Aimport
@@ -3661,717 +3661,7 @@
    %7D
-%0A%0A    public static void main(String%5B%5D args) %7B%0A        JPanel content = new JPanel();%0A        content.setLayout(new BorderLayout());%0A        final ToastBar toastBar = new ToastBar();%0A        toastBar.setPreferredSize(new Dimension(200, 48));%0A        content.add(toastBar, BorderLayout.SOUTH);%0A%0A        content.addMouseListener(new MouseAdapter() %7B%0A            @Override%0A            public void mouseClicked(MouseEvent e) %7B%0A                toastBar.display(new TextToast(%22Hello!%22));%0A                System.out.println(%22Added toast%22);%0A            %7D%0A        %7D);%0A%0A        JFrame window = new JFrame();%0A        window.setContentPane(content);%0A        window.setSize(200, 200);%0A        window.setVisible(true);%0A    %7D
 %0A%7D%0A

Remove toast debug code.