package ninja.ugly.prevail.example;

import com.google.common.eventbus.EventBus;

import ninja.ugly.prevail.chunk.Chunk;
import ninja.ugly.prevail.datamodel.DataModel;
import ninja.ugly.prevail.event.dispatcher.EventBusEventDispatcher;
import ninja.ugly.prevail.event.dispatcher.EventDispatcher;
import ninja.ugly.prevail.exception.InsertException;

import static ninja.ugly.prevail.chunk.VolatileChunk.KeyFactory;
import static ninja.ugly.prevail.chunk.VolatileChunk.KeyFactory.AutoIncrementingStringKeyFactory;

/**
 * An example Java application using the Prevail library.
 * <p>
 * A simple 'To Do' list is displayed to the user with options to add, delete or edit items.
 * Each item has a name and a completion status.  The items are stored in memory, however
 * this memory implementation is hidden behind a Chunk interface.  The Chunk is added to
 * a DataModel, a container for Chunks, which manages asynchronous to the chunk.  Results
 * from Chunk operations are returned to the main thread via Events to an EventDispatcher.
 * In this implementation, the EventDispatcher wraps Guava's EventBus.
 */
public class Main {
  public static void main(String args[]) throws InterruptedException, InsertException {
    // Create an EventDispatcher for the Chunk to return events on.
    EventDispatcher eventDispatcher = new EventBusEventDispatcher(new EventBus());

    // Create a Chunk in which TodoItems are accessed with String keys.
    // The implementatioon of TodoItemChunk just stores items in a HashMap, with keys
    // generated by the given KeyFactory.  Rest of the code is agnostic to the
    // particular implementation of the Chunk.
    KeyFactory<String, TodoItem> factory = new AutoIncrementingStringKeyFactory<TodoItem>();
    Chunk<String, TodoItem> chunk = new TodoItemChunk(factory);

    // Set the event dispatcher for the chunk to post events
    chunk.setEventDispatcher(eventDispatcher);

    // Create a DataModel to handle the chunk operations asynchronously.
    DataModel dataModel = new DataModel();

    // Register the Chunk on the DataModel at the default segment.
    dataModel.addChunk(chunk);

    // Start the main loop.
    new TodoListManager(dataModel, eventDispatcher).start();
  }
}