<!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,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;
    }

    //-------------------------------------------------------------------------
    // Acceleration
    //-------------------------------------------------------------------------
    var watchAccelId = null;
    
    /**
     * Start watching acceleration
     */
    var watchAccel = function() {
        console.log("watchAccel()");

        // Success callback
        var success = function(a){
            document.getElementById('x').innerHTML = roundNumber(a.x);
            document.getElementById('y').innerHTML = roundNumber(a.y);
            document.getElementById('z').innerHTML = roundNumber(a.z);
            console.log("watchAccel success callback");
        };

        // Fail callback
        var fail = function(e){
            console.log("watchAccel fail callback with error code "+e);
            stopAccel();
            setAccelStatus(Accelerometer.ERROR_MSG[e]);
        };

        // Update acceleration every 1 sec
        var opt = {};
        opt.frequency = 1000;
        watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt);

        setAccelStatus("Running");
    };

    /**
     * Stop watching the acceleration
     */
    var stopAccel = function() {
    	console.log("stopAccel()");
        setAccelStatus("Stopped");
        if (watchAccelId) {
            navigator.accelerometer.clearWatch(watchAccelId);
            watchAccelId = null;
        }
    };

    /**
     * Get current acceleration
     */
    var getAccel = function() {
        console.log("getAccel()");

        // Stop accel if running
        stopAccel();

        // Success callback
        var success = function(a){
            document.getElementById('x').innerHTML = roundNumber(a.x);
            document.getElementById('y').innerHTML = roundNumber(a.y);
            document.getElementById('z').innerHTML = roundNumber(a.z);
        };

        // Fail callback
        var fail = function(e){
            console.log("getAccel fail callback with error code "+e);
            setAccelStatus(Accelerometer.ERROR_MSG[e]);
        };

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

    /**
     * Set accelerometer status
     */
    var setAccelStatus = function(status) {
        document.getElementById('accel_status').innerHTML = status;
    };
    
    /**
     * Function called when page has finished loading.
     */
    function init() {
        console.log("accelerometer.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>Acceleration</h1>
    <div id="info">
        <div id="accel_status">Stopped</div>
        <div ><table width="100%">
            <tr><td width="20%">X:</td><td id="x"> </td></tr>
            <tr><td width="20%">Y:</td><td id="y"> </td></tr>
            <tr><td width="20%">Z:</td><td id="z"> </td></tr>
        </table></div>
    </div>

    <h2>Action</h2>
    <div class="btn large" onclick="getAccel();">Get Acceleration</div>
    <div class="btn large" onclick="watchAccel();">Start Watch</div>
    <div class="btn large" onclick="stopAccel();">Clear Watch</div>
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
  </body>
</html>      
