/*
 * Copyright 2011 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.geolocation.client;

import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.PartialSupport;

/**
 * Implements the HTML5 Geolocation interface.
 * 
 * <p>
 * You can obtain a user's position by first calling
 * <code>Geolocation.getIfSupported()</code>
 * </p>
 * 
 * <p>
 * Once you have a <code>Geolocation</code>, you can request the user's current
 * position by calling {@link #getCurrentPosition(Callback)} or
 * {@link #watchPosition(Callback)}.
 * </p>
 * 
 * <p>
 * The first time an application requests the user's position, the browser will
 * prompt the user for permission. If the user grants permission, the browser
 * will locate the user and report it back to your application. If the user
 * declines permission, the callback's {@link Callback#onFailure(Object)} method
 * will be called with a {@link PositionError} with its code set to
 * {@link PositionError#PERMISSION_DENIED}.
 * </p>
 * 
 * <p>
 * <span style="color:red;">Experimental API: This API is still under
 * development and is subject to change.</span>
 * 
 * <p>
 * This may not be supported on all browsers.
 * </p>
 * 
 * @see <a href="http://www.w3.org/TR/geolocation-API/">W3C Geolocation API</a>
 * @see <a href="http://diveintohtml5.info/geolocation.html">Dive Into HTML5 -
 *      Geolocation</a>
 */
@PartialSupport
public class Geolocation {

  private static GeolocationSupportDetector detector;
  private static Geolocation impl;

  /**
   * Detector for browser support for Geolocation.
   */
  private static class GeolocationSupportDetector {

    private static native boolean detectSupport() /*-{
      return !!$wnd.navigator.geolocation;
    }-*/;

    private boolean supported = detectSupport();

    public boolean isSupported() {
      return supported;
    }
  }

  /**
   * Detector for browsers that do not support Geolocation.
   */
  @SuppressWarnings("unused")
  private static class GeolocationSupportDetectorNo extends GeolocationSupportDetector {
    @Override
    public boolean isSupported() {
      return false;
    }
  }

  /**
   * Additional options for receiving the user's location.
   */
  public static class PositionOptions {
    private boolean enableHighAccuracy = false;
    private int timeout = -1;
    private int maximumAge = 0;

    /**
     * Sets whether or not the application will request a more accurate position
     * from the browser.
     *
     * <p>
     * If the browser supports this option, the user will be prompted to grant
     * permission to this application, even if permission to get the user's
     * (less accurate) position has already been granted.</p>
     *
     * <p>
     * Requesting high accuracy may be slower, or not supported at all,
     * depending on the browser.
     * </p>
     *
     * <p>
     * By default this is <code>false</code>
     * </p>
     */
    public PositionOptions setHighAccuracyEnabled(boolean enabled) {
      this.enableHighAccuracy = enabled;
      return this;
    }

    /**
     * Allows the browser to return a position immediately with a cached
     * position. The maximum age is then the oldest acceptable cached
     * position. If no acceptable cached position is found, the browser will
     * locate the user and cache and return the position.
     *
     * <p>
     * By default this is 0, which means that the position cache will not be
     * used.
     * </p>
     */
    public PositionOptions setMaximumAge(int maximumAge) {
      this.maximumAge = maximumAge;
      return this;
    }

    /**
     * Sets the amount of time (in milliseconds) that the application is willing
     * to wait before getting the user's position. If a request for position
     * takes more than this amount of time, an error will result.
     *
     * <p>
     * By default this is -1, which means there is no application-specified
     * timeout.
     * </p>
     */
    public PositionOptions setTimeout(int timeout) {
      this.timeout = timeout;
      return this;
    }
  }

  /**
   * Returns a {@link Geolocation} if the browser supports this feature, and
   * <code>null</code> otherwise.
   */
  public static Geolocation getIfSupported() {
    if (!isSupported()) {
      return null;
    } else {
      if (impl == null) {
        impl = new Geolocation();
      }
      return impl;
    }
  }

