/*
 * 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 elemental.js;

import com.google.gwt.core.client.GWT;

import elemental.client.Browser;
import elemental.html.Navigator;
import elemental.js.dom.JsDocument;
import elemental.js.html.JsWindow;

/**
 * JavaScript native implementation of {@link elemental.client.Browser}.
 */
@Deprecated
public class JsBrowser {
  /**
   * A {@link Browser.Info} implementation for when the browser is known to be
   * Gecko at compile time.
   */
  @SuppressWarnings("unused")
  private static class InfoWhenKnownGecko extends InfoWhenUnknown {
    @Override
    public boolean isGecko() {
      return true;
    }

    @Override
    public boolean isSupported() {
      return true;
    }

    @Override
    public boolean isWebKit() {
      return false;
    }
  }

  /**
   * A {@link Browser.Info} implementation for when the browser is known to be
   * Unsupported at compile time.
   */
  @SuppressWarnings("unused")
  private static class InfoWhenKnownUnsupported extends InfoWhenUnknown {
    @Override
    public boolean isGecko() {
      return false;
    }

    @Override
    public boolean isSupported() {
      return false;
    }

    @Override
    public boolean isWebKit() {
      return false;
    }
  }

  /**
   * A {@link Browser.Info} implementation for when the browser is known to be
   * WebKit at compile time.
   */
  @Deprecated
  @SuppressWarnings("unused")
  private static class InfoWhenKnownWebKit extends InfoWhenUnknown {
    @Override
    public boolean isGecko() {
      return false;
    }

    @Override
    public boolean isSupported() {
      return true;
    }

    @Override
    public boolean isWebKit() {
      return true;
    }
  }

  /**
   * A {@link Browser.Info} implementation for when the browser is not known
   * until runtime.
   *
   * <p>
   * Careful Captain! All those static fields are intentional. In order to
   * ensure good dead stripping of the entire InfoWhen class hierarchy, the
   * instance returned by {@link JsBrowser#getInfo()} must not be aliased, so it
   * instead returns a fly-weight instance referencing static fields.
   * </p>
   */
  private static class InfoWhenUnknown implements Browser.Info {
    private native static double getGeckoVersion(String userAgent) /*-{
      var r = / rv\:(\d+\.\d+)/.exec(userAgent);
      return r ? parseFloat(r[1]) : 0.0;
    }-*/;

    private native static String getProduct(Navigator nav) /*-{
      return nav.product;
    }-*/;

    private native static double getWebKitVersion(String userAgent) /*-{
      var r = /WebKit\/(\d+\.\d+)/.exec(userAgent);
      return r ? parseFloat(r[1]) : 0.0;
    }-*/;

    private static boolean browserDetected;

    private static boolean platformDetected;

    private static boolean isWebKit;

    private static boolean isGecko;

    private static boolean isMac;

    private static boolean isWindows;

    private static boolean isLinux;

    private void ensurePlatformDetected() {
      if (!platformDetected) {
        platformDetected = true;
        final String userAgent = getWindow().getNavigator().getUserAgent();
        isWindows = userAgent.indexOf("Win") >= 0;
        if (isWindows) {
          return;
        }

        isMac = userAgent.indexOf("Mac") >= 0;
        if (isMac) {
          return;
        }

        isLinux = userAgent.indexOf("Linux") >= 0;
      }
    }

    private void ensureBrowserDetected() {
      if (!browserDetected) {
        browserDetected = true;
        final Navigator nav = getWindow().getNavigator();
        final String ua = nav.getUserAgent();
        boolean isWebKitBased = ua.indexOf("WebKit") >= 0;
        if (isWebKitBased) {
          isWebKit = getWebKitVersion(ua) >= SUPPORTED_WEBKIT_VERSION;
          return;
        }

        assert !isWebKitBased;
        isGecko = getProduct(nav).equals("Gecko") && getGeckoVersion(ua) >= SUPPORTED_GECKO_VERSION;
      }
    }

    @Override
    public boolean isGecko() {
      ensureBrowserDetected();
      return isGecko;
    }

    @Override
    public boolean isSupported() {
      ensureBrowserDetected();
      return isGecko || isWebKit;
    }

    @Override
    public boolean isWebKit() {
      ensureBrowserDetected();
      return isWebKit;
    }

    @Override
    public boolean isLinux() {
      ensurePlatformDetected();
      return isLinux;
    }

    @Override
    public boolean isMac() {
      ensurePlatformDetected();
      return isMac;
    }

    public boolean isWindows() {
      ensurePlatformDetected();
      return isWindows;
    }
  }

  /**
   * The minimum version of WebKit that is supported.
   *
   * This equates to >= Safari 5.0.2
   */
  private static final double SUPPORTED_WEBKIT_VERSION = 533.18;

  /**
   * The minimum version of Gecko that is supported.
   *
   * This equates to >= Firefox 4.0
   */
  private static final double SUPPORTED_GECKO_VERSION = 2.0;

  /**
   * Gets the document within which this script is running.
   */
  public static native JsDocument getDocument() /*-{
    return $doc;
  }-*/;

  public static Browser.Info getInfo() {
    return GWT.create(InfoWhenUnknown.class);
  }

  /**
   * Gets the window within which this script is running.
   */
  public static native JsWindow getWindow() /*-{
    return $wnd;
  }-*/;

  // Non-instantiable.
  private JsBrowser() {
  }
}
