/*
 * 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.dynatablerf.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.requestfactory.shared.RequestContext;
import com.google.gwt.requestfactory.shared.Violation;
import com.google.gwt.sample.dynatablerf.client.events.EditPersonEvent;
import com.google.gwt.sample.dynatablerf.client.widgets.PersonEditor;
import com.google.gwt.sample.dynatablerf.shared.DynaTableRequestFactory;
import com.google.gwt.sample.dynatablerf.shared.DynaTableRequestFactory.PersonRequest;
import com.google.gwt.sample.dynatablerf.shared.PersonProxy;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTMLPanel;

import java.util.Set;

/**
 * This class shows how the UI for editing a person is wired up to the
 * RequestFactoryEditorDelegate. It is also responsible for showing and
 * dismissing the PersonEditor. The use of the FavoriteManager shows integration
 * between a remote service and a local service.
 */
public class PersonEditorWorkflow {
  interface Binder extends UiBinder<DialogBox, PersonEditorWorkflow> {
    Binder BINDER = GWT.create(Binder.class);
  }

  interface Driver extends
      RequestFactoryEditorDriver<PersonProxy, PersonEditor> {
  }

  static void register(EventBus eventBus,
      final DynaTableRequestFactory requestFactory,
      final FavoritesManager manager) {
    eventBus.addHandler(EditPersonEvent.TYPE, new EditPersonEvent.Handler() {
      public void startEdit(PersonProxy person, RequestContext requestContext) {
        new PersonEditorWorkflow(requestFactory, manager, person).edit(requestContext);
      }
    });
  }

  @UiField
  HTMLPanel contents;

  @UiField
  DialogBox dialog;

  @UiField
  CheckBox favorite;

  @UiField(provided = true)
  PersonEditor personEditor;

  private Driver editorDriver;
  private final FavoritesManager manager;
  private PersonProxy person;
  private final DynaTableRequestFactory requestFactory;

  private PersonEditorWorkflow(DynaTableRequestFactory requestFactory,
      FavoritesManager manager, PersonProxy person) {
    this.requestFactory = requestFactory;
    this.manager = manager;
    this.person = person;
    personEditor = new PersonEditor(requestFactory);
    Binder.BINDER.createAndBindUi(this);
    contents.addDomHandler(new KeyUpHandler() {
      public void onKeyUp(KeyUpEvent event) {
        if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
          onCancel(null);
        }
      }
    }, KeyUpEvent.getType());
    this.favorite.setVisible(false);
  }

  /**
   * Called by the cancel button when it is clicked. This method will just tear
   * down the UI and clear the state of the workflow.
   */
  @UiHandler("cancel")
  void onCancel(ClickEvent event) {
    dialog.hide();
  }

  /**
   * Called by the edit dialog's save button. This method will flush the
   * contents of the UI into the PersonProxy that is being edited, check for
   * errors, and send the request to the server.
   */
  @UiHandler("save")
  void onSave(ClickEvent event) {
    // Flush the contents of the UI
    RequestContext context = editorDriver.flush();

    // Check for errors
    if (editorDriver.hasErrors()) {
      dialog.setText("Errors detected locally");
      return;
    }

    // Send the request
    context.fire(new Receiver<Void>() {
      @Override
      public void onSuccess(Void response) {
        // If everything went as planned, just dismiss the dialog box
        dialog.hide();
      }

      @Override
      public void onViolation(Set<Violation> errors) {
        // Otherwise, show ConstraintViolations in the UI
        dialog.setText("Errors detected on the server");
        editorDriver.setViolations(errors);
      }
    });
  }

  /**
   * Called by the favorite checkbox when its value has been toggled.
   */
  @UiHandler("favorite")
  void onValueChanged(ValueChangeEvent<Boolean> event) {
    manager.setFavorite(person.stableId(), favorite.getValue());
  }

  /**
   * Construct and display the UI that will be used to edit the current
   * PersonProxy, using the given RequestContext to accumulate the edits.
   */
  private void edit(RequestContext requestContext) {
    editorDriver = GWT.create(Driver.class);
    editorDriver.initialize(requestFactory, personEditor);
    
    if (requestContext == null) {
      this.favorite.setVisible(true);
      fetchAndEdit();
      return;
    }

    editorDriver.edit(person, requestContext);
    personEditor.focus();
    favorite.setValue(manager.isFavorite(person), false);
    dialog.center();
  }

  private void fetchAndEdit() {
    // The request is configured arbitrarily
    Request<PersonProxy> fetchRequest = requestFactory.find(person.stableId());

    // Add the paths that the EditorDrives computes
    fetchRequest.with(editorDriver.getPaths());

    // We could do more with the request, but we just fire it
    fetchRequest.to(new Receiver<PersonProxy>() {
      @Override
      public void onSuccess(PersonProxy person) {
        PersonEditorWorkflow.this.person = person;
        // Start the edit process
        PersonRequest context = requestFactory.personRequest();
        // Display the UI
        edit(context);
        // Configure the method invocation to be sent in the context
        context.persist().using(person);
        // The context will be fire()'ed from the onSave() method
      }
    }).fire();
  }
}
