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


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

    var deviceReady = false;
    var platformId = cordova.require('cordova/platform').id;
    var CameraPopoverOptions = cordova.require('cordova/plugin/CameraPopoverOptions');
    var pictureUrl = null;
    var fileObj = null;
    var fileEntry = null;
    var pageStartTime = +new Date();
    
    //default camera options
    var camQualityDefault = ['quality value', 50];
    var camDestinationTypeDefault = ['FILE_URI', 1];
    var camPictureSourceTypeDefault = ['CAMERA', 1];
    var camAllowEditDefault = ['allowEdit', false];
    var camEncodingTypeDefault = ['JPEG', 0];
    var camMediaTypeDefault = ['mediaType', 0];
    var camCorrectOrientationDefault = ['correctOrientation', false];
    var camSaveToPhotoAlbumDefault = ['saveToPhotoAlbum', true];
    

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

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

    function clearStatus() {
        document.getElementById('camera_status').innerHTML = '';
        document.getElementById('camera_image').src = 'about:blank';
        var canvas = document.getElementById('canvas');
        canvas.width = canvas.height = 1;
        pictureUrl = null;
        fileObj = null;
        fileEntry = null;
    }

    function setPicture(url, callback) {
        pictureUrl = url;
        log('URL: ' + url.slice(0, 100));
        var img = document.getElementById('camera_image');
        var startTime = new Date();
        img.src = url;
        img.onloadend = function() {
            log('Image tag load time: ' + (new Date() - startTime));
            callback && callback();
        };
    }

    function onGetPictureError(e) {
        log('Error getting picture: ' + e.code);
    }

    function getPictureWin(data) {
        setPicture(data);
        // TODO: Fix resolveLocalFileSystemURI to work with native-uri.
        if (pictureUrl.indexOf('file:') == 0) {
            resolveLocalFileSystemURI(data, function(e) {
                fileEntry = e;
                logCallback('resolveLocalFileSystemURI()', true)(e);
            }, logCallback('resolveLocalFileSystemURI()', false));
        } else {
            var path = pictureUrl.replace(/^file:\/\/(localhost)?/, '').replace(/%20/g, ' ');
            fileEntry = new FileEntry('image_name.png', path);
        }
    }

    function getPicture() {
        clearStatus();
        var options = extractOptions();
        log('Getting picture with options: ' + JSON.stringify(options));
        var popoverHandle = navigator.camera.getPicture(getPictureWin, onGetPictureError, options);

        // Reposition the popover if the orientation changes.
        window.onorientationchange = function() {
            var newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0);
            popoverHandle.setPosition(newPopoverOptions);
        }
    }

    function uploadImage() {
        var ft = new FileTransfer(),
            uploadcomplete=0,
            progress = 0,
            options = new FileUploadOptions();
        options.fileKey="photo";
        options.fileName='test.jpg';
        options.mimeType="image/jpeg";
        ft.onprogress = function(progressEvent) {
            log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
        };
        var server = "http://cordova-filetransfer.jitsu.com";

        ft.upload(pictureUrl, server + '/upload', win, fail, options);
        function win(information_back){
            log('upload complete');
        }
        function fail(message) {
            log('upload failed: ' + JSON.stringify(message));
        }
    }

    function logCallback(apiName, success) {
        return function() {
            log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments)));
        };
    }

    /**
     * Select image from library using a NATIVE_URI destination type
     * This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
     */
    function readFile() {
        function onFileReadAsDataURL(evt) {
            var img = document.getElementById('camera_image');
            img.style.visibility = "visible";
            img.style.display = "block";
            img.src = evt.target.result;
            log("FileReader.readAsDataURL success");
        };

        function onFileReceived(file) {
            log('Got file: ' + JSON.stringify(file));
            fileObj = file;

            var reader = new FileReader();
            reader.onload = function() {
                log('FileReader.readAsDataURL() - length = ' + reader.result.length);
            };
            reader.onerror = logCallback('FileReader.readAsDataURL', false);
            reader.readAsDataURL(file);
        };
        // Test out onFileReceived when the file object was set via a native <input> elements.
        if (fileObj) {
            onFileReceived(fileObj);
        } else {
            fileEntry.file(onFileReceived, logCallback('FileEntry.file', false));
        }
    }
    function getFileInfo() {
        // Test FileEntry API here.
        fileEntry.getMetadata(logCallback('FileEntry.getMetadata', true), logCallback('FileEntry.getMetadata', false));
        fileEntry.setMetadata(logCallback('FileEntry.setMetadata', true), logCallback('FileEntry.setMetadata', false), { "com.apple.MobileBackup": 1 });
        fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false));
        fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false));
    };

    /**
     * Copy image from library using a NATIVE_URI destination type
     * This calls FileEntry.copyTo and FileEntry.moveTo.
     */
    function copyImage() {
        var onFileSystemReceived = function(fileSystem) {
            var destDirEntry = fileSystem.root;

            // Test FileEntry API here.
            fileEntry.copyTo(destDirEntry, 'copied_file.png', logCallback('FileEntry.copyTo', true), logCallback('FileEntry.copyTo', false));
            fileEntry.moveTo(destDirEntry, 'moved_file.png', logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
        };

        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, onFileSystemReceived, null);
    };

    /**
     * Write image to library using a NATIVE_URI destination type
     * This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
     */
    function writeImage() {
        var onFileWriterReceived = function(fileWriter) {
            fileWriter.onwrite = logCallback('FileWriter.write', true);
            fileWriter.onerror = logCallback('FileWriter.write', false);
            fileWriter.write("some text!");
        };

        var onFileTruncateWriterReceived = function(fileWriter) {
            fileWriter.onwrite = logCallback('FileWriter.truncate', true);
            fileWriter.onerror = logCallback('FileWriter.truncate', false);
            fileWriter.truncate(10);
        };

        fileEntry.createWriter(onFileWriterReceived, logCallback('FileEntry.createWriter', false));
        fileEntry.createWriter(onFileTruncateWriterReceived, null);
    };

    function displayImageUsingCanvas() {
        var canvas = document.getElementById('canvas');
        var img = document.getElementById('camera_image');
        var w = img.width;
        var h = img.height;
        h = 100 / w * h;
        w = 100;
        canvas.width = w;
        canvas.height= h;
        var context = canvas.getContext('2d');
        context.drawImage(img, 0, 0, w, h);
    };

    /**
     * Remove image from library using a NATIVE_URI destination type
     * This calls FileEntry.remove.
     */
    function removeImage() {
        fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
    };

    function testInputTag(inputEl) {
        clearStatus();
        // iOS 6 likes to dead-lock in the onchange context if you
        // do any alerts or try to remote-debug.
        window.setTimeout(function() {
            testNativeFile2(inputEl);
        }, 0);
    };

    function testNativeFile2(inputEl) {
        if (!inputEl.value) {
            alert('No file selected.');
            return;
        }
        fileObj = inputEl.files[0];
        if (!fileObj) {
            alert('Got value but no file.');
            return;
        }
        var URLApi = window.URL || window.webkitURL;
        if (URLApi) {
            var blobURL = URLApi.createObjectURL(fileObj);
            if (blobURL) {
                setPicture(blobURL, function() {
                    URLApi.revokeObjectURL(blobURL);
                });
            } else {
                log('URL.createObjectURL returned null');
            }
        } else {
            log('URL.createObjectURL() not supported.');
        }
    }

    function extractOptions() {
        var els = document.querySelectorAll('#image-options select');
        var ret = {};
        for (var i = 0, el; el = els[i]; ++i) {
            var value = el.value;
            if (value === '') continue;
            if (el.isBool) {
                ret[el.keyName] = !!value;
            } else {
                ret[el.keyName] = +value;
            }
        }
        return ret;
    }

    function createOptionsEl(name, values, selectionDefault) {
        var container = document.createElement('div');
        container.style.display = 'inline-block';
        container.appendChild(document.createTextNode(name + ': '));
        var select = document.createElement('select');
        select.keyName = name;
        container.appendChild(select);
        
        // if we didn't get a default value, insert the blank <default> entry
        if (selectionDefault == undefined) {
            var opt = document.createElement('option');
            opt.value = '';
            opt.text = '<default>';
            select.appendChild(opt);
        }
        
        select.isBool = typeof values == 'boolean';
        if (select.isBool) {
            values = {'true': 1, 'false': 0};
        }
        
        for (var k in values) {
            var opt = document.createElement('option');
            opt.value = values[k];
            opt.textContent = k;
            if (selectionDefault) {
                if (selectionDefault[0] == k) {
                    opt.selected = true;
                }
            }
            select.appendChild(opt);
        }
        var optionsDiv = document.getElementById('image-options');
        optionsDiv.appendChild(container);
    }

    /**
     * Function called when page has finished loading.
     */
    function init() {
        document.addEventListener("deviceready", function() {
            deviceReady = true;
            console.log("Device="+device.platform+" "+device.version);
            createOptionsEl('sourceType', Camera.PictureSourceType, camPictureSourceTypeDefault);
            createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault);
            createOptionsEl('encodingType', Camera.EncodingType, camEncodingTypeDefault);
            createOptionsEl('mediaType', Camera.MediaType, camMediaTypeDefault);
            createOptionsEl('quality', {'0': 0, '50': 50, '80': 80, '100': 100}, camQualityDefault);
            createOptionsEl('targetWidth', {'50': 50, '200': 200, '800': 800, '2048': 2048});
            createOptionsEl('targetHeight', {'50': 50, '200': 200, '800': 800, '2048': 2048});
            createOptionsEl('allowEdit', true, camAllowEditDefault);
            createOptionsEl('correctOrientation', true, camCorrectOrientationDefault);
            createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault);
            createOptionsEl('cameraDirection', Camera.Direction);
                          
        }, 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>Camera</h1>
    <div id="info" style="white-space: pre-wrap">
        <b>Status:</b> <div id="camera_status"></div>
        img: <img width="100" id="camera_image">
        canvas: <canvas id="canvas" width="1" height="1"></canvas>
    </div>
    <h2>Cordova Camera API</h2>
    <div id="image-options"></div>
    <div class="btn large" onclick="getPicture();">camera.getPicture()</div>
    <h2>Native File Inputs</h2>
    <div>input type=file <input type="file" onchange="testInputTag(this)"></div>
    <div>capture=camera <input type="file" accept="image/*;capture=camera" onchange="testInputTag(this)"></div>
    <div>capture=camcorder <input type="file" accept="video/*;capture=camcorder" onchange="testInputTag(this)"></div>
    <div>capture=microphone <input type="file" accept="audio/*;capture=microphone" onchange="testInputTag(this)"></div>
    <h2>Actions</h2>
    <div class="btn large" onclick="getFileInfo();">Get File Metadata</div>
    <div class="btn large" onclick="readFile();">Read with FileReader</div>
    <div class="btn large" onclick="copyImage();">Copy Image</div>
    <div class="btn large" onclick="writeImage();">Write Image</div>
    <div class="btn large" onclick="uploadImage();">Upload Image</div>
    <div class="btn large" onclick="displayImageUsingCanvas();">Draw Using Canvas</div>
    <div class="btn large" onclick="removeImage();">Remove Image</div>
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
  </body>
</html>
