﻿window.Rudder = {
    Data: {
        subscribers: {},
        subscribe: function(key, method) {
            if (typeof key == "string" && typeof method == "function") {
                jQuery(this).bind("onRDU" + key, method); //TODO: test for correct context
                if (this.getset(key)) {
                    method.apply(this, [null, key, this.getset(key)]);
                }
            }
        },
        unsubscribe: function(key, method) {
            if (typeof key == "string" && typeof method == "function") {
                jQuery(this).unbind("onRDU" + key, method); //TODO: test for correct context
            }
        },
        getset: function(key, valueorfilter) {//get stored data or set it, multi function
            if (typeof key == "undefined") { return null; } //or throw "provide a key"
            if (typeof valueorfilter == "object" || typeof valueorfilter == "boolean" || typeof valueorfilter == "string" || typeof valueorfilter == "number") {
                jQuery.data(
                    this,
                    key,
                    this.scrub(key, valueorfilter)
                );
                jQuery(this).trigger("onRDU" + key, arguments);
            }
            var result = jQuery.data(this, key);
            if (typeof result != "undefined" && typeof valueorfilter == "function") {
                result = jQuery.grep(result, valueorfilter);
            }
            return result;
        },
        scrub: function(key, value, map) {//map is optional
            if (typeof value != "object") { return value; }
            if (typeof this.scrubbers[key] == "undefined" && typeof map == "undefined") { return value; }
            value = this.scrubbers.complex.apply(this, [value, jQuery.extend(this.scrubbers[key], map)]);
            return value;
        },
        scrubbers: {
            Accounts: {
                BalanceUpdateTime: "datetime"
            },
            Goals: {
                CreateDate: "datetime",
                CompleteDate: "datetime",
                ProjectedCompleteDate: "datetime",
                TargetCompletionDate: "datetime"
            },
            SavingPlans: {
                CreateDate: "datetime",
                DueDate: "datetime",
                DueDate2: "datetime"//,
                //Statements: "Statements" // TURNED OFF BECAUSE THEY AREN'T NEEDED AND ADD TOO MUCH EXTRA PROCESSING
            },
            Statements: {
                DueDate: "datetime"
            },
            SavingsForecast: {
                Goals: "Goals",
                SavingPlans: "SavingPlans"
            },
            datetime: function(v) {
                return typeof v == "string" ? new Date(parseInt(v.substring(6, v.length - 2))) : v;
            },
            complex: function(v, map) {
                var _this = this;
                if (typeof v.length != "undefined") {
                    return jQuery.each(v, function(i, v) { _this.scrubbers.complex.apply(_this, [v, map]); });
                }
                jQuery.each(map, function(p, t) { //p = property, t = property type
                    if (typeof _this.scrubbers[t] == "object") {
                        v[p] = _this.scrubbers.complex.apply(_this, [v[p], _this.scrubbers[t]]);
                    } else {
                        v[p] = _this.scrubbers[t](v[p]);
                    }
                });
                return v;
            }
        }
    },
    Modal: {},
    init: function() {
        if (typeof window.jQuery == "undefined") { return; }
        //VALIDATOR DEFAULTS
        if (jQuery.validator) {
            jQuery.validator.setDefaults({
                showErrors: function(errorMap, errorList) {
                    for (var i = 0; this.errorList[i]; i++) {
                        var error = this.errorList[i];
                        this.settings.highlight && this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass);
                        //                        this.showLabel( error.element, error.message );
                        var el = jQuery(error.element);
                        if (el.parents(".holder-text").length) { el = el.parents(".holder-text"); }
                        el.attr("title", error.message).tooltip({ extraClass: "error" });
                        if (el.attr("type") == "checkbox") {
                            jQuery(el.form).find("label[for=" + el.attr("id") + "]").css("color", "red").attr("title", error.message).tooltip({ extraClass: "error" });
                        }
                    }
                    if (this.errorList.length) {
                        this.toShow = this.toShow.add(this.containers);
                    }
                    //		            if (this.settings.success) {
                    //			            for ( var i = 0; this.successList[i]; i++ ) {
                    //				            this.showLabel( this.successList[i] );
                    //			            }
                    //		            }
                    if (this.settings.unhighlight) {
                        for (var i = 0, elements = this.validElements(); elements[i]; i++) {
                            this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass);
                            var el = jQuery(elements[i]);
                            if (el.parents(".holder-text").length) { el = el.parents(".holder-text"); }
                            el.unbind("mouseover").unbind("mouseout").unbind("click"); //remove error tooltip
                            if (el.attr("type") == "checkbox") {
                                jQuery(el.form).find("label[for=" + el.attr("id") + "]").css("color", "").unbind("mouseover").unbind("mouseout").unbind("click"); //remove error tooltip
                                jQuery("#tooltip").hide();
                            }
                        }
                    }
                    this.toHide = this.toHide.not(this.toShow);
                    this.hideErrors();
                    this.addWrapper(this.toShow).show();
                },
                highlight: function(element, errorClass) {
                    var el = jQuery(element);
                    if (el.parents(".holder-text").length) { el = el.parents(".holder-text"); }
                    el.addClass(errorClass);
                },
                unhighlight: function(element, errorClass) {
                    var el = jQuery(element);
                    if (el.parents(".holder-text").length) { el = el.parents(".holder-text"); }
                    el.removeClass(errorClass);
                }
            });
            jQuery.validator.addMethod("numberc", function(value, element) {
                return this.optional(element) || /^(\d|,)*\.?\d*$/.test(value);
            }, "Please specify a valid amount");
            jQuery.validator.addMethod("simpledate", function(value, element) {
                return this.optional(element) || /^\d{2}\/\d{2}\/\d{4}$/.test(value);
            }, "Please specify a valid date");
        }
        //TEMPLATE DEFAULTS
        if (jQuery.fn.render) {
            jQuery.extend(jQuery.fn.render.defaults, {
                clone: true,
                preserve_template: true,
                formatter: function(k, v, i) {
                    var instructions = i.split("(");
                    instructions[1] = instructions[1].substring(0, instructions[1].length - 1);
                    switch (instructions[0]) {
                        case "CURRENCY":
                            switch (instructions[1]) {
                                case "D":
                                    return FormatCurrency(v, { precision: 0 });
                                    break;
                                case "C":
                                    return FormatCurrency(v);
                                    break;
                            }
                            break;
                        case "NUMBER":
                            switch (instructions[1]) {
                                case "D":
                                    return FormatCurrency(v, { unit: "", precision: 0 });
                                    break;
                                case "C":
                                    return FormatCurrency(v, { unit: "" });
                                    break;
                            }
                            break;
                        case "DATE":
                            return Date.Format(v, instructions[1]);
                            break;
                        case "BOOL":
                            var altvals = instructions[1].split("|");
                            return v ? altvals[0] : altvals[1];
                            break;
                        default:
                            return v;
                            break;
                    }
                }
            });
        }
        jQuery.fn.focused = function(options) {
            var classname = options || "focused"; //allow alternative class
            return this.each(function() {
                jQuery(this)
                    .focus(function() {
                        var el = jQuery(this);
                        if (el.parents(".holder-text").length) { el = el.parents(".holder-text"); }
                        el.addClass(classname);
                    })
                    .blur(function() {
                        var el = jQuery(this);
                        if (el.parents(".holder-text").length) { el = el.parents(".holder-text"); }
                        el.removeClass(classname);
                    });
            });
        };
        jQuery.fn.notextinput = function() {
            return this.each(function() {
                jQuery(this)
                    .keypress(function(e) {
                        var key = e.charCode ? e.charCode : (e.keyCode ? e.keyCode : 0);
                        var allow = false;
                        /*  firefox                      opera */
                        if ((e.ctrlKey && key == 97) || (e.ctrlKey && key == 65)) allow = true; // allow Ctrl+A
                        if ((e.ctrlKey && key == 120) || (e.ctrlKey && key == 88)) allow = true; // allow Ctrl+X (cut)
                        if ((e.ctrlKey && key == 99) || (e.ctrlKey && key == 67)) allow = true; // allow Ctrl+C (copy)
                        // check for other keys that have special purposes

                        if (key == 9 || key == 13) { // tab, enter
                            allow = true;
                        }
                        // for detecting special keys (listed above)
                        // IE does not support 'charCode' and ignores them in keypress anyway
                        else if (typeof e.charCode != "undefined") {
                            // special keys have 'keyCode' and 'which' the same (e.g. backspace)
                            if (e.keyCode == e.which && e.which != 0) {
                                allow = true;
                            }
                            // or keyCode != 0 and 'charCode'/'which' = 0
                            else if (e.keyCode != 0 && e.charCode == 0 && e.which == 0) {
                                allow = true;
                            }
                        }
                        return allow;
                    });
            });
        };
        jQuery.fn.clicktoedit = function(options) {
            options = jQuery.extend(
                {
                    hoverClass: "clicktoedit",
                    useFocusClass: true,
                    useTextHolder: false,
                    editFormatter: null,
                    viewFormatter: null,
                    inputFormatter: null,
                    valueFormatter: null
                },
                options);
            return this.each(function() {
                jQuery(this)
                .css("cursor", "pointer")
                .hover(function() { if (options.hoverClass) { jQuery(this).addClass(options.hoverClass); } },
                    function() { if (options.hoverClass) { jQuery(this).removeClass(options.hoverClass); } })
                .click(function() {
                    var orig = jQuery(this).removeClass(options.hoverClass);
                    var hidden = jQuery("#" + orig.attr("for"));
                    var fieldHTML = "<input " +
                        "type=\"text\" " +
                        "class=\"text" + (options.useFocusClass ? " focused" : "") + "\" " +
                        (options.maxLength ? "maxlength=\"" + options.maxLength + "\" " : "") +
                        "/>";
                    var field = jQuery(fieldHTML).insertAfter(orig.hide());
                    if (options.useTextHolder) { field.wrap('<div class="holder-text" />'); }
                    if (options.inputFormatter) { options.inputFormatter(orig, hidden, field, options); }
                    field
                        .val(options.editFormatter ? options.editFormatter(hidden.val()) : hidden.val())
                        .blur(function() {
                            var newval = options.valueFormatter ? options.valueFormatter(jQuery(this).val()) : jQuery(this).val();
                            if (newval && newval.length) {
                                orig.html(options.viewFormatter ? options.viewFormatter(newval) : newval);
                                hidden.val(newval);
                            }
                            orig.show();
                            if (options.useTextHolder) { field.parent().remove(); } else { field.remove(); }
                        })
                        .focus();
                    return false;
                });
            });
        };
    }
};
window.$RD = function() { return Rudder.Data.getset.apply(Rudder.Data, arguments); }; //Shortcut to data --> $RD("Accounts"), $RD("SavingsForecast")
window.$RM = function() { return Rudder.Modal[arguments[0]]; }; //Shortcut to modals --> $RM("AccountsUpdate"), $RM("SignUp")