const SERVER_REPLY_INVALID_POST_DATA_ERROR                = 'Invalid POST data!';
const SERVER_REPLY_INVALID_NUMBER_OF_POST_ARGUMENTS_ERROR = 'Invalid number of POST arguments!';
const SERVER_REPLY_GENERIC_NO                             = 'n';
const SERVER_REPLY_GENERIC_YES                            = 'y';
const SERVER_REPLY_GENERIC_LOGIC_ERROR                    = 'l';
const SERVER_REPLY_GENERIC_SERVER_ERROR                   = 's';

const DISABLED    = 'disabled';
const READ_ONLY   = 'readonly';
const INPUT_EVENT = 'input';

function has_white_space(string) {
    return string.indexOf(' ') >= 0;
}

function is_ascii(string) {
    return /^[\x00-\x7F]*$/.test(string);
}

/*__             __   __          __        __   __        ___    ___       __
 /  ` |     /\  /__` /__`    .   /  ` |    /  \ /  ` |__/ |__  | |__  |    |  \
 \__, |___ /~~\ .__/ .__/    .   \__, |___ \__/ \__, |  \ |    | |___ |___ |__/
*/

function ClockField(name) {
    this.element = $('#' + name);
}

/*__             __   __          __       ___  ___  ___    ___       __
 /  ` |     /\  /__` /__`    .   |  \  /\   |  |__  |__  | |__  |    |  \
 \__, |___ /~~\ .__/ .__/    .   |__/ /~~\  |  |___ |    | |___ |___ |__/
*/


/*__             __   __               ___  __   __       ___ ___  __
 /  ` |     /\  /__` /__`    .   |  | |__  |__) |__) |  |  |   |  /  \ |\ |
 \__, |___ /~~\ .__/ .__/    .   |/\| |___ |__) |__) \__/  |   |  \__/ | \|
*/
function WebButton(name) {
    this.element = $('#' + name);
}

WebButton.prototype.click = function() {
    this.element.click();
};

WebButton.prototype.enable = function() {
    this.element.prop(DISABLED, false);
};

WebButton.prototype.disable = function() {
    this.element.prop(DISABLED, true);
};

WebButton.prototype.hide = function() {
    this.element.hide();
};

WebButton.prototype.show = function() {
  this.element.show();
};

/* __             __   __                 __       ___     ___    ___       __
  /  ` |     /\  /__` /__`    .   | |\ | |__) |  |  |     |__  | |__  |    |  \
  \__, |___ /~~\ .__/ .__/    .   | | \| |    \__/  |     |    | |___ |___ |__/
*/

function InputField(name) {
    this.element        = $('#' + name);
    this.form           = $('#' + name + '_form');
    this.error          = $('#' + name + '_error');
    this.has_error      = false;
    this.is_read_only   = false;
    this.original_value = this.element.val();
}

InputField.prototype.REPLY_DO_ERRORS_EXIST_YES_WHITE_SPACE_ISSUE    = "Error : The input has white space!";
InputField.prototype.REPLY_DO_ERRORS_EXIST_YES_NON_ASCII_TEXT_ISSUE = "Error : The input has non-ascii text!";
InputField.prototype.REPLY_DO_ERRORS_EXIST_YES_TEXT_TOO_SHORT       = "Error : The input must be more than 4 characters.";
InputField.prototype.REPLY_DO_ERRORS_EXIST_YES_YES_TOO_LONG         = "Error : The input must be less than 40 characters.";
InputField.prototype.REPLY_DO_ERRORS_EXIST_NO                       = "No errors!";

InputField.prototype.set_original_value = function() {
    this.original_value = this.element.val();
};

InputField.prototype.currently_is_original_value = function() {
    return this.original_value === this.element.val();
};

InputField.prototype.enable = function() {
    this.element.prop(READ_ONLY, true);
    this.is_read_only = true;
};

InputField.prototype.disable = function() {
    this.element.prop(READ_ONLY, false);
    this.is_read_only = false;
};

