package nl.graphit.util.jsf.history;

import java.util.HashMap;
import java.util.Map;

import javax.faces.context.FacesContext;

import nl.graphit.util.IDGenerator;
import nl.graphit.util.jsf.FacesUtils;

/**
 * A session scope managed bean to keep track of certain pages, including their
 * state.
 * 
 * @author Nico Krijnen <nico.krijnen@graphit.nl>
 */
public class HistoryMarkers {

    // TODO add methods to access individual history markers and their info

    // TODO keep track of date/time for history state

    private static final String BEAN_NAME = "historyMarkers";

    private Map markers = new HashMap();

    private IDGenerator idGenerator = new IDGenerator();

    public static HistoryMarkers getCurrentInstance() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        return (HistoryMarkers) facesContext.getApplication()
                .createValueBinding("#{" + BEAN_NAME + "}").getValue(
                        facesContext);
    }

    public synchronized String getLastViewMarker() {
        ViewState viewState = HistoryManager.getCurrentInstance()
                .getLastViewState();
        String marker = viewState.getMarker();
        if (marker == null) {
            marker = generateMarker();
            markers.put(marker, viewState);
            viewState.setMarker(marker);
        }
        return marker;
    }

    public void returnToMarker() {
        String marker = (String) FacesUtils.getExternalContext()
                .getRequestParameterMap().get("historyMarker");

        ViewState viewState = (ViewState) markers.get(marker);
        if (viewState == null) {
            throw new IllegalArgumentException("Invalid history marker "
                    + marker);
        }

        // System.out.println("HistoryMarkers.returnToMarker " + marker);
        markers.remove(marker);

        FacesContext facesContext = FacesContext.getCurrentInstance();
        viewState.restore(facesContext);
    }

    /*
     * 
     */

    private String generateMarker() {
        String marker = null;
        while (marker == null || markers.get(marker) != null) {
            marker = idGenerator.generateId();
        }
        return marker;
    }

}
