<!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.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>      
