/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sis.internal.processing.isoline;

import java.awt.Shape;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.BasicStroke;
import java.awt.EventQueue;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.image.RenderedImage;
import javax.swing.Timer;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.ButtonModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.function.BiConsumer;
import java.util.concurrent.CountDownLatch;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.internal.referencing.j2d.AffineTransform2D;

import static org.junit.Assert.*;


/**
 * A viewer for showing isoline generation step-by-step.
 * For enabling the use of this class, temporarily remove {@code private} and {@code final} keywords in
 * {@link Isolines#LISTENER}, then uncomment the {@link #setListener(StepsViewer)} constructor body.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.3
 * @since   1.3
 * @module
 */
@SuppressWarnings("serial")
public final class StepsViewer extends JComponent implements BiConsumer<String,Path2D>, ChangeListener, ActionListener {
    /**
     * Sets the component to be notified after each row of isolines generated from the rendered image.
     * The body of this method is commented-out because {@link Isolines#LISTENER} is private and final.
     * The body should be uncommented only temporarily during debugging phases.
     */
    private static void setListener(final StepsViewer listener) {
        // Isolines.LISTENER = listener;
    }

    /**
     * Entry point for debugging. Edit this method body as needed for loading an image to use as test data.
     *
     * @param  args  ignored.
     * @throws Exception if an error occurred during I/O or isoline generation.
     */
    public static void main(final String[] args) throws Exception {
        // showStepByStep(local.test.DebugIsoline.data(), 0);
    }

    /**
     * Size of the window and spacing between borders and isolines. All values are in pixels.
     */
    private static final int CANVAS_WIDTH = 1600, CANVAS_HEIGHT = 1000, PADDING = 3;

    /**
     * Whether to flip X and/or Y axis.
     */
    private static final boolean FLIP_X = false, FLIP_Y = true;

    /**
     * Description of current step. This title is updated at each isoline generation step,
     * when {@link #accept(String, Shape)} is invoked.
     */
    private final JLabel stepTitle;

    /**
     * The button for moving to the next step. When this button is enabled, the isoline process is blocked
     * by {@link #blocker} until this button is pressed. When this button is pressed, the isoline process
     * continue until {@link #accept(String, Shape)} is invoked again.
     *
     * @see #actionPerformed(ActionEvent)
     */
    private final JButton next;

    /**
     * Simulate a "next" action after some delay. This is used when users keep the "Next" button pressed.
     */
    private final Timer delayedNext;

    /**
     * Blocks the isoline computation thread until the user is ready to see the next step.
     */
    private CountDownLatch blocker;

    /**
     * The isolines to show.
     */
    private Path2D isolines;

    /**
     * Bounds of {@link #isolines}, slightly expanded for making easier to see.
     */
    private Rectangle bounds;

    /**
     * Conversion from pixel indices in the source image to pixel indices in the displayed window.
     */
    private final AffineTransform2D sourceToCanvas;

    /**
     * Creates a new viewer.
     *
     * @param  data  the source of data for isolines.
     * @param  pane  the container where to add components.
     */
    @SuppressWarnings("ThisEscapedInObjectConstruction")
    private StepsViewer(final RenderedImage data, final Container pane) {
        final double scaleX = (CANVAS_WIDTH  - 2*PADDING) / (double) data.getWidth();
        final double scaleY = (CANVAS_HEIGHT - 2*PADDING) / (double) data.getHeight();
        sourceToCanvas = new AffineTransform2D(
                FLIP_X ? -scaleX : scaleX, 0, 0, FLIP_Y ? -scaleY : scaleY,
                scaleX * (PADDING + data.getMinX() + (FLIP_X ? data.getWidth()  : 0)),
                scaleY * (PADDING + data.getMinY() + (FLIP_Y ? data.getHeight() : 0)));

        stepTitle = new JLabel();
        next = new JButton("Next");
        next.setEnabled(false);
        next.addActionListener(this);
        next.getModel().addChangeListener(this);
        delayedNext = new Timer(1000, this::fastForward);       // 1 second delay before fast forward.
        delayedNext.setRepeats(false);

        final JPanel bar = new JPanel(new BorderLayout());
        bar .add(stepTitle, BorderLayout.CENTER);
        bar .add(next,      BorderLayout.EAST);
        pane.add(bar,       BorderLayout.NORTH);
        pane.add(this,      BorderLayout.CENTER);
    }

