<!DOCTYPE html>
<!--

 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you 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.

-->


<html>
  <head>
    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
    <title>Cordova Mobile Spec</title>
    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
    <script type="text/javascript" charset="utf-8" src="../cordova.js"></script>      

      
<script type="text/javascript" charset="utf-8">

    var deviceReady = false;

    //-------------------------------------------------------------------------
    // Location
    //-------------------------------------------------------------------------
    var watchLocationId = null;

    /**
     * Start watching location
     */
    var watchLocation = function(geo) {
        console.log("watchLocation()");

        // Success callback
        var success = function(p){
              console.log('watch location success');
              setLocationDetails(p);
        };

        // Fail callback
        var fail = function(e){
            console.log("watchLocation fail callback with error code "+e);
            stopLocation(geo);
        };

        // Get location
        watchLocationId = geo.watchPosition(success, fail, {enableHighAccuracy: true});
        setLocationStatus("Running");
    };

    /**
     * Stop watching the location
     */
    var stopLocation = function(geo) {
        setLocationStatus("Stopped");
        if (watchLocationId) {
            geo.clearWatch(watchLocationId);
            watchLocationId = null;
        }
    };

    /**
     * Get current location
     */
    var getLocation = function(geo, opts) {
        console.log("getLocation()");

        // Stop location if running
        stopLocation(geo);

        // Success callback
        var success = function(p){
            console.log('get location success');
            setLocationDetails(p);
            setLocationStatus("Done");
        };

        // Fail callback
        var fail = function(e){
            console.log("getLocation fail callback with error code "+e.code);
            setLocationStatus("Error: "+e.code);
        };

        // Get location
        geo.getCurrentPosition(success, fail, opts || {enableHighAccuracy: true}); //, {timeout: 10000});
        setLocationStatus("Retrieving location...");

    };

    /**
     * Set location status
     */
    var setLocationStatus = function(status) {
        document.getElementById('location_status').innerHTML = status;
    };
var setLocationDetails = function(p) {
var date = (new Date(p.timestamp));
            document.getElementById('latitude').innerHTML = p.coords.latitude;
            document.getElementById('longitude').innerHTML = p.coords.longitude;
            document.getElementById('altitude').innerHTML = p.coords.altitude;
            document.getElementById('accuracy').innerHTML = p.coords.accuracy;
            document.getElementById('heading').innerHTML = p.coords.heading;
            document.getElementById('speed').innerHTML = p.coords.speed;
            document.getElementById('altitude_accuracy').innerHTML = p.coords.altitudeAccuracy;
            document.getElementById('timestamp').innerHTML =  date.toDateString() + " " + date.toTimeString();
    }
    
    /**
     * Function called when page has finished loading.
     */
    function init() {
        document.addEventListener("deviceready", function() {
                deviceReady = true;
                console.log("Device="+device.platform+" "+device.version);
            }, false);
        window.setTimeout(function() {
        	if (!deviceReady) {
        		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
        	}
        },1000);
    }

</script>

  </head>
  <body onload="init();" id="stage" class="theme">
  
    <h1>Location</h1>
    <div id="info">
        <b>Status:</b> <span id="location_status">Stopped</span>
        <table width="100%">
            <tr><td><b>Latitude:</b></td><td id="latitude">&nbsp;</td></tr>
            <tr><td><b>Longitude:</b></td><td id="longitude">&nbsp;</td></tr>
            <tr><td><b>Altitude:</b></td><td id="altitude">&nbsp;</td></tr>
            <tr><td><b>Accuracy:</b></td><td id="accuracy">&nbsp;</td></tr>
            <tr><td><b>Heading:</b></td><td id="heading">&nbsp;</td></tr>
            <tr><td><b>Speed:</b></td><td id="speed">&nbsp;</td></tr>
            <tr><td><b>Altitude Accuracy:</b></td><td id="altitude_accuracy">&nbsp;</td></tr>
            <tr><td><b>Time:</b></td><td id="timestamp">&nbsp;</td></tr>
        </table>
    </div>
    <h2>Action</h2>
    <h3>Use Built-in WebView navigator.geolocation</h3>
    <a href="javascript:" class="btn large" onclick="getLocation(navigator.geolocation);">Get Location</a>
    <a href="javascript:" class="btn large" onclick="watchLocation(navigator.geolocation);">Start Watching Location</a>
    <a href="javascript:" class="btn large" onclick="stopLocation(navigator.geolocation);">Stop Watching Location</a>
    <a href="javascript:" class="btn large" onclick="getLocation(navigator.geolocation, {maximumAge:30000});">Get Location Up to 30 Seconds Old</a>
    <h3>USe Cordova Geolocation Plugin</h3>
    <a href="javascript:" class="btn large" onclick="getLocation(cordova.require('cordova/plugin/geolocation'));">Get Location</a>
    <a href="javascript:" class="btn large" onclick="watchLocation(cordova.require('cordova/plugin/geolocation'));">Start Watching Location</a>
    <a href="javascript:" class="btn large" onclick="stopLocation(cordova.require('cordova/plugin/geolocation'));">Stop Watching Location</a>
    <a href="javascript:" class="btn large" onclick="getLocation(cordova.require('cordova/plugin/geolocation'), {maximumAge:30000});">Get Location Up to 30 Seconds Old</a>
    <h2>&nbsp;</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a>    
  </body>
</html>      
