<!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-incl.js"></script>      

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

    var deviceReady = false;

    function roundNumber(num) {
        var dec = 3;
        var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
        return result;
    }

    //-------------------------------------------------------------------------
    // Compass
    //-------------------------------------------------------------------------
    var watchCompassId = null;

    /**
     * Start watching compass
     */
    var watchCompass = function() {
        console.log("watchCompass()");

        // Success callback
        var success = function(a){
            document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
        };

        // Fail callback
        var fail = function(e){
            console.log("watchCompass fail callback with error code "+e);
            stopCompass();
            setCompassStatus(e);
        };

        // Update heading every 1 sec
        var opt = {};
        opt.frequency = 1000;
        watchCompassId = navigator.compass.watchHeading(success, fail, opt);

        setCompassStatus("Running");
    };

    /**
     * Stop watching the acceleration
     */
    var stopCompass = function() {
        setCompassStatus("Stopped");
        if (watchCompassId) {
            navigator.compass.clearWatch(watchCompassId);
            watchCompassId = null;
        }
    };

    /**
     * Get current compass
     */
    var getCompass = function() {
        console.log("getCompass()");

        // Stop compass if running
        stopCompass();

        // Success callback
        var success = function(a){
            document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
        };

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

        // Make call
        var opt = {};
        navigator.compass.getCurrentHeading(success, fail, opt);
    };

    /**
     * Set compass status
     */
    var setCompassStatus = function(status) {
        document.getElementById('compass_status').innerHTML = status;
    };
    
    /**
     * 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>Compass</h1>
    <div id="info">
        <b>Status:</b> <span id="compass_status">Stopped</span>
        <table width="100%"><tr>
            <td width="33%">Heading: <span id="compassHeading"> </span></td>
        </tr></table>
    </div>
    <h2>Action</h2>
    <div class="btn large" onclick="getCompass();">Get Compass</div>
    <div class="btn large" onclick="watchCompass();">Start Watching Compass</div>
    <div class="btn large" onclick="stopCompass();">Stop Watching Compass</div>
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
  </body>
</html>      
