/*
 * corvusgps.ajax.js
 *
 * Copyright (c) CorvusGPS.com, 2015. All rights reserved.
 */

var corvusGps = new function () {
    "use strict";
    var baseUrl = "https://linda.corvusgps.com/interfaces/";
    var loginStatusUrl = "login_status_interface.php?origin=map-app";
    var loginUrl = "login_interface.php?origin=map-app";
    var devicesUrl = "device_interface.php?origin=map-app";
    var groupsUrl = "group_interface.php?origin=map-app";
    var mapUrl = "map_interface.php?origin=map-app";

    /**
     * Performs a login asynchronously.
     * 
     * @param {string} apiUrl The address of the login interface.
     * @param {string} formData Login form as a string.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {boolean} True, if the login was successful, otherwise false.
     */
    function ajaxPerformLogin(apiUrl, formData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            url: apiUrl,
            data: formData,
            success: function (data) {
                // this means that the supplied credentials were invalid, so the error callback should be invoked
            	if (data === "0") {
                    if (typeof errorCallback === "function") {
                        errorCallback();
                    }

                    return false;
                }

            	if (typeof successCallback === "function") {
                    successCallback(data);
                } else {
                    window.localStorage.setItem("auth_data", data);
                    window.localStorage.setItem("auth_is_authenticated", true);
                    window.localStorage.setItem("login_form_data", formData);
                }

                return true;
            },
            error: function () {
                if (typeof errorCallback === "function") {
                    errorCallback();
                }

                return false;
            }
        });
    }

    /**
     * Verifies credentials asynchronously.
     * 
     * @param {string} apiUrl The address of the login verification interface.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {boolean} True, if the login is valid, otherwise false.
     */
    function ajaxVerifyLogin(apiUrl, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            url: apiUrl,
            success: function (data) {
                if (data === "0") {
                    if (typeof errorCallback === "function") {
                        errorCallback();
                    }

                    return false;
                }

                if (typeof successCallback === "function") {
                    successCallback(data);
                }

                return true;
            },
            error: function () {
                if (typeof errorCallback === "function") {
                    errorCallback();
                }

                return false;
            }
        });
    }

    /**
     * Gets the registered devices or groups collection asynchronously.
     * 
     * @param {string} apiUrl The address of the device or group collection interface.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {string} A (possibly empty) JSON serialized collection of registered of devices or groups.
     */
    function ajaxGetDeviceOrGroupCollection(apiUrl, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            url: apiUrl,
            dataType: "json",
            success: function (data) {
                if (typeof successCallback === "function") {
                    successCallback(data);
                }

                return data;
            },
            error: function () {
                if (typeof errorCallback === "function") {
                    errorCallback();
                }

                return [];
            }
        });
    }

    /**
     * Gets the map data specified by the params object.
     * 
     * @param {string} apiUrl The address of the group collection interface.
     * @param {object} params Parameter object specifying the requested map data.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {string} A (possibly empty) JSON serialized set of map data.
     */
    function ajaxGetMapData(apiUrl, params, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            url: apiUrl,
            data: params,
            dataType: "json",
            success: function (data) {
                if (typeof successCallback === "function") {
                    successCallback(data);
                }

                return data;
            },
            error: function () {
                if (typeof errorCallback === "function") {
                    errorCallback();
                }

                return [];
            }
        });
    }

    /**
     * Persists the authentication data to HTML5 localStorage.
     * 
     * @param {string} authenticationData The authentication data received from the server interface.
     * @param {string} formData Login form as a string.
     */
    function persistAuthenticationData(authenticationData, formData) {
        window.localStorage.setItem("auth_is_authenticated", true);
        window.localStorage.setItem("auth_data", authenticationData);
        window.localStorage.setItem("login_form_data", formData);
    }

    /**
     * Removes the authentication data from the HTML5 localStorage.
     */
    function removeAuthenticationData() {
        window.localStorage.removeItem("auth_data");
        window.localStorage.removeItem("login_form_data");
        window.localStorage.setItem("auth_is_authenticated", false);
    }

    /**
     * Performs a login asynchronously.
     * 
     * @param {string} apiUrl The address of the login interface.
     * @param {string} formData Login form as a string.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {boolean} True, if the login was successful, otherwise false.
     */
    this.performLogin = function (apiUrl, formData, successCallback, errorCallback) {
        return ajaxPerformLogin(baseUrl + loginUrl, formData, successCallback, errorCallback);
    };

    /**
     * Verifies credentials asynchronously.
     * 
     * @param {string} apiUrl The address of the login verification interface.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {boolean} True, if the login is valid, otherwise false.
     */
    this.verifyLogin = function (apiUrl, successCallback, errorCallback) {
        return ajaxVerifyLogin(baseUrl + loginStatusUrl, successCallback, errorCallback);
    };

    /**
     * Performs refreshing the authentication info.
     * 
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     */
    this.refreshLogin = function (successCallback) {
        if (typeof successCallback !== "function") {
            successCallback = function () { }
        }

        // performs re-authentication
        var isAuthenticated = window.localStorage.getItem("auth_is_authenticated");
        if (isAuthenticated) {
            var loginFormData = window.localStorage.getItem("login_form_data");
            if (loginFormData) {
                ajaxPerformLogin(
                    baseUrl + loginUrl,
                    loginFormData,
                    successCallback,
                    function () {
                        console.log("corvusgps.ajax.js/refreshLogin(): Authentication was not successful. Please try again.");
                    });
            } else {
                console.log("corvusgps.ajax.js/refreshLogin(): Previously stored credentials were not found.");
            }
        }
    }

    /**
     * Gets the registered devices or groups collection asynchronously.
     * 
     * @param {string} apiUrl The address of the device or group collection interface.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {string} A (possibly empty) JSON serialized collection of registered of devices or groups.
     */
    this.getDeviceOrGroupCollection = function (apiUrl, successCallback, errorCallback) {
        return ajaxGetDeviceOrGroupCollection(apiUrl, successCallback, errorCallback);
    };

    /**
     * Gets the registered devices or groups collection asynchronously.
     * 
     * @param {string} apiUrl The address of the device or group collection interface.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {string} A (possibly empty) JSON serialized collection of registered of devices or groups.
     */
    this.getDeviceCollection = function (apiUrl, successCallback, errorCallback) {
        return ajaxGetDeviceOrGroupCollection(baseUrl + devicesUrl, successCallback, errorCallback);
    };

    /**
     * Gets the registered devices or groups collection asynchronously.
     * 
     * @param {string} apiUrl The address of the device or group collection interface.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {string} A (possibly empty) JSON serialized collection of registered of devices or groups.
     */
    this.getGroupCollection = function (apiUrl, successCallback, errorCallback) {
        return ajaxGetDeviceOrGroupCollection(baseUrl + groupsUrl, successCallback, errorCallback);
    };

    /**
     * Gets the map data specified by the params object.
     * 
     * @param {string} apiUrl The address of the group collection interface.
     * @param {object} params Parameter object specifying the requested map data.
     * @param {function} successCallback Function which will be invoked, if the operation is successful.
     * @param {function} errorCallback Function which will be invoked, if the operation has errors.
     * @returns {string} A (possibly empty) JSON serialized set of map data.
     */
    this.getMapData = function (apiUrl, params, successCallback, errorCallback) {
        return ajaxGetMapData(baseUrl + mapUrl, params, successCallback, errorCallback);
    };

    /**
     * Persists the authentication data to HTML5 localStorage.
     * 
     * @param {string} authenticationData The authentication data received from the server interface.
     * @param {string} formData Login form as a string.
     */
    this.persistAuthenticationData = function (authenticationData, formData) {
        persistAuthenticationData(authenticationData, formData);
    };

    /**
     * Removes the authentication data from the HTML5 localStorage.
     */
    this.removeAuthenticationData = function () {
        removeAuthenticationData();
    };
};