/*
 * 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.app.place;

import com.google.gwt.app.place.ProxyPlace.Operation;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.RecordRequest;
import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.RequestObject;
import com.google.gwt.user.client.Window;
import com.google.gwt.valuestore.shared.Record;
import com.google.gwt.valuestore.shared.SyncResult;
import com.google.gwt.valuestore.shared.Value;

import java.util.Set;

/**
 * <p>
 * <span style="color:red">Experimental API: This class is still under rapid
 * development, and is very likely to be deleted. Use it at your own risk.
 * </span>
 * </p>
 * Abstract activity for editing a record.
 * 
 * @param <R> the type of Record being edited
 */
public abstract class AbstractRecordEditActivity<R extends Record> implements
    Activity, RecordEditView.Delegate {

  private RequestObject<Void> requestObject;

  private final boolean creating;
  private final RecordEditView<R> view;
  private final Class<R> proxyType;
  private final RequestFactory requests;
  private final PlaceController placeController;

  private R record;
  private Long futureId;
  private Display display;

  public AbstractRecordEditActivity(RecordEditView<R> view, R record,
      Class<R> proxyType, boolean creating, RequestFactory requests,
      PlaceController placeController) {

    this.view = view;
    this.record = record;
    this.proxyType = proxyType;
    this.placeController = placeController;
    this.creating = creating;
    this.requests = requests;
  }

  public void cancelClicked() {
    String unsavedChangesWarning = mayStop();
    if ((unsavedChangesWarning == null)
        || Window.confirm(unsavedChangesWarning)) {
      if (requestObject != null) {
        // silence the next mayStop() call when place changes
        requestObject.reset();
      }
      exit(false);
    }
  }

  public R getRecord() {
    return record;
  }

  public RecordEditView<R> getView() {
    return view;
  }

  public String mayStop() {
    if (requestObject != null && requestObject.isChanged()) {
      return "Are you sure you want to abandon your changes?";
    }

    return null;
  }
  
  public void onCancel() {
    onStop();
  }

  public void onStop() {
    this.display = null;
  }

  public void saveClicked() {
    assert requestObject != null;
    if (!requestObject.isChanged()) {
      return;
    }
    view.setEnabled(false);

    final RequestObject<Void> toCommit = requestObject;
    requestObject = null;

    Receiver<Void> receiver = new Receiver<Void>() {
      public void onSuccess(Void ignore, Set<SyncResult> response) {
        if (display == null) {
          return;
        }
        boolean hasViolations = false;

         for (SyncResult syncResult : response) {
          Record syncRecord = syncResult.getRecord();
          if (creating) {
            if (futureId == null || !futureId.equals(syncResult.getFutureId())) {
              continue;
            }
            record = cast(syncRecord);
          } else {
            if (!syncRecord.getId().equals(record.getId())) {
              continue;
            }
          }
          if (syncResult.hasViolations()) {
            hasViolations = true;
            view.showErrors(syncResult.getViolations());
          }
        }
        if (!hasViolations) {
          exit(true);
        } else {
          requestObject = toCommit;
          requestObject.clearUsed();
          view.setEnabled(true);
        }
      }
    };
    toCommit.fire(receiver);
  }

  public void start(Display display, EventBus eventBus) {
    this.display = display;

    view.setDelegate(this);
    view.setCreating(creating);

    if (creating) {
      R tempRecord = requests.create(proxyType);
      futureId = tempRecord.getId();
      doStart(display, tempRecord);
    } else {
      RecordRequest<R> findRequest = getFindRequest(Value.of(getRecord().getId()));
      findRequest.with(getView().getPaths()).fire(new Receiver<R>() {
        public void onSuccess(R record, Set<SyncResult> syncResults) {
          if (AbstractRecordEditActivity.this.display != null) {
            doStart(AbstractRecordEditActivity.this.display, record);
          }
        }
      });
    }
  }

  /**
   * Called when the user cancels or has successfully saved. This default
   * implementation tells the {@link PlaceController} to show the details of the
   * edited record, or clears the display if a creation was canceled.
   * <p>
   * If we're creating, a call to getRecord() from here will return a record
   * with the correct id. However, other properties may be stale or unset.
   * 
   * @param saved true if changes were comitted
   */
  protected void exit(boolean saved) {
    if (!saved && creating) {
      display.showActivityWidget(null);
    } else {
      placeController.goTo(new ProxyPlace(getRecord(), Operation.DETAILS));
    }
  }

  /**
   * Called to fetch the details of the edited record.
   */
  protected abstract RecordRequest<R> getFindRequest(Value<Long> id);

  protected abstract RequestObject<Void> getPersistRequest(R record);

  @SuppressWarnings("unchecked")
  private R cast(Record syncRecord) {
    return (R) syncRecord;
  }

  private void doStart(final Display display, R record) {
    requestObject = getPersistRequest(record);
    R editableRecord = requestObject.edit(record);
    view.setEnabled(true);
    view.setValue(editableRecord);
    view.showErrors(null);
    display.showActivityWidget(view);
  }
}
