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

var exec = require('cordova/exec');
var platform = require('cordova/platform');

/**
 * Provides access to notifications on the device.
 */

module.exports = {

    /**
     * Open a native alert dialog, with a customizable title and button text.
     *
     * @param {String} message              Message to print in the body of the alert
     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
     * @param {String} title                Title of the alert dialog (default: Alert)
     * @param {String} buttonLabel          Label of the close button (default: OK)
     */
    alert: function (message, completeCallback, title, buttonLabel) {
        var _message = (typeof message === 'string' ? message : JSON.stringify(message));
        var _title = (typeof title === 'string' ? title : 'Alert');
        var _buttonLabel = (buttonLabel && typeof buttonLabel === 'string' ? buttonLabel : 'OK');
        exec(completeCallback, null, 'Notification', 'alert', [_message, _title, _buttonLabel]);
    },

    /**
     * Open a native confirm dialog, with a customizable title and button text.
     * The result that the user selects is returned to the result callback.
     *
     * @param {String} message              Message to print in the body of the alert
     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
     * @param {String} title                Title of the alert dialog (default: Confirm)
     * @param {Array} buttonLabels          Array of the labels of the buttons (default: ['OK', 'Cancel'])
     */
    confirm: function (message, resultCallback, title, buttonLabels) {
        var _message = (typeof message === 'string' ? message : JSON.stringify(message));
        var _title = (typeof title === 'string' ? title : 'Confirm');
        var _buttonLabels = (buttonLabels || ['OK', 'Cancel']);

        // Strings are deprecated!
        if (typeof _buttonLabels === 'string') {
            console.log('Notification.confirm(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).');
        }

        _buttonLabels = convertButtonLabels(_buttonLabels);

        exec(resultCallback, null, 'Notification', 'confirm', [_message, _title, _buttonLabels]);
    },

    /**
     * Open a native prompt dialog, with a customizable title and button text.
     * The following results are returned to the result callback:
     *  buttonIndex     Index number of the button selected.
     *  input1          The text entered in the prompt dialog box.
     *
     * @param {String} message              Dialog message to display (default: "Prompt message")
     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
     * @param {String} title                Title of the dialog (default: "Prompt")
     * @param {Array} buttonLabels          Array of strings for the button labels (default: ["OK","Cancel"])
     * @param {String} defaultText          Textbox input value (default: empty string)
     */
    prompt: function (message, resultCallback, title, buttonLabels, defaultText) {
        var _message = (typeof message === 'string' ? message : JSON.stringify(message));
        var _title = (typeof title === 'string' ? title : 'Prompt');
        var _buttonLabels = (buttonLabels || ['OK', 'Cancel']);

        // Strings are deprecated!
        if (typeof _buttonLabels === 'string') {
            console.log('Notification.prompt(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).');
        }

        _buttonLabels = convertButtonLabels(_buttonLabels);

        var _defaultText = (defaultText || '');
        exec(resultCallback, null, 'Notification', 'prompt', [_message, _title, _buttonLabels, _defaultText]);
    },

    /**
     * Causes the device to beep.
     * On Android, the default notification ringtone is played "count" times.
     *
     * @param {Integer} count       The number of beeps.
     */
    beep: function (count) {
        var defaultedCount = count || 1;
        exec(null, null, 'Notification', 'beep', [ defaultedCount ]);
    }
};

function convertButtonLabels (buttonLabels) {

    // Some platforms take an array of button label names.
    // Other platforms take a comma separated list.
    // For compatibility, we convert to the desired type based on the platform.
    if (platform.id === 'amazon-fireos' || platform.id === 'android' || platform.id === 'ios' ||
        platform.id === 'windowsphone' || platform.id === 'firefoxos' || platform.id === 'ubuntu' ||
        platform.id === 'windows8' || platform.id === 'windows') {

        if (typeof buttonLabels === 'string') {
            buttonLabels = buttonLabels.split(','); // not crazy about changing the var type here
        }
    } else {
        if (Array.isArray(buttonLabels)) {
            var buttonLabelArray = buttonLabels;
            buttonLabels = buttonLabelArray.toString();
        }
    }

    return buttonLabels;
}