InputField.prototype.set_to_error = function(error_message) {
    this.form.addClass('has-error');
    this.form.removeClass('has-success');
    this.error.show();
    this.error.text(error_message);
    this.has_error = true;
};

InputField.prototype.check_for_errors = function() {
    var response = this.do_errors_exist();

    if (!this.is_read_only) {
        if (response === InputField.prototype.REPLY_DO_ERRORS_EXIST_NO) {
            this.form.addClass('has-success');
            this.form.removeClass('has-error');
            this.error.hide();
        } else {
            this.set_to_error(response);
            return true;
        }
    }
    this.has_error = false;
    return false;
};

InputField.prototype.do_errors_exist = function() {
    if (has_white_space(this.element.val())) {
        return this.REPLY_DO_ERRORS_EXIST_YES_WHITE_SPACE_ISSUE
    } else if (!is_ascii(this.element.val())) {
        return this.REPLY_DO_ERRORS_EXIST_YES_NON_ASCII_TEXT_ISSUE
    } else if (this.element.val().length < 4) {
        return this.REPLY_DO_ERRORS_EXIST_YES_TEXT_TOO_SHORT
    } else if (this.element.val().length > 40) {
        return this.REPLY_DO_ERRORS_EXIST_YES_YES_TOO_LONG
    } else {
        return this.REPLY_DO_ERRORS_EXIST_NO
    }
};

InputField.prototype.get_content = function() {
    return this.element.val();
};

InputField.prototype.reset_to_original_value = function() {
    this.element.val(this.original_value);
};

InputField.prototype.is_healthy = function () {
    return !(this.element.val().length == 0) && !this.has_error;
};

/*   __             __   __                             __  ___      ___       __
    /  ` |     /\  /__` /__`    .    /\     |  /\  \_/ /__`  |   /\   |  |  | /__`
    \__, |___ /~~\ .__/ .__/    .   /~~\ \__/ /~~\ / \ .__/  |  /~~\  |  \__/ .__/
*/
function AJAXStatus() {
    this.element = $('#ajax_info');
    this.request_in_progress = false
}

AJAXStatus.prototype.set_text = function(text) {
    this.element.text(text);
};

AJAXStatus.prototype.clear_text = function() {
    this.element.text('');
};

/*__             __   __      __   __   __   __   __                   ___    __                      __
 /  ` |     /\  /__` /__`    |__) |__) /  \ / _` |__)  |\/|  |\/|  /\   |  | /  `  /\     |  /\  \_/ /  `  /\  |    |
 \__, |___ /~~\ .__/ .__/    |    |  \ \__/ \__> |  \  |  |  |  | /~~\  |  | \__, /~~\ \__/ /~~\ / \ \__, /~~\ |___ |___
*/
function ProgrammaticAJAXCall(ajax_url, success_function, failure_function, debug) {
    this.ajax_url                          = ajax_url;
    this.success_function                  = success_function;
    this.failure_function                  = failure_function;
    this.post_dictionary_element_reference = {};
    this.post_dictionary_by_value          = {};
    this.in_progress                       = false;
    this.debug                             = debug;
}

ProgrammaticAJAXCall.prototype.change_ajax_url = function(new_ajax_url) {
    this.ajax_url = new_ajax_url;
};

ProgrammaticAJAXCall.prototype.set_post_field_name_and_value = function(post_field_name, post_value) {
    this.post_dictionary_by_value[post_field_name] = post_value;
};

ProgrammaticAJAXCall.prototype.add_post_field_name_and_reference_element_id = function(post_field_name, reference_element_id) {
    this.post_dictionary_element_reference[post_field_name] = reference_element_id;
};

ProgrammaticAJAXCall.prototype.get_post_data = function() {
    var post_data = {};
    for (var key in this.post_dictionary_element_reference) {
        post_data[key] = $('#' + this.post_dictionary_element_reference[key]).val();
    }
    for (var key in this.post_dictionary_by_value) {
        post_data[key] = this.post_dictionary_by_value[key];
    }
    return post_data;
};

