/*
 * 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.place.shared.PlaceController;
import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver;
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.RequestContext;
import com.google.gwt.requestfactory.shared.ServerFailure;
import com.google.gwt.requestfactory.shared.Violation;
import com.google.gwt.sample.expenses.client.place.ProxyPlace.Operation;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

import java.util.Set;

/**
 * Abstract activity for editing a record. Subclasses must provide access to the
 * request that will be fired when Save is clicked.
 * <p>
 * Instances are not reusable. Once an activity is stoped, it cannot be
 * restarted.
 * 
 * @param <P> the type of Proxy being edited
 */
public abstract class AbstractProxyEditActivity<P extends EntityProxy> implements Activity,
    ProxyEditView.Delegate {

  private final ProxyEditView<P, ?> view;
  private final PlaceController placeController;

  private RequestFactoryEditorDriver<P, ?> editorDriver;
  private boolean waiting;

  public AbstractProxyEditActivity(ProxyEditView<P, ?> view, PlaceController placeController) {
    this.view = view;
    this.placeController = placeController;
  }

  public void cancelClicked() {
    String unsavedChangesWarning = mayStop();
    if ((unsavedChangesWarning == null)
        || Window.confirm(unsavedChangesWarning)) {
      editorDriver = null;
      exit(false);
    }
  }

  public String mayStop() {
    if (isWaiting() || changed()) {
      return "Are you sure you want to abandon your changes?";
    }

    return null;
  }

  public void onCancel() {
    onStop();
  }

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

  public void saveClicked() {
    if (!changed()) {
      return;
    }
    
    setWaiting(true);
    editorDriver.flush().fire(new Receiver<Void>() {
      /*
       * Callbacks do nothing if editorDriver is null, we were stopped in
       * midflight
       */
      @Override
      public void onFailure(ServerFailure error) {
        if (editorDriver != null) {
          setWaiting(false);
          super.onFailure(error);
        }
      }

      @Override
      public void onSuccess(Void ignore) {
        if (editorDriver != null) {
          // We want no warnings from mayStop, so:

          // Defeat isChanged check
          editorDriver = null;

          // Defeat call-in-flight check
          setWaiting(false);

          exit(true);
        }
      }

      @Override
      public void onViolation(Set<Violation> errors) {
        if (editorDriver != null) {
          setWaiting(false);
          editorDriver.setViolations(errors);
        }
      }
    });
  }

  public void start(AcceptsOneWidget display, EventBus eventBus) {
    editorDriver = view.createEditorDriver();
    view.setDelegate(this);
    editorDriver.edit(getProxy(), createSaveRequest(getProxy()));
    display.setWidget(view);
  }

  /**
   * Called once to create the appropriate request to save
   * changes.
   * 
   * @return the request context to fire when the save button is clicked
   */
  protected abstract RequestContext createSaveRequest(P proxy);

  /**
   * Called when the user cancels or has successfully saved. This default
   * implementation tells the {@link PlaceController} to show the details of the
   * edited record.
   * 
   * @param saved true if changes were comitted, false if user canceled
   */
  protected void exit(@SuppressWarnings("unused") boolean saved) {
    placeController.goTo(new ProxyPlace(getProxyId(), Operation.DETAILS));
  }

  /**
   * Get the proxy to be edited. Must be mutable, typically via a call to
   * {@link RequestContext#edit(EntityProxy)}, or
   * {@link RequestContext#create(Class)}.
   */
  protected abstract P getProxy();

  @SuppressWarnings("unchecked")
  // id type always matches proxy type
  protected EntityProxyId<P> getProxyId() {
    return (EntityProxyId<P>) getProxy().stableId();
  }

  private boolean changed() {
    return editorDriver != null && editorDriver.flush().isChanged();
  }

  /**
   * @return true if we're waiting for an rpc response.
   */
  private boolean isWaiting() {
    return waiting;
  }

  /**
   * While we are waiting for a response, we cannot poke setters on the proxy
   * (that is, we cannot call editorDriver.flush). So we set the waiting flag to
   * warn ourselves not to, and to disable the view.
   */
  private void setWaiting(boolean wait) {
    this.waiting = wait;
    view.setEnabled(!wait);
  }
}
