package de.siphalor.was.visual.jfx.util;

import de.siphalor.was.WhatAStorage;
import de.siphalor.was.content.lang.I18n;
import de.siphalor.was.visual.jfx.component.ScalingImagePane;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.input.*;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;

@SuppressWarnings("unused")
public class JFXStorageSlot {
	private final int x;
	private final int y;
	private final int depth;

	private final GridPane grid;
	private final ScalingImagePane[] images;
	private final Label[] labels;

	public JFXStorageSlot(int x, int y, int depth) {
		this.x = x;
		this.y = y;
		this.depth = depth;
		this.grid = new GridPane();

		grid.setOnDragDetected(this::onDragDetected);
		grid.setOnDragDropped(this::onDragDropped);
		grid.setOnDragEntered(this::onDragEntered);
		grid.setOnDragExited(this::onDragExited);
		grid.setOnDragOver(this::onDragOver);

		images = new ScalingImagePane[depth];
		labels = new Label[depth];

		String empty = I18n.getInstance().getString("game.storage.empty");

		RowConstraints rowConstraints = new RowConstraints();
		rowConstraints.setPercentHeight(100D / (depth + 1));
		rowConstraints.setMinHeight(10D);
		ColumnConstraints columnConstraints = new ColumnConstraints();
		columnConstraints.setPercentWidth(70D / (depth + 1));
		columnConstraints.setMinWidth(10D);

		for (int z = 0; z < depth; z++) {
			ScalingImagePane imagePane = new ScalingImagePane();
			grid.add(imagePane, depth - z - 1, z, 1, 1);
			GridPane.setValignment(imagePane, VPos.TOP);
			GridPane.setHalignment(imagePane, HPos.RIGHT);

			Label label = new Label();
			label.setText(empty);
			label.getStyleClass().add("storage-slot-item-title");

			grid.add(label, depth - z + 1, z + 1, Integer.MAX_VALUE, 1);
			GridPane.setValignment(label, VPos.TOP);

			images[z] = imagePane;
			labels[z] = label;

			grid.getRowConstraints().add(rowConstraints);
			grid.getColumnConstraints().add(columnConstraints);
		}
		grid.getColumnConstraints().add(columnConstraints);
		ColumnConstraints lastCC = new ColumnConstraints();
		lastCC.setPercentWidth(30D);
		grid.getColumnConstraints().add(lastCC);
		grid.getRowConstraints().add(rowConstraints);
	}

	public GridPane getGrid() {
		return grid;
	}

	public ScalingImagePane[] getImages() {
		return images;
	}

	public Label[] getLabels() {
		return labels;
	}

	private boolean canDropHere(DragEvent dragEvent) {
		if (dragEvent.getGestureSource() != grid && dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) {
			DraggedProduct origin = (DraggedProduct) dragEvent.getDragboard().getContent(DraggedProduct.FORMAT);
			if (origin instanceof DraggedProduct.Quest) {
				return WhatAStorage.getInstance().canStoreProduct(((DraggedProduct.Quest) origin).index, x, y);
			} else if (origin instanceof DraggedProduct.Slot){
				return WhatAStorage.getInstance().canMoveProduct(((DraggedProduct.Slot) origin).x, ((DraggedProduct.Slot) origin).y, x, y);
			}
		}
		return false;
	}

	private void onDragDetected(MouseEvent event) {
		int index;
		Image image = null;

		for (int z = depth - 1; z >= 0; z--) {
			if (images[z].getImage() != null) {
				image = images[z].getImage();
				break;
			}
		}
		if (image == null)
			return;

		Dragboard dragboard = grid.startDragAndDrop(TransferMode.MOVE);
		dragboard.setDragView(JFXUtil.scaleTo(image, 100));
		ClipboardContent content = new ClipboardContent();
		content.put(DraggedProduct.FORMAT, new DraggedProduct.Slot(x, y));
		dragboard.setContent(content);

		event.consume();
	}

	private void onDragEntered(DragEvent dragEvent) {
		JFXUtil.setStyleClass(grid, "drop-hover", canDropHere(dragEvent));
	}

	private void onDragExited(DragEvent dragEvent) {
		JFXUtil.setStyleClass(grid, "drop-hover", false);
	}

	private void onDragOver(DragEvent dragEvent) {
		if (canDropHere(dragEvent)) {
			dragEvent.acceptTransferModes(TransferMode.MOVE);
		}
		dragEvent.consume();
	}

	private void onDragDropped(DragEvent dragEvent) {
		if (dragEvent.getGestureSource() != grid && dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) {
			DraggedProduct origin = (DraggedProduct) dragEvent.getDragboard().getContent(DraggedProduct.FORMAT);
			if (origin instanceof DraggedProduct.Quest) {
				WhatAStorage.getInstance().userStoreProduct(((DraggedProduct.Quest) origin).index, x, y);
				dragEvent.setDropCompleted(true);
				return;
			} else if (origin instanceof DraggedProduct.Slot) {
				DraggedProduct.Slot slot = (DraggedProduct.Slot) origin;
				WhatAStorage.getInstance().userMoveProduct(slot.x, slot.y, x, y);
				dragEvent.setDropCompleted(true);
				return;
			}
		}
		dragEvent.setDropCompleted(false);
	}
}