  /**
   * Returns <code>true</code> if the browser supports geolocation.
   */
  public static boolean isSupported() {
    if (detector == null) {
      detector = GWT.create(GeolocationSupportDetector.class);
    }
    return detector.isSupported();
  }

  private static void handleFailure(Callback<Position, PositionError> callback, int code,
      String msg) {
    callback.onFailure(new PositionError(code, msg));
  }

  private static void handleSuccess(Callback<Position, PositionError> callback, PositionImpl pos) {
    callback.onSuccess(pos);
  }

  private static native JavaScriptObject toJso(PositionOptions options) /*-{
    var opt = {};
    if (options) {
      opt.enableHighAccuracy = options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::enableHighAccuracy;
      opt.maximumAge = options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::maximumAge;

      if (options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::timeout > 0) {
        opt.timeout = options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::timeout;
      }
    }
    return opt;
  }-*/;

  /**
   * Should be instantiated by {@link #getIfSupported()}.
   */
  protected Geolocation() {
  }

  /**
   * Stops watching the user's position.
   *
   * @param watchId the ID of a position watch as returned by a previous call to
   *        {@link #watchPosition(Callback)}.
   */
  public native void clearWatch(int watchId) /*-{
    $wnd.navigator.geolocation.clearWatch(watchId);
  }-*/;

  /**
   * Calls the callback with the user's current position.
   */
  public void getCurrentPosition(Callback<Position, PositionError> callback) {
    getCurrentPosition(callback, null);
  }

  /**
   * Calls the callback with the user's current position, with additional
   * options.
   */
  public native void getCurrentPosition(Callback<Position, PositionError> callback,
      PositionOptions options) /*-{
    var opt = @com.google.gwt.geolocation.client.Geolocation::toJso(*)(options);

    var success = $entry(function(pos) {
      @com.google.gwt.geolocation.client.Geolocation::handleSuccess(*)(callback, pos);
    });

    var failure = $entry(function(err) {
      @com.google.gwt.geolocation.client.Geolocation::handleFailure(*)
      (callback, err.code, err.message);
    });

    if (@com.google.gwt.geolocation.client.Geolocation::isSupported()) {
      $wnd.navigator.geolocation.getCurrentPosition(success, failure, opt);
    }
  }-*/;

  /**
   * Repeatedly calls the given callback with the user's position, as it
   * changes.
   *
   * <p>
   * The frequency of these updates is entirely up to the browser. There is no
   * guarantee that updates will be received at any set interval, but are
   * instead designed to be sent when the user's position changes. This method
   * should be used instead of polling the user's current position.
   * </p>
   *
   * @return the ID of this watch, which can be passed to
   *         {@link #clearWatch(int)} to stop watching the user's position.
   */
  public int watchPosition(Callback<Position, PositionError> callback) {
    return watchPosition(callback, null);
  }

  /**
   * Repeatedly calls the given callback with the user's position, as it
   * changes, with additional options.
   * 
   * <p>
   * The frequency of these updates is entirely up to the browser. There is no
   * guarantee that updates will be received at any set interval, but are
   * instead designed to be sent when the user's position changes. This method
   * should be used instead of polling the user's current position.
   * </p>
   * 
   * <p>
   * If the browser does not support geolocation, this method will do nothing,
   * and will return -1.
   * </p>
   * 
   * @return the ID of this watch, which can be passed to
   *         {@link #clearWatch(int)} to stop watching the user's position.
   */
  public native int watchPosition(Callback<Position, PositionError> callback,
      PositionOptions options) /*-{
    var opt = @com.google.gwt.geolocation.client.Geolocation::toJso(*)(options);

    var success = $entry(function(pos) {
      @com.google.gwt.geolocation.client.Geolocation::handleSuccess(*)(callback, pos);
    });

    var failure = $entry(function(err) {
      @com.google.gwt.geolocation.client.Geolocation::handleFailure(*)
      (callback, err.code, err.message);
    });

    var id = -1;
    if (@com.google.gwt.geolocation.client.Geolocation::isSupported()) {
      id = $wnd.navigator.geolocation.watchPosition(success, failure, opt);
    }
    return id;
  }-*/;
}
