/*
 * Copyright 2008 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.showcase.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.LazyPanel;
import com.google.gwt.user.client.ui.Widget;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * A widget used to show GWT examples in the ContentPanel.
 * </p>
 * <p>
 * This {@link Widget} uses a lazy initialization mechanism so that the content
 * is not rendered until the onInitialize method is called, which happens the
 * first time the {@link Widget} is added to the page. The data in the source
 * and css tabs are loaded using an RPC call to the server.
 * </p>
 */
public abstract class ContentWidget extends LazyPanel
    implements HasValueChangeHandlers<String> {

  /**
   * Generic callback used for asynchronously loaded data.
   *
   * @param <T> the data type
   */
  public static interface Callback<T> {
    void onError();

    void onSuccess(T value);
  }

  /**
   * Get the simple filename of a class.
   *
   * @param c the class
   */
  protected static String getSimpleName(Class<?> c) {
    String name = c.getName();
    return name.substring(name.lastIndexOf(".") + 1);
  }

  /**
   * A description of the example.
   */
  private final String description;

  /**
   * True if this example has associated styles, false if not.
   */
  private final boolean hasStyle;

  /**
   * The name of the example.
   */
  private final String name;

  /**
   * A mapping of filenames to their raw source code. The map is populated as
   * source is loaded.
   */
  private final Map<String, String> rawSource = new HashMap<String, String>();

  /**
   * A list of filenames of the raw source code included with this example.
   */
  private final List<String> rawSourceFilenames = new ArrayList<String>();

  /**
   * The source code associated with this widget.
   */
  private String sourceCode;

  /**
   * A style definitions used by this widget.
   */
  private String styleDefs;

  /**
   * The view that holds the name, description, and example.
   */
  private ContentWidgetView view;

  /**
   * Whether the demo widget has been initialized.
   */
  private boolean widgetInitialized;

  /**
   * Whether the demo widget is (asynchronously) initializing.
   */
  private boolean widgetInitializing;

  /**
   * Construct a {@link ContentWidget}.
   *
   * @param name the name of the example
   * @param description a description of the example
   * @param hasStyle true if the example has associated styles
   * @param rawSourceFiles the list of raw source files to include
   */
  public ContentWidget(String name, String description, boolean hasStyle,
      String... rawSourceFiles) {
    this.name = name;
    this.description = description;
    this.hasStyle = hasStyle;
    if (rawSourceFiles != null) {
      for (String rawSourceFile : rawSourceFiles) {
        rawSourceFilenames.add(rawSourceFile);
      }
    }
  }

  public HandlerRegistration addValueChangeHandler(
      ValueChangeHandler<String> handler) {
    return addHandler(handler, ValueChangeEvent.getType());
  }

  @Override
  public void ensureWidget() {
    super.ensureWidget();
    ensureWidgetInitialized();
  }

  /**
   * Get the description of this example.
   *
   * @return a description for this example
   */
  public final String getDescription() {
    return description;
  }

  /**
   * Get the name of this example to use as a title.
   *
   * @return a name for this example
   */
  public final String getName() {
    return name;
  }

  /**
   * Get the source code for a raw file.
   *
   * @param filename the filename to load
   * @param callback the callback to call when loaded
   */
  public void getRawSource(
      final String filename, final Callback<String> callback) {
    if (rawSource.containsKey(filename)) {
      callback.onSuccess(rawSource.get(filename));
    } else {
      RequestCallback rc = new RequestCallback() {
        public void onError(Request request, Throwable exception) {
          callback.onError();
        }

        public void onResponseReceived(Request request, Response response) {
          String text = response.getText();
          rawSource.put(filename, text);
          callback.onSuccess(text);
        }
      };

      String className = this.getClass().getName();
      className = className.substring(className.lastIndexOf(".") + 1);
      sendSourceRequest(
          rc, ShowcaseConstants.DST_SOURCE_RAW + filename + ".html");
    }
  }

  /**
   * Get the filenames of the raw source files.
   *
   * @return the raw source files.
   */
  public List<String> getRawSourceFilenames() {
    return Collections.unmodifiableList(rawSourceFilenames);
  }

  /**
   * Request the styles associated with the widget.
   *
   * @param callback the callback used when the styles become available
   */
  public void getStyle(final Callback<String> callback) {
    if (styleDefs != null) {
      callback.onSuccess(styleDefs);
    } else {
      RequestCallback rc = new RequestCallback() {
        public void onError(Request request, Throwable exception) {
          callback.onError();
        }

        public void onResponseReceived(Request request, Response response) {
          styleDefs = response.getText();
          callback.onSuccess(styleDefs);
        }
      };

      String srcPath = ShowcaseConstants.DST_SOURCE_STYLE + "standard";
      if (LocaleInfo.getCurrentLocale().isRTL()) {
        srcPath += "_rtl";
      }
      String className = this.getClass().getName();
      className = className.substring(className.lastIndexOf(".") + 1);
      sendSourceRequest(rc, srcPath + "/" + className + ".html");
    }
  }

  /**
   * Request the source code associated with the widget.
   *
   * @param callback the callback used when the source become available
   */
  public void getSource(final Callback<String> callback) {
    if (sourceCode != null) {
      callback.onSuccess(sourceCode);
    } else {
      RequestCallback rc = new RequestCallback() {
        public void onError(Request request, Throwable exception) {
          callback.onError();
        }

        public void onResponseReceived(Request request, Response response) {
          sourceCode = response.getText();
          callback.onSuccess(sourceCode);
        }
      };

      String className = this.getClass().getName();
      className = className.substring(className.lastIndexOf(".") + 1);
      sendSourceRequest(
          rc, ShowcaseConstants.DST_SOURCE_EXAMPLE + className + ".html");
    }
  }

  /**
   * Returns true if this widget has a style section.
   *
   * @return true if style tab available
   */
  public final boolean hasStyle() {
    return hasStyle;
  }

  /**
   * When the widget is first initialized, this method is called. If it returns
   * a Widget, the widget will be added as the first tab. Return null to disable
   * the first tab.
   *
   * @return the widget to add to the first tab
   */
  public abstract Widget onInitialize();

  /**
   * Called when initialization has completed and the widget has been added to
   * the page.
   */
  public void onInitializeComplete() {
  }

  protected abstract void asyncOnInitialize(
      final AsyncCallback<Widget> callback);

  /**
   * Initialize this widget by creating the elements that should be added to the
   * page.
   */
  @Override
  protected final Widget createWidget() {
    view = new ContentWidgetView();
    view.setName(getName());
    view.setDescription(getDescription());
    return view;
  }

  /**
   * Fire a {@link ValueChangeEvent} indicating that the user wishes to see the
   * specified source file.
   *
   * @param filename the filename that the user wishes to see
   */
  protected void fireRawSourceRequest(String filename) {
    if (!rawSourceFilenames.contains(filename)) {
      throw new IllegalArgumentException(
          "Filename is not registered with this example: " + filename);
    }
    ValueChangeEvent.fire(this, filename);
  }

  @Override
  protected void onLoad() {
    ensureWidget();
  }

  /**
   * Ensure that the demo widget has been initialized. Note that initialization
   * can fail if there is a network failure.
   */
  private void ensureWidgetInitialized() {
    if (widgetInitializing || widgetInitialized) {
      return;
    }

    widgetInitializing = true;

    asyncOnInitialize(new AsyncCallback<Widget>() {
      public void onFailure(Throwable reason) {
        widgetInitializing = false;
        Window.alert(
            "Failed to download code for this widget (" + reason + ")");
      }

      public void onSuccess(Widget result) {
        widgetInitializing = false;
        widgetInitialized = true;

        Widget widget = result;
        if (widget != null) {
          view.setExample(widget);
        }
        onInitializeComplete();
      }
    });
  }

  /**
   * Send a request for source code.
   *
   * @param callback the {@link RequestCallback} to send
   * @param url the URL to target
   */
  private void sendSourceRequest(RequestCallback callback, String url) {
    RequestBuilder builder = new RequestBuilder(
        RequestBuilder.GET, GWT.getModuleBaseURL() + url);
    builder.setCallback(callback);
    try {
      builder.send();
    } catch (RequestException e) {
      callback.onError(null, e);
    }
  }
}
