package de.renew.propertymanagementgui.reactivecomponents;

/**
 * This class represents a state of a component.
 * It holds a value and a reference to the rerender method of the component.
 * When the value is changed, the rerender method is called.
 *
 * @param <T> the type of the value of the state
 */
public class State<T> {
    private T _value;
    private final Runnable _rerender;

    /**
     * Constructor for the State class.
     *
     * @param value the initial value of the state
     * @param rerender the rerender method of the component
     */
    public State(T value, Runnable rerender) {
        this._value = value;
        this._rerender = rerender;
    }

    /**
     * Returns the value of the state.
     *
     * @return the value of the state
     */
    public T getValue() {
        return _value;
    }

    /**
     * Returns the value of the state.
     * If the new value is different from the old value, the rerender method is called.
     *
     * @param value the new value of the state
     */
    public void setValue(T value) {
        T oldValue = this._value;
        if (oldValue.equals(value)) {
            return;
        }
        this._value = value;
        _rerender.run();
    }

    /**
     * Compares two states.
     *
     * @return {@code true} if the values of the states are equal or the States themselves, {@code false} otherwise
     */
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        State<?> state = (State<?>) o;
        return _value.equals(state._value);
    }
}