ProgrammaticAJAXCall.prototype.make_call = function() {

    var _this = this;

    $.post(_this.ajax_url,
        _this.get_post_data()
        , function(data, status) {
        if (status === 'success') {
            if (_this.debug) {
                console.log('AJAX call to ' + _this.ajax_url + ' was successful!');
            }
            _this.success_function(data);
            _this.in_progress = false;
        } else {
            if (_this.debug) {
                console.log('AJAX call to ' + _this.ajax_url + ' failed!');
            }
            _this.failure_function();
            _this.in_progress = false;
        }
    });
};

/*__             __   __                                __
 /  ` |     /\  /__` /__`    .    /\     |  /\  \_/    /  `  /\  |    |
 \__, |___ /~~\ .__/ .__/    .   /~~\ \__/ /~~\ / \    \__, /~~\ |___ |___
*/
function AJAXCall(ajax_url, success_function, failure_function, debug) {
    this.ajax_url         = ajax_url;
    this.ajax_button      = new WebButton(ajax_url + '_button');
    this.ajax_status      = $('#' + ajax_url + '_status');
    this.in_progress      = false;
    this.post_dictionary  = {};
    this.success_function = success_function;
    this.failure_function = failure_function;
    this.debug            = debug;

    var _this = this;

    this.ajax_button.element.click(function() {
        _this.in_progress = true;
        _this.ajax_status.text('AJAX call currently in progress.');
        if (_this.debug) {
            console.log('Making an AJAX call to ' + _this.ajax_url);
        }
        $.post(_this.ajax_url,
            _this.get_post_data()
        , function(data, status) {
            if (status === 'success') {
                if (_this.debug) {
                    console.log('AJAX call to ' + _this.ajax_url + ' was successful!');
                }
                _this.success_function(data);
                _this.in_progress = false;
            } else {
                if (_this.debug) {
                    console.log('AJAX call to ' + _this.ajax_url + ' failed!');
                }
                _this.failure_function();
                _this.in_progress = false;
            }
        });
    });
}

AJAXCall.prototype.set_status_text = function(status_text) {
    this.ajax_status.val(status_text);
};

AJAXCall.prototype.add_post_field_name_and_reference_element_id = function(post_field_name, reference_element_id) {
    this.post_dictionary[post_field_name] = reference_element_id;
};

AJAXCall.prototype.get_post_data = function() {
    var post_data = {};
    for (var key in this.post_dictionary) {
        post_data[key] = $('#' + this.post_dictionary[key]).val();
    }
    return post_data;
};

/* __   __   __     __  ___     __  ___       __  ___
  /__` /  ` |__) | |__)  |     /__`  |   /\  |__)  |
  .__/ \__, |  \ | |     |     .__/  |  /~~\ |  \  |
*/

$(document).ready(function() {

    // Needed for tooltips to work.
    $('[data-toggle="tooltip"]').tooltip();

    var feedback = new InputField('feedback');

    $('#feedback').keypress(function(event) {
        if (event.keyCode === 10 || event.keyCode === 13) {
            event.preventDefault();
            
            console.log('Doing AJAX to \'send_feedback\'');
            $.post('send_feedback', {
                content       : feedback.get_content(),
                page_sent_from: window.location.href
            }, function (data, status) {
                if (status === 'success') {
                    console.log('Got the following data : ' + data);
                    feedback.element.val('Feedback sent successfully, thank you so much!')
                } else {
                    console.log('DEBUG THIS ERROR!!?');
                    feedback.element.val('Sorry :X, error sending data to the server.');
                }
            });

        }
    });

    function set_footer_time() {
        var m = moment().format('MM.DD.YYYY, hh:mm:ss | ');
        footer_time.text(m);
    }

    var footer_time = $('#footer_time');
    set_footer_time();

    setInterval(function () {
        set_footer_time();
    }, 1000);

    var weather_data_toggle = $('#weather_data');

    weather_data_toggle.click(function() {
        console.log('Weather data toggle was just clicked!');
    });

});