/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.sample.expenses.client.place;

import com.google.gwt.activity.shared.Activity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.EntityProxyChange;
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.requestfactory.shared.WriteOperation;
import com.google.gwt.sample.expenses.client.place.ProxyPlace.Operation;
import com.google.gwt.user.cellview.client.AbstractHasData;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.RangeChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Abstract activity for displaying a list of {@link EntityProxy}. These
 * activities are not re-usable. Once they are stopped, they cannot be
 * restarted.
 * <p>
 * Subclasses must:
 * 
 * <ul>
 * <li>provide a {@link ProxyListView}
 * <li>implement method to request a full count
 * <li>implement method to find a range of entities
 * <li>respond to "show details" commands
 * </ul>
 * <p>
 * Only the properties required by the view will be requested.
 * 
 * @param <P> the type of {@link EntityProxy} listed
 */
public abstract class AbstractProxyListActivity<P extends EntityProxy>
    implements Activity, ProxyListView.Delegate<P> {

  /**
   * This mapping allows us to update individual rows as records change.
   */
  private final Map<EntityProxyId<P>, Integer> idToRow = new HashMap<EntityProxyId<P>, Integer>();
  private final Map<EntityProxyId<P>, P> idToProxy = new HashMap<EntityProxyId<P>, P>();

  private final PlaceController placeController;
  private final SingleSelectionModel<P> selectionModel;
  private final Class<P> proxyClass;

  private HandlerRegistration rangeChangeHandler;
  private ProxyListView<P> view;
  private AcceptsOneWidget display;

  public AbstractProxyListActivity(PlaceController placeController,
      ProxyListView<P> view, Class<P> proxyType) {
    this.view = view;
    this.placeController = placeController;
    this.proxyClass = proxyType;
    view.setDelegate(this);

    final HasData<P> hasData = view.asHasData();
    rangeChangeHandler = hasData.addRangeChangeHandler(new RangeChangeEvent.Handler() {
      public void onRangeChange(RangeChangeEvent event) {
        AbstractProxyListActivity.this.onRangeChanged(hasData);
      }
    });

    // Inherit the view's key provider
    ProvidesKey<P> keyProvider = ((AbstractHasData<P>) hasData).getKeyProvider();
    selectionModel = new SingleSelectionModel<P>(keyProvider);
    hasData.setSelectionModel(selectionModel);

    selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
      public void onSelectionChange(SelectionChangeEvent event) {
        P selectedObject = selectionModel.getSelectedObject();
        if (selectedObject != null) {
          showDetails(selectedObject);
        }
      }
    });
  }

  public void createClicked() {
    placeController.goTo(new ProxyPlace(proxyClass));
  }

  public ProxyListView<P> getView() {
    return view;
  }

  public String mayStop() {
    return null;
  }

  public void onCancel() {
    onStop();
  }

  /**
   * Called by the table as it needs data.
   */
  public void onRangeChanged(HasData<P> listView) {
    final Range range = listView.getVisibleRange();

    final Receiver<List<P>> callback = new Receiver<List<P>>() {
      @Override
      public void onSuccess(List<P> values) {
        if (view == null) {
          // This activity is dead
          return;
        }
        idToRow.clear();
        idToProxy.clear();
        for (int i = 0, row = range.getStart(); i < values.size(); i++, row++) {
          P proxy = values.get(i);
          @SuppressWarnings("unchecked")
          // Why is this cast needed?
          EntityProxyId<P> proxyId = (EntityProxyId<P>) proxy.stableId();
          idToRow.put(proxyId, row);
          idToProxy.put(proxyId, proxy);
        }
        getView().asHasData().setRowData(range.getStart(), values);
        if (display != null) {
          display.setWidget(getView());
        }
      }
    };

    fireRangeRequest(range, callback);
  }

  public void onStop() {
    view.setDelegate(null);
    view = null;
    rangeChangeHandler.removeHandler();
    rangeChangeHandler = null;
  }

  /**
   * Select the given record, or clear the selection if called with null or an
   * id we don't know.
   */
  public void select(EntityProxyId<P> proxyId) {
    /*
     * The selectionModel will not flash if we put it back to the same state it
     * is already in, so we can keep this code simple.
     */

    // Clear the selection
    P selected = selectionModel.getSelectedObject();
    if (selected != null) {
      selectionModel.setSelected(selected, false);
    }

    // Select the new proxy, if it's relevant
    if (proxyId != null) {
      P selectMe = idToProxy.get(proxyId);
      selectionModel.setSelected(selectMe, true);
    }
  }

  public void start(AcceptsOneWidget display, EventBus eventBus) {
    view.setDelegate(this);
    EntityProxyChange.registerForProxyType(eventBus, proxyClass,
        new EntityProxyChange.Handler<P>() {
          public void onProxyChange(EntityProxyChange<P> event) {
            update(event.getWriteOperation(), event.getProxyId());
          }
        });
    eventBus.addHandler(PlaceChangeEvent.TYPE, new PlaceChangeEvent.Handler() {
      public void onPlaceChange(PlaceChangeEvent event) {
        updateSelection(event.getNewPlace());
      }
    });
    this.display = display;
    init();
    updateSelection(placeController.getWhere());
  }

  public void update(WriteOperation writeOperation, EntityProxyId<P> proxyId) {
    switch (writeOperation) {
      case UPDATE:
        update(proxyId);
        break;

      case DELETE:
        init();
        break;

      case PERSIST:
        /*
         * On create, we presume the new record is at the end of the list, so
         * fetch the last page of items.
         */
        getLastPage();
        break;
    }
  }

  protected abstract Request<List<P>> createRangeRequest(Range range);

  protected abstract void fireCountRequest(Receiver<Long> callback);

  /**
   * Called when the user chooses a record to view. This default implementation
   * sends the {@link PlaceController} to an appropriate {@link ProxyPlace}.
   * 
   * @param record the chosen record
   */
  protected void showDetails(P record) {
    placeController.goTo(new ProxyPlace(record.stableId(), Operation.DETAILS));
  }

  @SuppressWarnings("unchecked")
  private EntityProxyId<P> cast(ProxyPlace proxyPlace) {
    return (EntityProxyId<P>) proxyPlace.getProxyId();
  }

  private void fireRangeRequest(final Range range,
      final Receiver<List<P>> callback) {
    createRangeRequest(range).with(getView().getPaths()).fire(callback);
  }

  private void getLastPage() {
    fireCountRequest(new Receiver<Long>() {
      @Override
      public void onSuccess(Long response) {
        if (view == null) {
          // This activity is dead
          return;
        }
        HasData<P> table = getView().asHasData();
        int rows = response.intValue();
        table.setRowCount(rows, true);
        if (rows > 0) {
          int pageSize = table.getVisibleRange().getLength();
          int remnant = rows % pageSize;
          if (remnant == 0) {
            table.setVisibleRange(rows - pageSize, pageSize);
          } else {
            table.setVisibleRange(rows - remnant, pageSize);
          }
        }
        onRangeChanged(table);
      }
    });
  }

  private void init() {
    fireCountRequest(new Receiver<Long>() {
      @Override
      public void onSuccess(Long response) {
        if (view == null) {
          // This activity is dead
          return;
        }
        getView().asHasData().setRowCount(response.intValue(), true);
        onRangeChanged(view.asHasData());
      }
    });
  }

  private void update(EntityProxyId<P> proxyId) {
    final Integer row = idToRow.get(proxyId);
    if (row == null) {
      return;
    }
    fireRangeRequest(new Range(row, 1), new Receiver<List<P>>() {
      @Override
      public void onSuccess(List<P> response) {
        getView().asHasData().setRowData(row,
            Collections.singletonList(response.get(0)));
      }
    });
  }

  private void updateSelection(Place newPlace) {
    if (newPlace instanceof ProxyPlace) {
      ProxyPlace proxyPlace = (ProxyPlace) newPlace;
      if (proxyPlace.getOperation() != Operation.CREATE
          && proxyPlace.getProxyClass().equals(proxyClass)) {
        select(cast(proxyPlace));
        return;
      }
    }

    select(null);
  }
}
