/*
 *
 * 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.
 *
*/

/* globals Camera, resolveLocalFileSystemURL, FileEntry, CameraPopoverOptions, FileTransfer, FileUploadOptions, LocalFileSystem, MSApp */
/* eslint-env jasmine */

exports.defineAutoTests = function () {
    describe('Camera (navigator.camera)', function () {
        it('should exist', function () {
            expect(navigator.camera).toBeDefined();
        });

        it('should contain a getPicture function', function () {
            expect(navigator.camera.getPicture).toBeDefined();
            expect(typeof navigator.camera.getPicture === 'function').toBe(true);
        });
    });

    describe('Camera Constants (window.Camera + navigator.camera)', function () {
        it('camera.spec.1 window.Camera should exist', function () {
            expect(window.Camera).toBeDefined();
        });

        it('camera.spec.2 should contain three DestinationType constants', function () {
            expect(Camera.DestinationType.DATA_URL).toBe(0);
            expect(Camera.DestinationType.FILE_URI).toBe(1);
            expect(Camera.DestinationType.NATIVE_URI).toBe(2);
            expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
            expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
            expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
        });

        it('camera.spec.3 should contain two EncodingType constants', function () {
            expect(Camera.EncodingType.JPEG).toBe(0);
            expect(Camera.EncodingType.PNG).toBe(1);
            expect(navigator.camera.EncodingType.JPEG).toBe(0);
            expect(navigator.camera.EncodingType.PNG).toBe(1);
        });

        it('camera.spec.4 should contain three MediaType constants', function () {
            expect(Camera.MediaType.PICTURE).toBe(0);
            expect(Camera.MediaType.VIDEO).toBe(1);
            expect(Camera.MediaType.ALLMEDIA).toBe(2);
            expect(navigator.camera.MediaType.PICTURE).toBe(0);
            expect(navigator.camera.MediaType.VIDEO).toBe(1);
            expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
        });

        it('camera.spec.5 should contain three PictureSourceType constants', function () {
            expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
            expect(Camera.PictureSourceType.CAMERA).toBe(1);
            expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
            expect(navigator.camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
            expect(navigator.camera.PictureSourceType.CAMERA).toBe(1);
            expect(navigator.camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
        });
    });
};

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

exports.defineManualTests = function (contentEl, createActionButton) {
    var pictureUrl = null;
    var fileObj = null;
    var fileEntry = null;
    var pageStartTime = +new Date();

    // default camera options
    var camQualityDefault = ['50', 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];

    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) {
        try {
            window.atob(url);
            // if we got here it is a base64 string (DATA_URL)
            url = 'data:image/jpeg;base64,' + url;
        } catch (e) {
            // not DATA_URL
        }
        log('URL: "' + url.slice(0, 90) + '"');

        pictureUrl = url;
        var img = document.getElementById('camera_image');
        var startTime = new Date();
        img.src = url;
        img.onload = function () {
            log('Img size: ' + img.naturalWidth + 'x' + img.naturalHeight);
            log('Image tag load time: ' + (new Date() - startTime));
            if (callback) {
                callback();
            }
        };
    }

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

    function getPictureWin (data) {
        setPicture(data);
        // TODO: Fix resolveLocalFileSystemURI to work with native-uri.
        if (pictureUrl.indexOf('file:') === 0 || pictureUrl.indexOf('content:') === 0 || pictureUrl.indexOf('ms-appdata:') === 0 || pictureUrl.indexOf('assets-library:') === 0) {
            resolveLocalFileSystemURL(data, function (e) {
                fileEntry = e;
                logCallback('resolveLocalFileSystemURL()', true)(e.toURL());
                readFile();
            }, logCallback('resolveLocalFileSystemURL()', false));
        } else if (pictureUrl.indexOf('data:image/jpeg;base64') === 0) {
            // do nothing
        } 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();
        var options = new FileUploadOptions();
        options.fileKey = 'photo';
        options.fileName = 'test.jpg';
        options.mimeType = 'image/jpeg';
        ft.onprogress = function (progressEvent) {
            console.log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
        };
        var server = 'http://sheltered-retreat-43956.herokuapp.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;
            /* eslint-disable no-undef */
            var reader = new FileReader();
            /* eslint-enable no-undef */
            reader.onload = function () {
                log('FileReader.readAsDataURL() - length = ' + reader.result.length);
            };
            reader.onerror = logCallback('FileReader.readAsDataURL', false);
            reader.onloadend = onFileReadAsDataURL;
            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;
            var origName = fileEntry.name;

            // 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));

            // cleanup
            // rename moved file back to original name so other tests can reference image
            resolveLocalFileSystemURL(destDirEntry.nativeURL + 'moved_file.png', function (fileEntry) {
                fileEntry.moveTo(destDirEntry, origName, logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
                console.log('Cleanup: successfully renamed file back to original name');
            }, function () {
                console.log('Cleanup: failed to rename file back to original name');
            });

            // remove copied file
            resolveLocalFileSystemURL(destDirEntry.nativeURL + 'copied_file.png', function (fileEntry) {
                fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
                console.log('Cleanup: successfully removed copied file');
            }, function () {
                console.log('Cleanup: failed to remove copied file');
            });
        };

        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) {
        /* eslint-disable no-undef */
        if (!inputEl.value) {
            alert('No file selected.');
            return;
        }
        fileObj = inputEl.files[0];
        if (!fileObj) {
            alert('Got value but no file.');
            return;
        }
        /* eslint-enable no-undef */
        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 = {};
        /* eslint-disable no-cond-assign */
        for (var i = 0, el; el = els[i]; ++i) {
            var value = el.value;
            if (value === '') continue;
            value = +value;

            if (el.isBool) {
                ret[el.getAttribute('name')] = !!value;
            } else {
                ret[el.getAttribute('name')] = value;
            }
        }
        /* eslint-enable no-cond-assign */
        return ret;
    }

    function createOptionsEl (name, values, selectionDefault) {
        var openDiv = '<div style="display: inline-block">' + name + ': ';
        var select = '<select name=' + name + ' id="' + name + '">';

        var defaultOption = '';
        if (selectionDefault === undefined) {
            defaultOption = '<option value="">default</option>';
        }

        var options = '';
        if (typeof values === 'boolean') {
            values = { 'true': 1, 'false': 0 };
        }
        for (var k in values) {
            var isSelected = '';
            if (selectionDefault) {
                if (selectionDefault[0] === k) {
                    isSelected = 'selected';
                }
            }
            options += '<option value="' + values[k] + '" ' + isSelected + '>' + k + '</option>';
        }

        var closeDiv = '</select></div>';

        return openDiv + select + defaultOption + options + closeDiv;
    }

    /******************************************************************************/

    var info_div = '<h1>Camera</h1>' +
            '<div id="info">' +
            '<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>';
    var options_div = '<h2>Cordova Camera API Options</h2>' +
            '<div id="image-options">' +
            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) +
            '</div>';
    var getpicture_div = '<div id="getpicture"></div>';
    var test_procedure = '<h4>Recommended Test Procedure</h4>' +
            'Options not specified should be the default value' +
            '<br>Status box should update with image and info whenever an image is taken or selected from library' +
            '</p><div style="background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto">' +
            '<ol> <li>All default options. Should be able to edit once picture is taken and will be saved to library.</li>' +
            '</p><li>sourceType=PHOTOLIBRARY<br>Should be able to see picture that was just taken in previous test and edit when selected</li>' +
            '</p><li>sourceType=Camera<br>allowEdit=false<br>saveToPhotoAlbum=false<br>Should not be able to edit when taken and will not save to library</li>' +
            '</p><li>encodingType=PNG<br>allowEdit=true<br>saveToPhotoAlbum=true<br>cameraDirection=FRONT<br>Should bring up front camera. Verify in status box info URL that image is encoded as PNG.</li>' +
            '</p><li>sourceType=SAVEDPHOTOALBUM<br>mediaType=VIDEO<br>Should only be able to select a video</li>' +
            '</p><li>sourceType=SAVEDPHOTOALBUM<br>mediaType=PICTURE<br>allowEdit=false<br>Should only be able to select a picture and not edit</li>' +
            '</p><li>sourceType=PHOTOLIBRARY<br>mediaType=ALLMEDIA<br>allowEdit=true<br>Should be able to select pics and videos and edit picture if selected</li>' +
            '</p><li>sourceType=CAMERA<br>targetWidth & targetHeight=50<br>allowEdit=false<br>Do Get File Metadata test below and take note of size<br>Repeat test but with width and height=800. Size should be significantly larger.</li>' +
            '</p><li>quality=0<br>targetWidth & targetHeight=default<br>allowEdit=false<br>Do Get File Metadata test below and take note of size<br>Repeat test but with quality=80. Size should be significantly larger.</li>' +
            '</ol></div>';
    var inputs_div = '<h2>Native File Inputs</h2>' +
            'For the following tests, status box should update with file selected' +
            '</p><div>input type=file <input type="file" class="testInputTag"></div>' +
            '<div>capture=camera <input type="file" accept="image/*;capture=camera" class="testInputTag"></div>' +
            '<div>capture=camcorder <input type="file" accept="video/*;capture=camcorder" class="testInputTag"></div>' +
            '<div>capture=microphone <input type="file" accept="audio/*;capture=microphone" class="testInputTag"></div>';
    var actions_div = '<h2>Actions</h2>' +
            'For the following tests, ensure that an image is set in status box' +
            '</p><div id="metadata"></div>' +
            'Expected result: Get metadata about file selected.<br>Status box will show, along with the metadata, "Call to FileEntry.getMetadata success, Call to FileEntry.setMetadata success, Call to FileEntry.getParent success"' +
            '</p><div id="reader"></div>' +
            'Expected result: Read contents of file.<br>Status box will show "Got file: {some metadata}, FileReader.readAsDataURL() - length = someNumber"' +
            '</p><div id="copy"></div>' +
            'Expected result: Copy image to new location and move file to different location.<br>Status box will show "Call to FileEntry.copyTo success:{some metadata}, Call to FileEntry.moveTo success:{some metadata}"' +
            '</p><div id="write"></div>' +
            'Expected result: Write image to library.<br>Status box will show "Call to FileWriter.write success:{some metadata}, Call to FileWriter.truncate success:{some metadata}"' +
            '</p><div id="upload"></div>' +
            'Expected result: Upload image to server.<br>Status box may print out progress. Once finished will show "upload complete"' +
            '</p><div id="draw_canvas"></div>' +
            'Expected result: Display image using canvas.<br>Image will be displayed in status box under "canvas:"' +
            '</p><div id="remove"></div>' +
            'Expected result: Remove image from library.<br>Status box will show "FileEntry.remove success:["OK"]';

    // We need to wrap this code due to Windows security restrictions
    // see http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences for details
    if (window.MSApp && window.MSApp.execUnsafeLocalFunction) {
        MSApp.execUnsafeLocalFunction(function () {
            contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
        });
    } else {
        contentEl.innerHTML = info_div + options_div + getpicture_div + test_procedure + inputs_div + actions_div;
    }

    var elements = document.getElementsByClassName('testInputTag');
    var listener = function (e) {
        testInputTag(e.target);
    };
    for (var i = 0; i < elements.length; ++i) {
        var item = elements[i];
        item.addEventListener('change', listener, false);
    }

    createActionButton('Get picture', function () {
        getPicture();
    }, 'getpicture');

    createActionButton('Clear Status', function () {
        clearStatus();
    }, 'getpicture');

    createActionButton('Get File Metadata', function () {
        getFileInfo();
    }, 'metadata');

    createActionButton('Read with FileReader', function () {
        readFile();
    }, 'reader');

    createActionButton('Copy Image', function () {
        copyImage();
    }, 'copy');

    createActionButton('Write Image', function () {
        writeImage();
    }, 'write');

    createActionButton('Upload Image', function () {
        uploadImage();
    }, 'upload');

    createActionButton('Draw Using Canvas', function () {
        displayImageUsingCanvas();
    }, 'draw_canvas');

    createActionButton('Remove Image', function () {
        removeImage();
    }, 'remove');
};
