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

import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDriver;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.requestfactory.shared.RequestContext;
import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.Violation;

/**
 * The interface that links RequestFactory and the Editor framework together.
 * <p>
 * Instances of this interface are created with
 *
 * <pre>
 * interface MyRFED extends RequestFactoryEditorDriver&lt;MyObjectProxy, MyObjectEditor> {}
 * MyRFED instance = GWT.create(MyRFED.class);
 * {
 * instance.initialize(.....);
 * myRequest.with(instance.getPaths());
 *
 * // Fire the request, in the callback
 * instance.edit(retrievedRecord);
 * // Control when the request is sent
 * instance.flush().fire(new Receiver {...});
 * }
 * </pre>
 *
 * <p><span style='color:red'>RequestFactory has moved to
 * <code>com.google.web.bindery.requestfactory</code>.  This package will be
 * removed in a future version of GWT.</span></p>
 *
 * @param <P> the type of Proxy being edited
 * @param <E> the type of Editor that will edit the Record
 *
 * @see HasRequestContext
 * @see {@link com.google.gwt.requestfactory.client.testing.MockRequestFactoryEditorDriver
 *      MockRequestFactoryEditorDriver}
 */
@Deprecated
public interface RequestFactoryEditorDriver<P, E extends Editor<? super P>>
    extends EditorDriver<RequestContext> {
  /**
   * Start driving the Editor and its sub-editors with data for display-only
   * mode.
   *
   * @param proxy a Proxy of type P
   */
  void display(P proxy);

  /**
   * Start driving the Editor and its sub-editors with data. A
   * {@link RequestContext} is required to provide context for the changes to
   * the proxy (see {@link RequestContext#edit}. Note that this driver will not
   * fire the request.
   *
   * @param proxy the proxy to be edited
   * @param request the request context that will accumulate edits and is
   *          returned form {@link #flush}
   */
  void edit(P proxy, RequestContext request);

  /**
   * Update the object being edited with the current state of the Editor.
   *
   * @return the RequestContext passed into
   *         {@link #edit(Object, RequestContext)}
   * @throws IllegalStateException if {@link #edit(Object, RequestContext)} has
   *           not been called
   */
  RequestContext flush();

  /**
   * Returns a new array containing the request paths.
   *
   * @return an array of Strings
   */
  String[] getPaths();

  /**
   * Overload of {@link #initialize(RequestFactory, Editor)} to allow a modified
   * {@link EventBus} to be monitored for subscription services.
   *
   * @param eventBus the {@link EventBus}
   * @param requestFactory a {@link RequestFactory} instance
   * @param editor an {@link Editor} of type E
   *
   * @see com.google.gwt.editor.client.EditorDelegate#subscribe
   * @see com.google.gwt.event.shared.ResettableEventBus
   */
  void initialize(EventBus eventBus, RequestFactory requestFactory, E editor);

  /**
   * Initializes a driver with the editor it will run, and a RequestFactory to
   * use for subscription services.
   *
   * @param requestFactory a {@link RequestFactory} instance
   * @param editor an {@link Editor} of type E
   *
   * @see com.google.gwt.editor.client.EditorDelegate#subscribe
   */
  void initialize(RequestFactory requestFactory, E editor);

  /**
   * Initializes a driver that will not be able to support subscriptions. Calls
   * to {@link com.google.gwt.editor.client.EditorDelegate#subscribe()} will do
   * nothing.
   *
   * @param editor an {@link Editor} of type E
   */
  void initialize(E editor);

  /**
   * Show Violations returned from an attempt to submit a request. The
   * violations will be converted into
   * {@link com.google.gwt.editor.client.EditorError EditorError} objects whose
   * {@link com.google.gwt.editor.client.EditorError#getUserData()
   * getUserData()} method can be used to access the original Violation object.
   *
   * @param violations an Iterable over {@link Violation} instances
   * @return <code>true</code> if there were any unconsumed EditorErrors which
   *         can be retrieved from {@link #getErrors()}
   */
  boolean setViolations(Iterable<Violation> violations);
}
