package com.ht.ui.util;

import java.util.LinkedList;

import javafx.scene.Node;

public class RedoUndoManager {

	private LinkedList<Runnable> undoList = new LinkedList<Runnable>();
	private LinkedList<Runnable> redoList = new LinkedList<Runnable>();
	private int currentUndoRedoIndex = -1;
	private final int maxUndoRedoSize = 100;
	private Node undoButton;
	private Node redoButton;
	
	public RedoUndoManager(Node undoButton, Node redoButton) {
		this.undoButton = undoButton;
		this.redoButton = redoButton;
		
		this.undoButton.setDisable(true);
		this.redoButton.setDisable(true);
	}
	
	public void reset() {
		this.undoList.clear();
		this.redoList.clear();
		this.undoButton.setDisable(true);
		this.redoButton.setDisable(true);
		currentUndoRedoIndex = -1;
	}
	
	public void redo() {
		if ((currentUndoRedoIndex + 1) >= 0 && (currentUndoRedoIndex + 1) < undoList.size()) {
			redoList.get(currentUndoRedoIndex + 1).run();
			currentUndoRedoIndex++;
			
			undoButton.setDisable(false);
			if (currentUndoRedoIndex + 1 >= redoList.size()) {
				redoButton.setDisable(true);
			}
		}
	}

	public void undo() {
		if (currentUndoRedoIndex >= 0 && currentUndoRedoIndex < undoList.size()) {
			undoList.get(currentUndoRedoIndex).run();
			currentUndoRedoIndex--;
			
			redoButton.setDisable(false);
			if (currentUndoRedoIndex < 0) {
				undoButton.setDisable(true);
			}
		}
	}

	public void updateUndoRedoList(Runnable undo, Runnable redo) {

		while (undoList.size() - 1 > currentUndoRedoIndex) {
			undoList.removeLast();
			redoList.removeLast();
			if (undoList.size() == 0) {
				break;
			}
		}

		undoList.addLast(undo);
		redoList.addLast(redo);
		if (undoList.size() > maxUndoRedoSize) {
			undoList.removeFirst();
			redoList.removeFirst();
		}

		currentUndoRedoIndex = undoList.size() - 1;

		undoButton.setDisable(false);
		redoButton.setDisable(true);
	}
	
}
