<!--

 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.

-->

<!DOCTYPE html>
<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>      
