﻿
// ------------------------------------------------------------------------------------------------------------------------------
// Array
// ------------------------------------------------------------------------------------------------------------------------------


Array.prototype.indexOf = function (value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] == value) {
            return i;
        }
    }
    return null;
}


Array.prototype.contains = function (value) {
    return this.indexOf(value) != null;
}


Array.prototype.remove = function (value) {
    var index = this.indexOf(value);
    if (index != null) {
        this.splice(index, 1);
        return value;
    }
    return null;
}



// filters an array using provided selectorFunction(arrayobject)
// eg myarray.select(function(arrayobject){ return arrayobject.id = 1; });
Array.prototype.select = function (selectorFunction) {
    var _returnArray = new Array();
    for (var i = 0; i < this.length; i++) {
        if (selectorFunction(this[i])) {
            _returnArray.push(this[i]);
        }
    }
    return _returnArray;
}


Array.prototype.get = function (query) {

    // Supplied an index; return it. 
    if (typeof query == 'number' && query > 0 && query < this.length) {
        return this[query];
    }

    // supplied a comparison function
    if (typeof query == 'function') {
        for (var i = 0; i < this.length; i++) {
            if (query(this[i])) {
                return this[i];
            }
        }
    }

    return null;
}


// Shorthand method for looping through an array
Array.prototype.each = function (function_to_run) {
    var args = new Array();
    args[1] = this;
    for (var i = 0; i < this.length; i++) {
        // use the call function to force 'this' within function_to_run to be the array element i 
        args[0] = i;
        args[2] = this[i];
        function_to_run.apply(this[i], args);
    }
}

// ------------------------------------------------------------------------------------------------------------------------------
// Date
// ------------------------------------------------------------------------------------------------------------------------------


Date.prototype.fromJson = function (value) {
    // remove anything except numbers and + sign (so we can use /Date(123456780000)/ and /Date(12345678+010)/
    var ticks = parseFloat(value.replace(/[^0-9+]/gi, ''));
    this.setTime(ticks);
    return this;
}

Date.prototype.fromJsonWithTimezone = function (value, timezoneOffsetInMinutes) {
    // remove anything except numbers and + sign (so we can use /Date(123456780000)/ and /Date(12345678+010)/
    var ticks = parseFloat(value.replace(/[^0-9+]/gi, ''));
    this.timeZoneCorrection = timezoneOffsetInMinutes;
    var timezoneCorrection = (timezoneOffsetInMinutes || 0) * 60 * 1000;
    this.setTime(ticks + timezoneCorrection);
    return this;
}



Date.prototype.toDayString = function (template) {

    var days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];

    switch (template || '') {
        case 'ddd':
            return days[this.getDay()].substring(0, 3);

        case 'dd':
            return this.getDate() < 10 ? '0' + this.getDate() : this.getDate();

        case 'dS':
            return this.getDate() + this.getDate().ordinalSuffix();

        case 'd':
            return this.getDate();

        default:
            return days[this.getDay()];
    }
}

Date.prototype.toMonthString = function (template) {

    var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

    switch (template || '') {
        case 'mmm':
            return months[this.getMonth()].substring(0, 3);

        case 'mm':
            return this.getMonth() < 10 ? '0' + this.getMonth() : this.getMonth();

        case 'm':
            return this.getMonth();

        default:
            return months[this.getMonth()];
    }
}


Date.prototype.toUTCDateString = function (format) {
    format = format || 'dd/MM/yyyy';
    var formatOptions = [
        { id: 'dd', value: function (date) { return date.getUTCDate().padWithZeros(2); } },
        { id: 'MMM', value: function (date) { return date.toMonthString(); } },
        { id: 'MM', value: function (date) { return (date.getUTCMonth() + 1).padWithZeros(2); } },
        { id: 'yyyy', value: function (date) { return date.getUTCFullYear().padWithZeros(4); } },
        { id: 'HH', value: function (date) { return date.getUTCHours().padWithZeros(2); } },
        { id: 'hh', value: function (date) { return (date.getUTCHours() % 12).padWithZeros(2); } },
        { id: 'mm', value: function (date) { return date.getUTCMinutes().padWithZeros(2); } },
        { id: 'ss', value: function (date) { return date.getUTCSeconds().padWithZeros(2); } }
    ];
    for (var i = 0; i < formatOptions.length; i++) {
        format = format.replace(formatOptions[i].id, formatOptions[i].value(this));
    }
    return format;
}

// ------------------------------------------------------------------------------------------------------------------------------
// Number
// ------------------------------------------------------------------------------------------------------------------------------


Number.prototype.ordinalSuffix = function () {
    if (this > 3) {
        return 'th';
    }
    else if (this == 3) {
        return 'rd';
    }
    else if (this == 2) {
        return 'nd';
    }
    else if (this == 1) {
        return 'st';
    }
}


Number.prototype.padWithZeros = function(digits){
    ///<summary>Pads a number with the specified number of zeros</summary>
    var text = '' + this;
    for (var i = text.length; i < digits; i++){
        text = '0' + text;
    }
    return text;
}


// ------------------------------------------------------------------------------------------------------------------------------
// String
// ------------------------------------------------------------------------------------------------------------------------------

// truncate string to nearest word
String.prototype.truncate = function (limit, useWordBoundary) {
    var tooLong = this.length > limit;
    var shortened = tooLong ? this.substr(0, limit - 1) : this;
    shortened = useWordBoundary && tooLong ? shortened.substr(0, shortened.lastIndexOf(' ')) : shortened;
    return tooLong ? shortened + '...' : shortened;
};


// strip html
String.prototype.stripHtml = function () {
    return this.replace(/(<([^>]+)>)/ig, "");
};


String.prototype.contains = function (value) {
    return this.indexOf(value) > -1;
}

// safely add a querystring term to a url
String.prototype.addQueryStringTermToUrl = function (value) {
    if (this.contains('?')) {
        return this + '&' + value;
    }
    else {
        return this + '?' + value;
    }
}



String.prototype.isNullOrEmpty = function () {
    return this == null || this == '';
}



// Replaces all instances of the given substring.
String.prototype.replaceAll = function (
strTarget, // The substring you want to replace
strSubString // The string you want to replace in.
) {
    var strText = this;
    var intIndexOfMatch = strText.indexOf(strTarget);

    // Keep looping while an instance of the target string
    // still exists in the string.
    while (intIndexOfMatch != -1) {
        // Relace out the current instance.
        strText = strText.replace(strTarget, strSubString)

        // Get the index of any next matching substring.
        intIndexOfMatch = strText.indexOf(strTarget);
    }

    // Return the updated string with ALL the target strings
    // replaced out with the new substring.
    return (strText);
}

