/*!
 * (c) 2010 SysIQ, Inc. All rights reserved.
 *
 * This product is protected by United States laws,
 * international copyright treaties and all other applicable
 * national or international laws.
 *
 * This software may not, in whole or in part, be copied,
 * photocopied, translated, modified, or reduced to any
 * electronic medium or machine readable form
 * without the prior written consent of SysIQ, Inc.
 *
 * Filename: commons.js
 * Author:   Alexander Goldobin
 */

//Date extensions

Date.fromObj = function(o, dateOnly) {
    return dateOnly ?
           new Date(o.year, o.month - 1, o.day) :
           new Date(o.year, o.month - 1, o.day, o.hours, o.minutes, o.seconds, o.milliseconds);
};

Date.prototype.addMonths = function(months) {
    var years = Math.ceil(months/12);
    months = months - (years * 12);

    var m = this.getMonth() + months;
    var newDate = new Date(this.getTime());

    if (m < 0) {
        newDate.setMonth(12 + m);
        newDate.setYear(this.getFullYear() + years - 1);
    }
    else if (m > 11) {
        newDate.setMonth(m - 12);
        newDate.setYear(this.getFullYear() + years + 1);
    }
    else {
        newDate.setMonth(m);
        newDate.setYear(this.getFullYear() + years);
    }

    return newDate;
};

Date.prototype.formatAsUsDateShort = function() {
    var y = (""+this.year);
    var shortY = y.length > 2 ? y.substr(2, y.length - 2) : y;
    return (this.month + 1) + "/" + this.day + "/" + shortY;
};

// String extensions

String.prototype.toUpperCaseFirst = function() {
    if (this.length > 1) {
        var firstChar = this.substr(0,1).toUpperCase();
        return firstChar + this.substr(1, this.length - 1);
    }
    else {
        return this.toUpperCase();
    }
};

// Array extensions

(function($){
    $.representArray = function(arr, separator) {
        var representation = "";
        var blocksPut = 0;
        for (var i = 0; i < arr.length; ++i) {
            var str = jQuery.trim(jQuery.isFunction(arr[i]) ? arr[i]() : arr[i]);
            if (str.length > 0) {
                if (blocksPut++ > 0) {
                    representation += separator;
                }

                representation += str;
            }
        }
        return representation;
    };
})(jQuery);

// jQuery extensions

(function($){
    $.mapDict = function(dict, fn) {
        var d = {};
        $.each(dict, function(k, v) {
            d[k] = fn(k, v);
        });
        return d;
    };

    $.mapSelectors = function(selectors) {
        return $.mapDict(selectors, function(k, v) { return $(v); });
    };

    $.fn.mapSelectors = function(selectors) {
        var self = $(this);
        return $.mapDict(selectors, function(k, v) { return self.find(v); });
    };

})(jQuery); 


// Checks is value informally nothing 
(function($){
    $.isNothing = function(o) {
        return o == null || $.trim(o).length == 0;
    };

})(jQuery);


// Properties
(function($){
    $.property = function(name) {
        $.fn[name] = function() {
            if (arguments.length > 0) {
                this.trigger(name, arguments[0]);
            }
            else {
                var holder = {
                    result: null
                };
                this.trigger(name, holder);
                return holder.result;
            }

        }
    };

    $.fn.propertyHandler = function(name, fns) {
        this.bind(name, function(e, v) {
            if (e.target != this) return;
            if ($.isFunction(fns.get)) {
                v.result = fns.get();
            }
            if ($.isFunction(fns.set)) {
                fns.set(v);
            }
        });
    }


})(jQuery);

// Event Shortcut
(function($){
$.eventShortcut = function(name) {

    $.fn[name] = function(fn) {
        if ($.isFunction(fn)) {
            this.bind(name, fn);
        }
        else {
            this.trigger(name);
        }
    }
};

})(jQuery);

(function($){
$.objectSize = function(object) {
    var count = 0;
    $.each(object, function(k, v){
        count++;
    });
    return count
};

})(jQuery);


// jQuery.validation extensions

(function($){

if (!$.validator) {
    return;
}

$.validator.addMethod("creditCardExpiration", function(value, element, params) {
        var minMonth = new Date().getMonth() + 1;
        var minYear = new Date().getFullYear();
        var $month = $(params.month);
        var $year = $(params.year);

        var month = parseInt($month.val(), 10);
        var year = parseInt($year.val(), 10);

        return (year > minYear) || ((year === minYear) && (month >= minMonth));
    },
    "Your Credit Card Expiration date is invalid."
);

var creditCardStrictPattern = /^((67\d{2})|(4\d{3})|(5[1-5]\d{2})|(6011))(-?\s?\d{4}){3}|(3[4,7])\d{2}-?\s?\d{6}-?\s?\d{5}$/i;

$.validator.addMethod("creditCardStrict", function(value, element, params) {
        var no = value.replace(/-/g, "");
        return this.optional(element) || $.trim(value).length > 0 && creditCardStrictPattern.test(no);
    },
    "Please enter a correct credit card number."
);

})(jQuery);