    /**
     * Generates isolines for the given image and show the result step by step.
     * The given image shall have only one band.
     *
     * @param  data    the source of data for isolines.
     * @param  levels  levels of isolones to generate.
     */
    public static void showStepByStep(final RenderedImage data, final double... levels) {
        assertEquals("Unsupported number of bands.", 1, data.getSampleModel().getNumBands());
        final JFrame frame = new JFrame("Step-by-step isoline viewer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        final StepsViewer viewer = new StepsViewer(data, frame.getContentPane());
        final Isolines iso;
        try {
            setListener(viewer);
            frame.setVisible(true);
            frame.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
            iso = Isolines.generate(data, new double[][] {levels}, null)[0];
        } catch (TransformException e) {
            throw new AssertionError(e);        // Should not happen because we specified an identity transform.
        } finally {
            setListener(null);
        }
        final Path2D path = new Path2D.Float();
        for (final Shape shape : iso.polylines().values()) {
            path.append(shape, false);
        }
        viewer.accept("Final result", path);
    }

    /**
     * Invoked when the isolines need to be drawn.
     */
    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        final Graphics2D gh = (Graphics2D) g;
        if (bounds != null) {
            gh.setStroke(new BasicStroke(2));
            gh.setColor(Color.RED);
            gh.draw(bounds);
        }
        if (isolines != null) {
            gh.setStroke(new BasicStroke(1));
            gh.setColor(Color.BLUE);
            gh.draw(isolines);
        }
    }

    /**
     * Returns {@code true} if the shapes described by given iterators are equal.
     * This is used for deciding if it is worth to bother the user with a request
     * for pressing the "Next" button.
     */
    private static boolean equal(final PathIterator it1, final PathIterator it2) {
        final float[] a1 = new float[6];
        final float[] a2 = new float[6];
        while (!it1.isDone()) {
            if (it2.isDone()) return false;
            final int code = it1.currentSegment(a1);
            if (code != it2.currentSegment(a2)) {
                return false;
            }
            int n;
            switch (code) {
                case PathIterator.SEG_MOVETO:
                case PathIterator.SEG_LINETO:  n = 2; break;
                case PathIterator.SEG_QUADTO:  n = 4; break;
                case PathIterator.SEG_CUBICTO: n = 6; break;
                case PathIterator.SEG_CLOSE:   n = 0; break;
                default: throw new AssertionError(code);
            }
            while (--n >= 0) {
                if (Float.floatToIntBits(a1[n]) != Float.floatToIntBits(a2[n])) {
                    return false;
                }
            }
            it1.next();
            it2.next();
        }
        return it2.isDone();
    }

    /**
     * Invoked after a row has been processed during the isoline generation.
     * This is invoked from the main thread (<strong>not</strong> the Swing thread).
     *
     * @param  title   description of current state.
     * @param  update  new isolines to show.
     */
    @Override
    public void accept(final String title, final Path2D update) {
        update.transform(sourceToCanvas);
        final Rectangle b = update.getBounds();
        b.x      -= PADDING;
        b.y      -= PADDING;
        b.width  += PADDING * 2;
        b.height += PADDING * 2;
        try {
            final CountDownLatch c = new CountDownLatch(1);
            EventQueue.invokeLater(() -> {
                if (isolines != null && equal(isolines.getPathIterator(null), update.getPathIterator(null))) {
                    stepTitle.setText(title + " (no change)");
                    c.countDown();
                } else {
                    stepTitle.setText(title);
                    isolines = update;
                    bounds = b;
                    repaint();
                    assertNull(blocker);
                    if (next.getModel().isPressed()) {
                        c.countDown();
                    } else {
                        blocker = c;
                        next.setEnabled(true);
                    }
                }
            });
            c.await();
        } catch (InterruptedException  e) {
            throw new AssertionError(e);            // Stop the test.
        }
    }

    /**
     * Invoked by Swing when user presses the "Next" button.
     * This method resumes isoline computation.
     *
     * @param  event  ignored.
     */
    @Override
    public void actionPerformed(final ActionEvent event) {
        next.setEnabled(false);
        if (blocker != null) {
            blocker.countDown();
            blocker = null;
        }
    }

    /**
     * Invoked when the "Next" button is kept pressed.
     * The effect is to start the "fast forward" mode.
     * This method shall be invoked in Swing thread.
     *
     * @param  event  ignored.
     */
    private void fastForward(final ActionEvent event) {
        if (next.getModel().isPressed()) {
            if (blocker != null) {
                blocker.countDown();
                blocker = null;
            }
        }
    }

    /**
     * Invoked by Swing when the state of the "Next" button (pressed or not) changed.
     * If the button is pressed one second without being released, then we enter a
     * "fast forward" mode until the button is released.
     *
     * @param  event  ignored.
     */
    @Override
    public void stateChanged(final ChangeEvent event) {
        final ButtonModel m = (ButtonModel) event.getSource();
        if (m.isPressed()) {
            delayedNext.restart();
        } else {
            delayedNext.stop();
        }
    }
}
