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

//cordova-js/lib/common/plugin/CaptureError.js
var INTERNAL_ERROR_CODE = 0,
    APPLICATION_BUSY_ERROR_CODE = 1,
    INVALID_ARGUMENT_ERROR_CODE = 2,
    NO_MEDIA_FILES_ERROR_CODE = 3;

function capture(action, options, result, webview) {
    var limit = options.limit || 1,
        fail = function (error) {
            result.callbackError({code: INTERNAL_ERROR_CODE});
        },
        onCaptured = function (path) {
            var sb = webview.setFileSystemSandbox;
            webview.setFileSystemSandbox = false;
            window.webkitRequestFileSystem(window.PERSISTENT, 1024, function (fs) {
                fs.root.getFile(path, {}, function (fe) {
                    fe.file(function (file) {
                        file.fullPath = fe.fullPath;
                        webview.setFileSystemSandbox = sb;
                        result.callbackOk([file]);
                    }, fail);
                }, fail);
            }, fail);
        },
        onAudioCaptured = function (response) {
            window.qnx.webplatform.getApplication().invocation.removeEventListener("childCardClosed", onAudioCaptured);
            if (response.data && response.data !== "") {
                onCaptured(response.data);
            } else {
                result.callbackError({code: NO_MEDIA_FILES_ERROR_CODE });
            }
        },
        onCancelled = function () {
            result.callbackError({code: NO_MEDIA_FILES_ERROR_CODE });
        },
        onInvoked = function (error) {
            if (error) {
                result.callbackError({code: APPLICATION_BUSY_ERROR_CODE});
            }
        };

    if (limit < 0) {
        result.error({code: INVALID_ARGUMENT_ERROR_CODE});
    } else if (action === "audio") {
        window.qnx.webplatform.getApplication().invocation.invoke(
            { 
                target: "sys.apps.audiorecorder",
                action: "bb.action.CAPTURE"
            },
            function (error) {
                if (error) {
                    console.log(error);
                } else {
                    window.qnx.webplatform.getApplication().invocation.addEventListener("childCardClosed", onAudioCaptured);
                }
            });
        result.noResult(true);
    } else {
        window.qnx.webplatform.getApplication().cards.camera.open(action, onCaptured, onCancelled, onInvoked);
        result.noResult(true);
    }
}

module.exports = {
    getSupportedAudioModes: function (success, fail, args, env) {
        var result = new PluginResult(args, env);
        result.ok([]);
    },
    getSupportedImageModes: function (win, fail, args, env) {
        var result = new PluginResult(args, env);
        result.ok([]);
    },
    getSupportedVideoModes: function (win, fail, args, env) {
        var result = new PluginResult(args, env);
        result.ok([]);
    },
    captureImage: function (win, fail, args, env) {
        var result = new PluginResult(args, env),
            options = args[0] === "undefined" ? {} : JSON.parse(decodeURIComponent(args[0]));

        capture("photo", options,  result, env.webview);
    },
    captureVideo: function (win, fail, args, env) {
        var result = new PluginResult(args, env),
            options = args[0] === "undefined" ? {} : JSON.parse(decodeURIComponent(args[0]));

        capture("video", options, result, env.webview);
    },
    captureAudio: function (win, fail, args, env) {
        var result = new PluginResult(args, env);
        capture("audio", {}, result, env.webview);
    }
};
