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

/* global cordova, Windows, Media, MediaError, LocalFileSystem, halfSpeedBtn */

// increased timeout for actual playback to give device chance to download and play mp3 file
// some emulators can be REALLY slow at this, so two minutes
var ACTUAL_PLAYBACK_TEST_TIMEOUT = 2 * 60 * 1000;

var WEB_MP3_FILE = 'https://cordova.apache.org/downloads/BlueZedEx.mp3';
var WEB_MP3_STREAM = 'https://cordova.apache.org/downloads/BlueZedEx.mp3';

var isWindows = cordova.platformId === 'windows8' || cordova.platformId === 'windows';
var isBrowser = cordova.platformId === 'browser';
// Detect whether audio hardware is available and enabled. For iOS playing audio is
// not supported on emulators w/out sound device connected to host PC but (which is
// the case for Sauce Labs emulators - see CB-11430)
var isAudioSupported = isWindows
    ? !!Windows.Media.Devices.MediaDevice.getDefaultAudioRenderId(Windows.Media.Devices.AudioDeviceRole.default)
    : cordova.platformId === 'ios'
        ? !window.SAUCELABS_ENV
        : true;

var isKitKat = cordova.platformId === 'android' && /Android\s4\.4/.test(window.navigator.userAgent);

exports.defineAutoTests = function () {
    var failed = function (done, msg, context) {
        if (context && context.done) return;
        context.done = true;
        var info = typeof msg === 'undefined' ? 'Unexpected error callback' : msg;
        expect(true).toFailWithMessage(info);
        done();
    };

    var succeed = function (done, msg, context) {
        if (context && context.done) return;
        context.done = true;
        var info = typeof msg === 'undefined' ? 'Unexpected success callback' : msg;
        expect(true).toFailWithMessage(info);
        done();
    };

    describe('Media', function () {
        beforeEach(function () {
            // Custom Matcher
            jasmine.Expectation.addMatchers({
                toFailWithMessage: function () {
                    return {
                        compare: function (_, message) {
                            var pass = false;
                            return {
                                pass: pass,
                                message: message
                            };
                        }
                    };
                }
            });
        });

        it('media.spec.1 should exist', function () {
            expect(Media).toBeDefined();
            expect(typeof Media).toBe('function');
        });

        it('media.spec.2 should have the following properties', function () {
            var media1 = new Media('dummy');
            expect(media1.id).toBeDefined();
            expect(media1.src).toBeDefined();
            expect(media1._duration).toBeDefined();
            expect(media1._position).toBeDefined();
            media1.release();
        });

        it('media.spec.3 should define constants for Media status', function () {
            expect(Media).toBeDefined();
            expect(Media.MEDIA_NONE).toBe(0);
            expect(Media.MEDIA_STARTING).toBe(1);
            expect(Media.MEDIA_RUNNING).toBe(2);
            expect(Media.MEDIA_PAUSED).toBe(3);
            expect(Media.MEDIA_STOPPED).toBe(4);
        });

        it('media.spec.4 should define constants for Media errors', function () {
            expect(MediaError).toBeDefined();
            expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0);
            expect(MediaError.MEDIA_ERR_ABORTED).toBe(1);
            expect(MediaError.MEDIA_ERR_NETWORK).toBe(2);
            expect(MediaError.MEDIA_ERR_DECODE).toBe(3);
            expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4);
        });

        it('media.spec.5 should contain a play function', function () {
            var media1 = new Media('dummy');
            expect(media1.play).toBeDefined();
            expect(typeof media1.play).toBe('function');
            media1.release();
        });

        it('media.spec.6 should contain a stop function', function () {
            var media1 = new Media('dummy');
            expect(media1.stop).toBeDefined();
            expect(typeof media1.stop).toBe('function');
            media1.release();
        });

        it('media.spec.7 should contain a seekTo function', function () {
            var media1 = new Media('dummy');
            expect(media1.seekTo).toBeDefined();
            expect(typeof media1.seekTo).toBe('function');
            media1.release();
        });

        it('media.spec.8 should contain a pause function', function () {
            var media1 = new Media('dummy');
            expect(media1.pause).toBeDefined();
            expect(typeof media1.pause).toBe('function');
            media1.release();
        });

        it('media.spec.9 should contain a getDuration function', function () {
            var media1 = new Media('dummy');
            expect(media1.getDuration).toBeDefined();
            expect(typeof media1.getDuration).toBe('function');
            media1.release();
        });

        it('media.spec.10 should contain a getCurrentPosition function', function () {
            var media1 = new Media('dummy');
            expect(media1.getCurrentPosition).toBeDefined();
            expect(typeof media1.getCurrentPosition).toBe('function');
            media1.release();
        });

        it('media.spec.11 should contain a startRecord function', function () {
            var media1 = new Media('dummy');
            expect(media1.startRecord).toBeDefined();
            expect(typeof media1.startRecord).toBe('function');
            media1.release();
        });

        it('media.spec.12 should contain a stopRecord function', function () {
            var media1 = new Media('dummy');
            expect(media1.stopRecord).toBeDefined();
            expect(typeof media1.stopRecord).toBe('function');
            media1.release();
        });

        it('media.spec.13 should contain a release function', function () {
            var media1 = new Media('dummy');
            expect(media1.release).toBeDefined();
            expect(typeof media1.release).toBe('function');
            media1.release();
        });

        it('media.spec.14 should contain a setVolume function', function () {
            var media1 = new Media('dummy');
            expect(media1.setVolume).toBeDefined();
            expect(typeof media1.setVolume).toBe('function');
            media1.release();
        });

        it('media.spec.15 should contain a getCurrentAmplitude function', function () {
            var media1 = new Media('dummy');
            expect(media1.getCurrentAmplitude).toBeDefined();
            expect(typeof media1.getCurrentAmplitude).toBe('function');
            media1.release();
        });

        it('media.spec.16 should contain a pauseRecord function', function () {
            var media1 = new Media('dummy');
            expect(media1.pauseRecord).toBeDefined();
            expect(typeof media1.pauseRecord).toBe('function');
            media1.release();
        });

        it('media.spec.17 should contain a resumeRecord function', function () {
            var media1 = new Media('dummy');
            expect(media1.resumeRecord).toBeDefined();
            expect(typeof media1.resumeRecord).toBe('function');
            media1.release();
        });

        it('media.spec.18 should return MediaError for bad filename', function (done) {
            // bb10 dialog pops up, preventing tests from running
            if (cordova.platformId === 'blackberry10') {
                pending();
            }

            var context = this;
            var fileName = 'invalid.file.name';
            var badMedia = new Media(
                fileName,
                succeed.bind(
                    null,
                    done,
                    ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'
                ),
                function (result) {
                    if (context.done) return;
                    context.done = true;

                    expect(result).toBeDefined();
                    expect(result.code).toBe(MediaError.MEDIA_ERR_ABORTED);
                    if (badMedia) {
                        badMedia.release();
                    }
                    done();
                }
            );
            badMedia.play();
        });

        describe('actual playback', function () {
            var checkInterval, media;

            afterEach(function () {
                clearInterval(checkInterval);
                if (media) {
                    media.stop();
                    media.release();
                    media = null;
                }
            });

            it(
                'media.spec.19 position should be set properly',
                function (done) {
                    // no audio hardware available
                    if (!isAudioSupported || isBrowser || isKitKat) {
                        pending();
                    }

                    // context variable used as an extra security statement to ensure that the callback is processed only once,
                    // in case the statusChange callback is reached more than one time with the same status code.
                    // Some information about this kind of behaviour can be found at JIRA: CB-7099.
                    var context = this;
                    var mediaFile = WEB_MP3_FILE;
                    var successCallback = function () {};
                    var statusChange = function (statusCode) {
                        if (!context.done && statusCode === Media.MEDIA_RUNNING) {
                            checkInterval = setInterval(function () {
                                if (context.done) return;
                                media.getCurrentPosition(function successCallback (position) {
                                    if (position > 0.0) {
                                        context.done = true;
                                        expect(true).toBe(true);
                                        done();
                                    }
                                }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
                            }, 1000);
                        }
                    };
                    media = new Media(
                        mediaFile,
                        successCallback,
                        failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
                        statusChange
                    );
                    media.play();
                },
                ACTUAL_PLAYBACK_TEST_TIMEOUT
            );

            it(
                'media.spec.20 duration should be set properly',
                function (done) {
                    if (!isAudioSupported || cordova.platformId === 'blackberry10' || isBrowser || isKitKat) {
                        pending();
                    }

                    // context variable used as an extra security statement to ensure that the callback is processed only once,
                    // in case the statusChange callback is reached more than one time with the same status code.
                    // Some information about this kind of behaviour can be found at JIRA: CB-7099.
                    var context = this;
                    var mediaFile = WEB_MP3_FILE;
                    var successCallback = function () {};
                    var statusChange = function (statusCode) {
                        if (!context.done && statusCode === Media.MEDIA_RUNNING) {
                            checkInterval = setInterval(function () {
                                if (context.done) return;
                                media.getCurrentPosition(function (position) {
                                    if (position > 0.0) {
                                        context.done = true;
                                        expect(media.getDuration()).toBeGreaterThan(0.0);
                                        done();
                                    }
                                }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
                            }, 1000);
                        }
                    };
                    media = new Media(
                        mediaFile,
                        successCallback,
                        failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
                        statusChange
                    );
                    media.play();
                },
                ACTUAL_PLAYBACK_TEST_TIMEOUT
            );

            it(
                'media.spec.21 should be able to resume playback after pause',
                function (done) {
                    if (!isAudioSupported || cordova.platformId === 'blackberry10' || isKitKat) {
                        pending();
                    }

                    // context variable used as an extra security statement to ensure that the callback is processed only once,
                    // in case the statusChange callback is reached more than one time with the same status code.
                    // Some information about this kind of behaviour can be found at JIRA: CB-7099.
                    var context = this;
                    var resumed = false;
                    var mediaFile = WEB_MP3_FILE;
                    var successCallback = function () {};
                    var statusChange = function (statusCode) {
                        if (context.done) return;

                        if (statusCode === Media.MEDIA_RUNNING) {
                            if (!resumed) {
                                media.seekTo(20000);
                                media.pause();
                                return;
                            }

                            media.getCurrentPosition(function (position) {
                                expect(position).toBeGreaterThan(19);
                                expect(position).toBeLessThan(21);
                                context.done = true;
                                done();
                            }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
                        }

                        if (statusCode === Media.MEDIA_PAUSED) {
                            resumed = true;
                            media.play();
                        }
                    };
                    media = new Media(
                        mediaFile,
                        successCallback,
                        failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
                        statusChange
                    );

                    // CB-10535: Play after a few secs, to give allow enough buffering of media file before seeking
                    setTimeout(function () {
                        media.play();
                    }, 4000);
                },
                ACTUAL_PLAYBACK_TEST_TIMEOUT
            );

            it(
                'media.spec.22 should be able to seek through file',
                function (done) {
                    if (!isAudioSupported || cordova.platformId === 'blackberry10' || isKitKat) {
                        pending();
                    }

                    // context variable used as an extra security statement to ensure that the callback is processed only once,
                    // in case the statusChange callback is reached more than one time with the same status code.
                    // Some information about this kind of behaviour can be found at JIRA: CB-7099.
                    var context = this;
                    var mediaFile = WEB_MP3_FILE;
                    var successCallback = function () {};
                    var statusChange = function (statusCode) {
                        if (!context.done && statusCode === Media.MEDIA_RUNNING) {
                            checkInterval = setInterval(function () {
                                if (context.done) return;
                                media.seekTo(5000);
                                media.getCurrentPosition(function (position) {
                                    expect(position).toBeCloseTo(5, 0);
                                    context.done = true;
                                    done();
                                }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
                            }, 1000);
                        }
                    };
                    media = new Media(
                        mediaFile,
                        successCallback,
                        failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
                        statusChange
                    );

                    // CB-10535: Play after a few secs, to give allow enough buffering of media file before seeking
                    setTimeout(function () {
                        media.play();
                    }, 4000);
                },
                ACTUAL_PLAYBACK_TEST_TIMEOUT
            );
        });

        it('media.spec.23 should contain a setRate function', function () {
            var media1 = new Media('dummy');
            expect(media1.setRate).toBeDefined();
            expect(typeof media1.setRate).toBe('function');
            media1.release();
        });

        it(
            'media.spec.24 playback rate should be set properly using setRate',
            function (done) {
                if (cordova.platformId !== 'ios') {
                    expect(true).toFailWithMessage('Platform does not supported this feature');
                    pending();
                }

                // no audio hardware available
                if (!isAudioSupported) {
                    pending();
                }

                var mediaFile = WEB_MP3_FILE;
                var successCallback;
                var context = this;
                var flag = true;
                var statusChange = function (statusCode) {
                    console.log('status code: ' + statusCode);
                    if (statusCode === Media.MEDIA_RUNNING && flag) {
                        // flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
                        // in case for some reason the statusChange callback is reached more than one time with the same status code.
                        // Some information about this kind of behavior it can be found at JIRA: CB-7099
                        flag = false;
                        setTimeout(function () {
                            media1.getCurrentPosition(
                                function (position) {
                                    // in four seconds expect position to be between 4 & 10. Here, the values are chosen to give
                                    // a large enough buffer range for the position to fall in and are not based on any calculation.
                                    expect(position).not.toBeLessThan(4);
                                    expect(position).toBeLessThan(10);
                                    media1.stop();
                                    media1.release();
                                    context.done = true;
                                    done();
                                },
                                failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position'),
                                context
                            );
                        }, 4000);
                    }
                };

                var media1 = new Media(
                    mediaFile,
                    successCallback,
                    failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
                    statusChange
                );
                // make audio playback two times faster
                media1.setRate(2);
                media1.play();
            },
            ACTUAL_PLAYBACK_TEST_TIMEOUT
        );

        it(
            'media.spec.25 should be able to play an audio stream',
            function (done) {
                // no audio hardware available, OR
                // O_o Safari can't play the stream, so we're skipping this test on all browsers o_O
                if (!isAudioSupported || isBrowser || isKitKat) {
                    pending();
                }

                // The link below points to an infinite mp3 stream
                var mediaFile = WEB_MP3_STREAM;
                var successCallback;
                var context = this;
                var flag = true;
                var statusChange = function (statusCode) {
                    console.log('status code: ' + statusCode);
                    if (statusCode === Media.MEDIA_RUNNING && flag) {
                        // flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
                        // in case for some reason the statusChange callback is reached more than one time with the same status code.
                        // Some information about this kind of behavior it can be found at JIRA: CB-7099
                        flag = false;
                        expect(true).toBe(true);
                        media1.stop();
                        media1.release();
                        context.done = true;
                        done();
                    }
                };

                var media1 = new Media(
                    mediaFile,
                    successCallback,
                    failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
                    statusChange
                );
                media1.play();
            },
            ACTUAL_PLAYBACK_TEST_TIMEOUT
        );

        it('media.spec.26 should not crash or throw when setting the volume right after creating the media', function (done) {
            // bb10 dialog pops up, preventing tests from running
            if (cordova.platformId === 'blackberry10') {
                pending();
            }

            var mediaFile = WEB_MP3_FILE;
            var media = null;

            expect(function () {
                media = new Media(mediaFile);
                media.setVolume('0.5');
            }).not.toThrow();

            // if there is no exception or crash in 3 seconds, the spec is completed
            setTimeout(function () {
                if (media) {
                    media.release();
                    done();
                }
            }, 3000);
        });

        it('media.spec.27 should call success or error when trying to stop a media that is in starting state', function (done) {
            // bb10 dialog pops up, preventing tests from running
            if (!isAudioSupported || cordova.platformId === 'blackberry10') {
                pending();
            }

            var mediaFile = WEB_MP3_FILE;
            var media = null;
            var context = this;
            var beenStarting = false;
            var safeDone = function () {
                if (!context.done) {
                    media.release();
                    context.done = true;
                    done();
                }
            };

            var errorCallback = jasmine.createSpy('errorCallback').and.callFake(function (e) {
                expect(true).toBe(true);
                safeDone();
            });
            var successCallback = function () {
                expect(true).toBe(true);
                safeDone();
            };
            var statusChange = function (s) {
                if (s === Media.MEDIA_STARTING && !context.done) {
                    beenStarting = true;
                    media.stop();
                } else if (s === Media.MEDIA_RUNNING) {
                    // Some plugin implementations may skip "Starting" state
                    // so we'll also try to call stop in "Running" state,
                    // but in this case we should check that the "Starting" state wasn't really reached,
                    // otherwise it would mean that the previous media.stop() call has been ignored
                    expect(beenStarting).toBe(false);
                    media.stop();
                }
            };

            media = new Media(mediaFile, successCallback, errorCallback, statusChange);
            media.play();
        });
    });
};

//* *****************************************************************************************
//* **************************************Manual Tests***************************************
//* *****************************************************************************************

exports.defineManualTests = function (contentEl, createActionButton) {
    // -------------------------------------------------------------------------
    // Audio player
    // -------------------------------------------------------------------------
    var media1 = null;
    var media1Timer = null;
    var audioSrc = null;
    var defaultaudio = WEB_MP3_FILE;

    // Play audio function
    function playAudio (url) {
        console.log('playAudio()');
        console.log(' -- media=' + media1);

        var src = defaultaudio;

        if (url) {
            src = url;
        }

        // Stop playing if src is different from currently playing source
        if (src !== audioSrc) {
            if (media1 !== null) {
                stopAudio();
                media1 = null;
            }
        }

        if (media1 === null) {
            // TEST STREAMING AUDIO PLAYBACK
            // var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3";   // works
            // var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
            // var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
            // var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
            // var src = "MusicSearch/mp3/train.mp3";    // works
            // var src = "bryce.mp3";  // works
            // var src = "/android_asset/www/bryce.mp3"; // works

            media1 = new Media(
                src,
                function () {
                    console.log('playAudio():Audio Success');
                },
                function (err) {
                    console.log('playAudio():Audio Error: ' + err.code);
                    setAudioStatus('Error: ' + err.code);
                },
                function (status) {
                    console.log('playAudio():Audio Status: ' + status);
                    setAudioStatus(Media.MEDIA_MSG[status]);

                    // If stopped, then stop getting current position
                    if (Media.MEDIA_STOPPED === status) {
                        clearInterval(media1Timer);
                        media1Timer = null;
                        setAudioPosition('0 sec');
                    }
                }
            );
        }
        audioSrc = src;
        document.getElementById('durationValue').innerHTML = '';
        // Play audio
        media1.play();
        if (media1Timer === null && media1.getCurrentPosition) {
            media1Timer = setInterval(function () {
                media1.getCurrentPosition(
                    function (position) {
                        if (position >= 0.0) {
                            setAudioPosition(position + ' sec');
                        }
                    },
                    function (e) {
                        console.log('Error getting pos=' + e);
                        setAudioPosition('Error: ' + e);
                    }
                );
            }, 1000);
        }

        // Get duration
        var counter = 0;
        var timerDur = setInterval(function () {
            counter = counter + 100;
            if (counter > 2000) {
                clearInterval(timerDur);
            }
            var dur = media1.getDuration();
            if (dur > 0) {
                clearInterval(timerDur);
                document.getElementById('durationValue').innerHTML = dur + ' sec';
            }
        }, 100);
    }

    // Pause audio playback
    function pauseAudio () {
        console.log('pauseAudio()');
        if (media1) {
            media1.pause();
        }
    }

    // Stop audio
    function stopAudio () {
        console.log('stopAudio()');
        if (media1) {
            media1.stop();
        }
        clearInterval(media1Timer);
        media1Timer = null;
    }

    // Release audio
    function releaseAudio () {
        console.log('releaseAudio()');
        if (media1) {
            media1.stop(); // imlied stop of playback, resets timer
            media1.release();
        }
    }

    // Set audio status
    function setAudioStatus (status) {
        document.getElementById('statusValue').innerHTML = status;
    }

    // Set audio position
    function setAudioPosition (position) {
        document.getElementById('positionValue').innerHTML = position;
    }

    // Seek audio
    function seekAudio (mode) {
        var time = document.getElementById('seekInput').value;
        if (time === '') {
            time = 5000;
        } else {
            time = time * 1000; // we expect the input to be in seconds
        }
        if (media1 === null) {
            console.log('seekTo requested while media1 is null');
            if (audioSrc === null) {
                audioSrc = defaultaudio;
            }
            media1 = new Media(
                audioSrc,
                function () {
                    console.log('seekToAudio():Audio Success');
                },
                function (err) {
                    console.log('seekAudio():Audio Error: ' + err.code);
                    setAudioStatus('Error: ' + err.code);
                },
                function (status) {
                    console.log('seekAudio():Audio Status: ' + status);
                    setAudioStatus(Media.MEDIA_MSG[status]);

                    // If stopped, then stop getting current position
                    if (Media.MEDIA_STOPPED === status) {
                        clearInterval(media1Timer);
                        media1Timer = null;
                        setAudioPosition('0 sec');
                    }
                }
            );
        }

        media1.getCurrentPosition(
            function (position) {
                var deltat = time;
                if (mode === 'by') {
                    deltat = time + position * 1000;
                }
                media1.seekTo(
                    deltat,
                    function () {
                        console.log('seekAudioTo():Audio Success');
                        // force an update on the position display
                        updatePosition();
                    },
                    function (err) {
                        console.log('seekAudioTo():Audio Error: ' + err.code);
                    }
                );
            },
            function (e) {
                console.log('Error getting pos=' + e);
                setAudioPosition('Error: ' + e);
            }
        );
    }

    // set audio volume
    function setVolume () {
        console.log('setVolume()');
        var volume = document.getElementById('volumeInput').value;
        if (media1 !== null) {
            media1.setVolume(volume);
        }
    }

    // for forced updates of position after a successful seek

    function updatePosition () {
        media1.getCurrentPosition(
            function (position) {
                if (position >= 0.0) {
                    setAudioPosition(position + ' sec');
                }
            },
            function (e) {
                console.log('Error getting pos=' + e);
                setAudioPosition('Error: ' + e);
            }
        );
    }

    // -------------------------------------------------------------------------
    // Audio recorder
    // -------------------------------------------------------------------------
    var mediaRec = null;
    var recTime = 0;
    var recordSrc = 'myRecording.mp3';

    // Record audio
    function recordAudio () {
        console.log('recordAudio(), recording to ' + recordSrc);
        console.log(' -- media=' + mediaRec);

        releaseAudio();

        if (!mediaRec) {
            mediaRec = new Media(
                recordSrc,
                function () {
                    console.log('recordAudio():Audio Success');
                },
                function (err) {
                    console.log('recordAudio():Audio Error: ' + err.code);
                    setAudioStatus('Error: ' + err.code);
                },
                function (status) {
                    console.log('recordAudio():Audio Status: ' + status);
                    setAudioStatus(Media.MEDIA_MSG[status]);
                }
            );
        }

        // Record audio
        mediaRec.startRecord();

        // Stop recording after 10 sec
        recTime = 0;
        var recInterval = setInterval(function () {
            recTime = recTime + 1;
            setAudioPosition(recTime + ' sec');
            if (recTime >= 10) {
                clearInterval(recInterval);
                if (mediaRec.stopAudioRecord) {
                    mediaRec.stopAudioRecord();
                } else {
                    mediaRec.stopRecord();
                }
                console.log('recordAudio(): stop');
            }
        }, 1000);
    }

    // Play back recorded audio
    function playRecording () {
        playAudio(recordSrc);
    }

    // Function to get a filename for iOS recording
    // Ensures that file doesn't exist to test CB-11380
    function getRecordSrc () {
        var noop = function () {};
        recordSrc = 'cdvfile://localhost/temporary/iOSRecording.wav';
        window.resolveLocalFileSystemURL(
            recordSrc,
            function (file) {
                file.remove(function () {
                    console.log('Successfully removed ' + recordSrc);
                }, noop);
            },
            noop
        );
    }

    // Function to create a file for BB recording
    function getRecordSrcBB () {
        var fsFail = function (error) {
            console.log('error creating file for BB recording', error);
        };
        var gotFile = function (file) {
            recordSrc = file.fullPath;
        };
        var gotFS = function (fileSystem) {
            fileSystem.root.getFile(
                'BBRecording.amr',
                {
                    create: true
                },
                gotFile,
                fsFail
            );
        };
        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
    }

    // Function to create a file for Windows recording
    function getRecordSrcWin () {
        var fsFail = function (error) {
            console.log('error creating file for Win recording', error);
        };
        var gotFile = function (file) {
            recordSrc = file.name;
        };
        var gotFS = function (fileSystem) {
            fileSystem.root.getFile(
                'WinRecording.m4a',
                {
                    create: true
                },
                gotFile,
                fsFail
            );
        };
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fsFail);
    }

    // Generate Dynamic Table
    function generateTable (tableId, rows, cells, elements) {
        var table = document.createElement('table');
        for (var r = 0; r < rows; r++) {
            var row = table.insertRow(r);
            for (var c = 0; c < cells; c++) {
                var cell = row.insertCell(c);
                cell.setAttribute('align', 'center');
                for (var e in elements) {
                    if (elements[e].position.row === r && elements[e].position.cell === c) {
                        var htmlElement = document.createElement(elements[e].tag);
                        var content;

                        if (elements[e].content !== '') {
                            content = document.createTextNode(elements[e].content);
                            htmlElement.appendChild(content);
                        }
                        if (elements[e].type) {
                            htmlElement.type = elements[e].type;
                        }
                        htmlElement.setAttribute('id', elements[e].id);
                        cell.appendChild(htmlElement);
                    }
                }
            }
        }
        table.setAttribute('align', 'center');
        table.setAttribute('id', tableId);
        return table;
    }

    // Audio && Record Elements
    var elementsResultsAudio = [
        {
            id: 'statusTag',
            content: 'Status:',
            tag: 'div',
            position: {
                row: 0,
                cell: 0
            }
        },
        {
            id: 'statusValue',
            content: '',
            tag: 'div',
            position: {
                row: 0,
                cell: 2
            }
        },
        {
            id: 'durationTag',
            content: 'Duration:',
            tag: 'div',
            position: {
                row: 1,
                cell: 0
            }
        },
        {
            id: 'durationValue',
            content: '',
            tag: 'div',
            position: {
                row: 1,
                cell: 2
            }
        },
        {
            id: 'positionTag',
            content: 'Position:',
            tag: 'div',
            position: {
                row: 2,
                cell: 0
            }
        },
        {
            id: 'positionValue',
            content: '',
            tag: 'div',
            position: {
                row: 2,
                cell: 2
            }
        }
    ];
    var elementsAudio = [
        {
            id: 'playBtn',
            content: '',
            tag: 'div',
            position: {
                row: 0,
                cell: 0
            }
        },
        {
            id: 'pauseBtn',
            content: '',
            tag: 'div',
            position: {
                row: 0,
                cell: 1
            }
        },
        {
            id: 'stopBtn',
            content: '',
            tag: 'div',
            position: {
                row: 1,
                cell: 0
            }
        },
        {
            id: 'releaseBtn',
            content: '',
            tag: 'div',
            position: {
                row: 1,
                cell: 1
            }
        },
        {
            id: 'seekByBtn',
            content: '',
            tag: 'div',
            position: {
                row: 2,
                cell: 0
            }
        },
        {
            id: 'seekToBtn',
            content: '',
            tag: 'div',
            position: {
                row: 2,
                cell: 1
            }
        },
        {
            id: 'seekInput',
            content: '',
            tag: 'input',
            type: 'number',
            position: {
                row: 2,
                cell: 2
            }
        },
        {
            id: 'halfSpeedBtn',
            content: '',
            tag: 'div',
            position: {
                row: 0,
                cell: 2
            }
        },
        {
            id: 'setVolumeBtn',
            content: '',
            tag: 'div',
            position: {
                row: 3,
                cell: 0
            }
        },
        {
            id: 'volumeInput',
            tag: 'input',
            type: 'text',
            position: {
                row: 3,
                cell: 1
            }
        }
    ];
    var elementsRecord = [
        {
            id: 'recordbtn',
            content: '',
            tag: 'div',
            position: {
                row: 1,
                cell: 0
            }
        },
        {
            id: 'recordplayBtn',
            content: '',
            tag: 'div',
            position: {
                row: 1,
                cell: 1
            }
        },
        {
            id: 'recordpauseBtn',
            content: '',
            tag: 'div',
            position: {
                row: 2,
                cell: 0
            }
        },
        {
            id: 'recordstopBtn',
            content: '',
            tag: 'div',
            position: {
                row: 2,
                cell: 1
            }
        }
    ];

    // Title audio results
    var div = document.createElement('h2');
    div.appendChild(document.createTextNode('Audio'));
    div.setAttribute('align', 'center');
    contentEl.appendChild(div);
    // Generate and add results table
    contentEl.appendChild(generateTable('info', 3, 3, elementsResultsAudio));

    // Title audio actions
    div = document.createElement('h2');
    div.appendChild(document.createTextNode('Actions'));
    div.setAttribute('align', 'center');
    contentEl.appendChild(div);
    // Generate and add buttons table
    contentEl.appendChild(generateTable('audioActions', 4, 3, elementsAudio));
    createActionButton(
        'Play',
        function () {
            playAudio();
        },
        'playBtn'
    );
    createActionButton(
        'Pause',
        function () {
            pauseAudio();
        },
        'pauseBtn'
    );
    createActionButton(
        'HalfSpeed',
        function () {
            if (halfSpeedBtn.firstChild.firstChild.innerText === 'HalfSpeed') {
                halfSpeedBtn.firstChild.firstChild.innerText = 'FullSpeed';
                media1.setRate(0.5);
            } else if (halfSpeedBtn.firstChild.firstChild.innerText === 'FullSpeed') {
                halfSpeedBtn.firstChild.firstChild.innerText = 'DoubleSpeed';
                media1.setRate(1.0);
            } else {
                halfSpeedBtn.firstChild.firstChild.innerText = 'HalfSpeed';
                media1.setRate(2.0);
            }
        },
        'halfSpeedBtn'
    );
    createActionButton(
        'Stop',
        function () {
            stopAudio();
        },
        'stopBtn'
    );
    createActionButton(
        'Release',
        function () {
            releaseAudio();
        },
        'releaseBtn'
    );
    createActionButton(
        'Seek By',
        function () {
            seekAudio('by');
        },
        'seekByBtn'
    );
    createActionButton(
        'Seek To',
        function () {
            seekAudio('to');
        },
        'seekToBtn'
    );
    createActionButton(
        'Set volume',
        function () {
            setVolume();
        },
        'setVolumeBtn'
    );
    // get Special path to record if iOS || Blackberry
    if (cordova.platformId === 'ios') {
        getRecordSrc();
    } else if (cordova.platformId === 'blackberry') {
        getRecordSrcBB();
    } else if (cordova.platformId === 'windows' || cordova.platformId === 'windows8') {
        getRecordSrcWin();
    }

    // testing process and details
    function addItemToList (_list, _text) {
        var item = document.createElement('li');
        item.appendChild(document.createTextNode(_text));
        _list.appendChild(item);
    }

    div = document.createElement('h4');
    div.appendChild(document.createTextNode('Recommended Test Procedure'));
    contentEl.appendChild(div);

    var list = document.createElement('ol');
    addItemToList(
        list,
        'Press play - Will start playing audio. Status: Running, Duration: 61.333 sec, Position: Current position of audio track'
    );
    addItemToList(
        list,
        'Press pause - Will pause the audio. Status: Paused, Duration: 61.333 sec, Position: Position where track was paused'
    );
    addItemToList(list, 'Press play - Will begin playing where track left off from the pause');
    addItemToList(list, 'Press stop - Will stop the audio. Status: Stopped, Duration: 61.333 sec, Position: 0 sec');
    addItemToList(list, 'Press play - Will begin playing the audio track from the beginning');
    addItemToList(list, 'Press release - Will stop the audio. Status: Stopped, Duration: 61.333 sec, Position: 0 sec');
    addItemToList(list, 'Press play - Will begin playing the audio track from the beginning');
    addItemToList(list, 'Type 10 in the text box beside Seek To button');
    addItemToList(list, 'Press seek by - Will jump 10 seconds ahead in the audio track. Position: should jump by 10 sec');
    addItemToList(list, 'Press stop if track is not already stopped');
    addItemToList(list, 'Type 30 in the text box beside Seek To button');
    addItemToList(list, 'Press play then seek to - Should jump to Position 30 sec');
    addItemToList(list, 'Press stop');
    addItemToList(list, 'Type 5 in the text box beside Seek To button');
    addItemToList(list, 'Press play, let play past 10 seconds then press seek to - should jump back to position 5 sec');

    div = document.createElement('div');
    div.setAttribute(
        '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'
    );
    div.appendChild(list);
    contentEl.appendChild(div);

    // Title Record Audio
    div = document.createElement('h2');
    div.appendChild(document.createTextNode('Record Audio'));
    div.setAttribute('align', 'center');
    contentEl.appendChild(div);
    // Generate and add Record buttons table
    contentEl.appendChild(generateTable('recordContent', 3, 3, elementsRecord));
    createActionButton(
        'Record Audio \n 10 sec',
        function () {
            recordAudio();
        },
        'recordbtn'
    );
    createActionButton(
        'Play',
        function () {
            playRecording();
        },
        'recordplayBtn'
    );
    createActionButton(
        'Pause',
        function () {
            pauseAudio();
        },
        'recordpauseBtn'
    );
    createActionButton(
        'Stop',
        function () {
            stopAudio();
        },
        'recordstopBtn'
    );

    // testing process and details
    div = document.createElement('h4');
    div.appendChild(document.createTextNode('Recommended Test Procedure'));
    contentEl.appendChild(div);

    list = document.createElement('ol');
    addItemToList(
        list,
        'Press Record Audio 10 sec - Will start recording audio for 10 seconds. Status: Running, Position: number of seconds recorded (will stop at 10)'
    );
    addItemToList(list, 'Status will change to Stopped when finished recording');
    addItemToList(
        list,
        'Press play - Will begin playing the recording. Status: Running, Duration: # of seconds of recording, Position: Current position of recording'
    );
    addItemToList(
        list,
        'Press stop - Will stop playing the recording. Status: Stopped, Duration: # of seconds of recording, Position: 0 sec'
    );
    addItemToList(list, 'Press play - Will begin playing the recording from the beginning');
    addItemToList(
        list,
        'Press pause - Will pause the playback of the recording. Status: Paused, Duration: # of seconds of recording, Position: Position where recording was paused'
    );
    addItemToList(list, 'Press play - Will begin playing the recording from where it was paused');

    div = document.createElement('div');
    div.setAttribute(
        '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'
    );
    div.appendChild(list);
    contentEl.appendChild(div);
};
