/*
 *  Keyframe-Based Video Summarization Designer
 *  Copyright (C) 2014 Waltenberger Andreas
 *
 *  This program 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package at.ac.tuwien.ims.util;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Slider;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import javax.imageio.ImageIO;

/**
 * Popup-window to save the created video summarization
 * @author Andreas Waltenberger
 *
 */
public class ImageExporter extends Stage {

	private BorderPane layout;
	private Scene scene;
	private HBox buttons;

	private Button save;
	private Button cancel;
	private ImageView view;
	private ScrollPane scrollpane;
	private Slider scaler;
	private CheckBox checkbox;

	private FileChooser saver;

	public ImageExporter(Stage owner, WritableImage image) {
		initOwner(owner);
		initStyle(StageStyle.DECORATED);
		initModality(Modality.WINDOW_MODAL);
		setTitle("Export Image");

		saver = new FileChooser();
		saver.setInitialFileName("summary");
		// allow the image to be saved as jpg or png
		saver.getExtensionFilters().add(new ExtensionFilter("PNG", "*.png"));
		saver.getExtensionFilters().add(new ExtensionFilter("JPEG", "*.jpg"));

		// slider element to enable scaling for the image
		scaler = new Slider(0.1, 1, 1);
		scaler.setShowTickLabels(true);
		scaler.setShowTickMarks(true);
		scaler.setMajorTickUnit(0.1);
		scaler.setMinorTickCount(0);
		scaler.setBlockIncrement(0.1);
		scaler.setSnapToTicks(true);
		BorderPane.setMargin(scaler, new Insets(0, 0, 10, 0));

		view = new ImageView(image);
		view.scaleXProperty().bind(scaler.valueProperty());
		view.scaleYProperty().bind(scaler.valueProperty());

		scrollpane = new ScrollPane(view);
		scrollpane.setMinSize(1000, 500);
		BorderPane.setMargin(scrollpane, new Insets(0, 0, 10, 0));

		save = new Button("Save");
		save.setPrefSize(70, 20);
		save.setDefaultButton(true);
		save.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				File output = saver.showSaveDialog(ImageExporter.this);
				if (output != null) {
					try {
						// retrieve the image from the window
						BufferedImage image = SwingFXUtils.fromFXImage(view.getImage(), null);
						// if the user wants to save a scaled instance of the image ...
						if (checkbox.isSelected()) {
							int scaledWidth = (int) (image.getWidth() * scaler.getValue());
							int scaledHeight = (int) (image.getHeight() * scaler.getValue());
							// ... the image gets scaled down and then saved
							Image scaled = image.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);
							BufferedImage preview = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
							Graphics2D g = preview.createGraphics();
							g.drawImage(scaled, 0, 0, null);
							g.dispose();
							image = preview;
						}

						if (output.getName().endsWith("png")) {
							ImageIO.write(image, "png", output);
						} else {
							// remove alpha channel for export in jpg images
							BufferedImage imageRGB = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.OPAQUE);
							Graphics2D graphics = imageRGB.createGraphics();
							graphics.drawImage(image, 0, 0, null);
							ImageIO.write(imageRGB, "jpg", output);
							graphics.dispose();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				close();
			}
		});

		cancel = new Button("Cancel");
		cancel.setPrefSize(70, 20);
		cancel.setCancelButton(true);
		cancel.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				close();
			}
		});

		checkbox = new CheckBox("Save scaled image");

		buttons = new HBox(10);
		buttons.getChildren().addAll(save, cancel, checkbox);
		BorderPane.setAlignment(buttons, Pos.BOTTOM_RIGHT);

		layout = new BorderPane();
		layout.setPadding(new Insets(7));
		layout.setTop(scaler);
		layout.setCenter(scrollpane);
		layout.setBottom(buttons);

		scene = new Scene(layout);
		setScene(scene);
		setResizable(true);
	}
}
