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

/* jshint jasmine: true */
/* global CaptureAudioOptions, CaptureImageOptions, CaptureVideoOptions, CaptureError */
/* global Media, MediaFile, MediaFileData, resolveLocalFileSystemURL */

exports.defineAutoTests = function () {
    describe('Capture (navigator.device.capture)', function () {
        it("capture.spec.1 should exist", function () {
            expect(navigator.device).toBeDefined();
            expect(navigator.device.capture).toBeDefined();
        });

        it("capture.spec.2 should have the correct properties ", function () {
            expect(navigator.device.capture.supportedAudioModes).toBeDefined();
            expect(navigator.device.capture.supportedImageModes).toBeDefined();
            expect(navigator.device.capture.supportedVideoModes).toBeDefined();
        });

        it("capture.spec.3 should contain a captureAudio function", function () {
            expect(navigator.device.capture.captureAudio).toBeDefined();
            expect(typeof navigator.device.capture.captureAudio == 'function').toBe(true);
        });

        it("capture.spec.4 should contain a captureImage function", function () {
            expect(navigator.device.capture.captureImage).toBeDefined();
            expect(typeof navigator.device.capture.captureImage == 'function').toBe(true);
        });

        it("capture.spec.5 should contain a captureVideo function", function () {
            expect(navigator.device.capture.captureVideo).toBeDefined();
            expect(typeof navigator.device.capture.captureVideo == 'function').toBe(true);
        });

        describe('CaptureAudioOptions', function () {
            it("capture.spec.6 CaptureAudioOptions constructor should exist", function () {
                var options = new CaptureAudioOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
                expect(options.duration).toBeDefined();
            });
        });

        describe('CaptureImageOptions', function () {
            it("capture.spec.7 CaptureImageOptions constructor should exist", function () {
                var options = new CaptureImageOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
            });
        });

        describe('CaptureVideoOptions', function () {
            it("capture.spec.8 CaptureVideoOptions constructor should exist", function () {
                var options = new CaptureVideoOptions();
                expect(options).toBeDefined();
                expect(options.limit).toBeDefined();
                expect(options.duration).toBeDefined();
            });
        });

        describe('CaptureError interface', function () {
            it("capture.spec.9 CaptureError constants should be defined", function () {
                expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0);
                expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1);
                expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2);
                expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3);
            });

            it("capture.spec.10 CaptureError properties should exist", function () {
                var error = new CaptureError();
                expect(error).toBeDefined();
                expect(error.code).toBeDefined();
            });
        });

        describe('MediaFileData', function () {
            it("capture.spec.11 MediaFileData constructor should exist", function () {
                var fileData = new MediaFileData();
                expect(fileData).toBeDefined();
                expect(fileData.bitrate).toBeDefined();
                expect(fileData.codecs).toBeDefined();
                expect(fileData.duration).toBeDefined();
                expect(fileData.height).toBeDefined();
                expect(fileData.width).toBeDefined();
            });
        });

        describe('MediaFile', function () {
            it("capture.spec.12 MediaFile constructor should exist", function () {
                var fileData = new MediaFile();
                expect(fileData).toBeDefined();
                expect(fileData.name).toBeDefined();
                expect(fileData.type).toBeDefined();
                expect(fileData.lastModifiedDate).toBeDefined();
                expect(fileData.size).toBeDefined();
            });
        });
    });
};

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

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

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

    function captureAudioWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        log('Audio captured: ' + path);
        var m = new Media(path);
        m.play();
        getFileMetadata(mediaFiles[0]);
    }

    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;
        // Necessary since windows doesn't allow file URLs for <img> elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[0].localURL;
        }
        log('Image captured: ' + path);
        document.getElementById('camera_image').src = path;
    }

    function captureImagesWin(mediaFiles) {
        var path = mediaFiles[0].fullPath;
        // Necessary since windows doesn't allow file URLs for <img> elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[0].localURL;
        }
        var path2 = mediaFiles[1].fullPath;
        // Necessary since windows doesn't allow file URLs for <img> elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[1].localURL;
        }
        var path3 = mediaFiles[2].fullPath;
        // Necessary since windows doesn't allow file URLs for <img> elements
        if (cordova.platformId == 'windows' || cordova.platformId == 'windows8' || cordova.platformId === 'browser') {
            path = mediaFiles[2].localURL;
        }
        log('Image captured: ' + path);
        log('Image captured: ' + path2);
        log('Image captured: ' + path3);
        document.getElementById('camera_image').src = path;
        document.getElementById('camera_image2').src = path2;
        document.getElementById('camera_image3').src = path3;
    }

    function captureImageFail(e) {
        log('Error getting image: ' + e.code);
    }

    function getImage() {
        clearStatus();
        var options = { limit: 1 };
        navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);
    }

    function getImages() {
        clearStatus();
        var options = { limit: 3 };
        navigator.device.capture.captureImage(captureImagesWin, 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";
        vid.controls = "true";
        var source_vid = document.createElement('source');
        source_vid.id = "theSource";
        source_vid.src = path;
        vid.appendChild(source_vid);
        document.getElementById('video_container').appendChild(vid);
        getFileMetadata(mediaFiles[0]);
    }

    function getFileMetadata(mediaFile) {
        mediaFile.getFormatData(getMetadataWin, getMetadataFail);
    }

    function getMetadataWin(metadata) {
        var strMetadata =
        "duration = " + metadata.duration + '\n' +
        "width = " + metadata.width + '\n' +
        "height = " + metadata.height;
        log(strMetadata);
    }

    function getMetadataFail(e) {
        log("Error getting metadata: " + e.code);
    }

    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 resolveMediaFileURL(mediaFile, callback) {
        resolveLocalFileSystemURL(mediaFile.localURL, function (entry) {
            log("Resolved by URL: " + mediaFile.localURL);
            if (callback) callback();
        }, function (err) {
            log("Failed to resolve by URL: " + mediaFile.localURL);
            log("Error: " + JSON.stringify(err));
            if (callback) callback();
        });
    }

    function resolveMediaFile(mediaFile, callback) {
        resolveLocalFileSystemURL(mediaFile.fullPath, function (entry) {
            log("Resolved by path: " + mediaFile.fullPath);
            if (callback) callback();
        }, function (err) {
            log("Failed to resolve by path: " + mediaFile.fullPath);
            log("Error: " + JSON.stringify(err));
            if (callback) callback();
        });
    }

    function resolveVideo() {
        clearStatus();
        var options = { limit: 1, duration: 5 };
        navigator.device.capture.captureVideo(function (mediaFiles) {
            captureVideoWin(mediaFiles);
            resolveMediaFile(mediaFiles[0], function () {
                resolveMediaFileURL(mediaFiles[0]);
            });
        }, captureVideoFail, options);
    }

    function clearStatus() {
        document.getElementById('camera_status').innerHTML = '';
        document.getElementById('camera_image').src = 'about:blank';
        document.getElementById('camera_image2').src = 'about:blank';
        document.getElementById('camera_image3').src = 'about:blank';
    }

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

    contentEl.innerHTML = '<div id="info" style="white-space: pre-wrap">' +
        '<b>Status:</b> <div id="camera_status"></div>' +
        'img1: <img width="100" id="camera_image">' +
        'img2: <img width="100" id="camera_image2">' +
        'img3: <img width="100" id="camera_image3">' +
        'video: <div id="video_container"></div>' +
        '</div><div id="audio"></div>' +
        'Expected result: Audio recorder will come up. Press record button to record for 10 seconds. Press Done. Status box will update with audio file and automatically play recording.' +
        '<p/> <div id="image"></div>' +
        'Expected result: Status box will update with image just taken.' +
        '<p/> <div id="images"></div>' +
        'Expected result: Status box will update with images just taken.' +
        '<p/> <div id="video"></div>' +
        'Expected result: Record 10 second video. Status box will update with video file that you can play.' +
        '<p/> <div id="video_and_resolve"></div>' +
        'Expected result: Record 5 second video. Status box will show that URL was resolved and video will get added at the bottom of the status box for playback.';

    createActionButton('Capture 10 sec of audio and play', function () {
        getAudio();
    }, 'audio');

    createActionButton('Capture 1 image', function () {
        getImage();
    }, 'image');

    createActionButton('Capture 3 images', function () {
        getImages();
    }, 'images');

    createActionButton('Capture 10 sec of video', function () {
        getVideo();
    }, 'video');

    createActionButton('Capture 5 sec of video and resolve', function () {
        resolveVideo();
    }, 'video_and_resolve');
};
