/*
 * 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.web.bindery.requestfactory.gwt.client.impl;

import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.impl.AbstractEditorDelegate;
import com.google.gwt.editor.client.impl.Refresher;
// This import is not an accident, details in subscribe() implementation
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.BaseProxy;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.EntityProxyChange;
import com.google.web.bindery.requestfactory.shared.EntityProxyId;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.WriteOperation;
import com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext;

import java.util.List;

/**
 * Base class for generated EditorDelegates using a RequestFactory as the
 * backend.
 * 
 * @param <P> the type of Proxy
 * @param <E> the type of Editor
 */
public abstract class RequestFactoryEditorDelegate<P, E extends Editor<P>>
    extends AbstractEditorDelegate<P, E> {
  private class SubscriptionHandler implements
      EntityProxyChange.Handler<EntityProxy> {

    public void onProxyChange(EntityProxyChange<EntityProxy> event) {
      if (event.getWriteOperation().equals(WriteOperation.UPDATE)
          && event.getProxyId().equals(((EntityProxy) getObject()).stableId())) {
        PathCollector collector = new PathCollector();
        accept(collector);
        EntityProxyId<?> id = event.getProxyId();
        doFind(collector.getPaths(), id);
      }
    }

    @SuppressWarnings(value = {"rawtypes", "unchecked"})
    private void doFind(List<String> paths, EntityProxyId id) {
      factory.find(id).with(paths.toArray(new String[paths.size()])).fire(
          new SubscriptionReceiver());
    }
  }

  private class SubscriptionReceiver extends Receiver<EntityProxy> {
    @Override
    public void onSuccess(EntityProxy response) {
      @SuppressWarnings("unchecked")
      P cast = (P) response;
      setObject(cast);
      accept(new Refresher());
    }
  }

  protected EventBus eventBus;
  protected RequestFactory factory;
  protected RequestContext request;

  public void setRequestContext(RequestContext request) {
    this.request = request;
  }

  @Override
  public HandlerRegistration subscribe() {
    if (factory == null) {
      /*
       * They called the no-subscriptions version of
       * RequestFactoryEditorDriver#initialize
       */
      return null;
    }

    if (!(getObject() instanceof EntityProxy)) {
      /*
       * This is kind of weird. The user is asking for notifications on a
       * String, which means there's a HasEditorDelegate<String> in play and not
       * the usual LeafValueEditor<String>.
       */
      return null;
    }

    // Can't just use getObject().getClass() because it's not the proxy type
    EntityProxyId<?> stableId = ((EntityProxy) getObject()).stableId();
    @SuppressWarnings("unchecked")
    Class<EntityProxy> clazz = (Class<EntityProxy>) stableId.getProxyClass();

    /*
     * Convert to the old gwt HandlerRegistration type required by the
     * EditorDelegate interface. This can get cleaned up when Editor moves to
     * com.google.web.bindery.
     */
    final com.google.web.bindery.event.shared.HandlerRegistration toReturn =
        EntityProxyChange.<EntityProxy> registerForProxyType(eventBus, clazz,
            new SubscriptionHandler());
    return new HandlerRegistration() {
      public void removeHandler() {
        toReturn.removeHandler();
      }
    };
  }

  @Override
  protected <R, S extends Editor<R>> void addSubDelegate(
      AbstractEditorDelegate<R, S> subDelegate, String path, S subEditor) {
    RequestFactoryEditorDelegate<R, S> d = (RequestFactoryEditorDelegate<R, S>) subDelegate;
    d.initialize(eventBus, factory, path, subEditor);
  }

  @Override
  protected <T> T ensureMutable(T object) {
    if (request == null) {
      // Read-only mode
      return object;
    }
    if (object instanceof BaseProxy) {
      @SuppressWarnings("unchecked")
      T toReturn = (T) request.edit((BaseProxy) object);
      return toReturn;
    }
    return object;
  }

  protected void initialize(EventBus eventBus, RequestFactory factory,
      String pathSoFar, E editor) {
    this.eventBus = eventBus;
    this.factory = factory;
    super.initialize(pathSoFar, editor);
  }

  /**
   * Must call four-arg version instead.
   */
  @Override
  protected void initialize(String pathSoFar, E editor) {
    throw new UnsupportedOperationException();
  }

  @Override
  protected boolean shouldFlush() {
    if (request == null) {
      return false;
    }
    if (request instanceof AbstractRequestContext) {
      return !((AbstractRequestContext) request).isLocked();
    }
    return true;
  }
}
