<!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;
    var platformId = cordova.require('cordova/platform').id;
    var pageStartTime = +new Date();

    //-------------------------------------------------------------------------
    // Camera
    //-------------------------------------------------------------------------

    function log(value) {
        console.log(value);
        document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
    }

    function captureAudioWin(mediaFiles){
        var path = mediaFiles[0].fullPath;
        log('Audio captured: ' + path);
        var m = new Media(path);
        m.play(); 
    }
    
    function captureAudioFail(e){
        log('Error getting audio: ' + e.code);
    }
    
    function getAudio(){
        clearStatus();
        var options = { limit: 1, duration: 10};
        navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options);
    }
    
    function captureImageWin(mediaFiles){
        var path = mediaFiles[0].fullPath;
        log('Image captured: ' + path);    
        document.getElementById('camera_image').src = path;    
    }
    
    function captureImageFail(e){
        log('Error getting image: ' + e.code);
    }
    
    function getImage(){
        clearStatus();
        var options = { limit: 1 };
        navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);    
    }    
    
    function captureVideoWin(mediaFiles){
        var path = mediaFiles[0].fullPath;
        log('Video captured: ' + path);
        
        // need to inject the video element into the html
        // doesn't seem to work if you have a pre-existing video element and
        // add in a source tag
        var vid = document.createElement('video');
        vid.id="theVideo";
        vid.width = "320";
        vid.height= "240";
        var source_vid = document.createElement('source');
        source_vid.id = "theSource";
        source_vid.src = path;
        vid.appendChild(source_vid);
        document.getElementById('video_container').appendChild(vid);    
    }
    
    function captureVideoFail(e){
        log('Error getting video: ' + e.code);
    }
    
    function getVideo(){
        clearStatus();
        var options = { limit: 1, duration: 10 };
        navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);      
    }
    
    function clearStatus() {
        document.getElementById('camera_status').innerHTML = '';
        document.getElementById('camera_image').src = 'about:blank';
    }

    /**
     * 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>Capture</h1>
    <div id="info" style="white-space: pre-wrap">
        <b>Status:</b> <div id="camera_status"></div>
        img: <img width="100" id="camera_image">
        video: <div id="video_container"></div>
    </div>
    
    <h2>Cordova Capture API</h2>
    <div id="image-options"></div>

    <h2>Actions</h2>
    <div class="btn large" onclick="getAudio();">Capture 10 secs of audio and play</div>
    <div class="btn large" onclick="getImage();">Capture 1 image</div>
    <div class="btn large" onclick="getVideo();">Capture 10 secs of video</div>
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
  </body>
</html>
