﻿if (typeof (ILP)) {
    ILP.widgets = {
        payDateWidget: function (opts) { // jquery plugin
            if (typeof (opts) == 'String' && opts == 'api')
                return $(this).data('payDateWidget');

            var instantiator = function ($el, opts) {
                var self = this;
                self.indicator = $('<div class="ajax-loader-wait"><div></div></div>');

                self.fn = {
                    payFrequency: {
                        lastValue: opts.payFrequency.val || -1,
                        change: function (event) {
                            var $changeEl = $(this);

                            if ($changeEl.val() == self.fn.payFrequency.lastValue || !self.fn.changeIsValid($changeEl)) return;
                            self.fn.payFrequency.lastValue = $changeEl.val();
                            $(opts.payFrequency.container).hide('fast', function () {
                                var params = opts.ajaxData.call($changeEl);
                                $(this).before(self.indicator.hide()).prev('.ajax-loader-wait').show('fast');
                                setTimeout(function () {
                                    $(opts.payFrequency.container).load(opts.payFrequency.url, params, self.fn.payFrequency.loadSuccess);
                                }, 300);
                            });
                            $(opts.payDays.container).hide('fast');
                            self.fn.biWeeklyPayDates.lastValue = self.fn.payDays.lastValue = -1;

                        },
                        loadSuccess: function (response, status, xhr) {
                            $(this).show('fast').prev('.ajax-loader-wait').remove();
                            if (status == "error") return;
                            var $thisFormsEls = $(this).find('input:radio, select')
                                .bind('change keyup', self.fn.payDays.change);

                            if (opts.validationRules) {
                                $thisFormsEls.rules("add", opts.validationRules);
                            }
                        }
                    },
                    payDays: {
                        lastValue: opts.payDays.val || -1,
                        change: function (event) {
                            // debugger;
                            var $changeEl = $(this);
                            var params = opts.ajaxData.call($changeEl);
                            var toggleObect = opts.payDaysChangeIsBiweekly.call(this) ? 'biWeeklyPayDates' : 'payDays';

                            if ($changeEl.val() == self.fn[toggleObect].lastValue || !self.fn.changeIsValid($changeEl)) return;

                            self.fn[toggleObect].lastValue = $changeEl.val();
                            $(opts[toggleObect].container).hide('fast', function () {
                                $(this).before(self.indicator.hide()).prev('.ajax-loader-wait').show('fast');
                                setTimeout(function () {
                                    $(opts[toggleObect].container).load(opts[toggleObect].url, params, self.fn[toggleObect].loadSuccess);
                                }, 300);
                            });
                            $(opts.payDays.container).hide('fast');
                        },
                        loadSuccess: function (response, status, xhr) {
                            $(this).show('fast').prev('.ajax-loader-wait').remove();
                        }
                    },
                    biWeeklyPayDates: {
                        lastValue: opts.biWeeklyPayDates.val || -1,
                        loadSuccess: function (response, status, xhr) {
                            self.fn.payFrequency.loadSuccess.call(this, response, status, xhr)
                        } // biweekly loadSuccess is the same as payFreq loadSuccess
                    },
                    changeIsValid: function ($el) { // rdo's must be checked, selects must have a value
                        return $el.is(':radio:checked') || (($el.children().length > 0) && $el.val() != '');
                    }
                };
                //$(opts.payDays.container).css({ position: 'relative' });
                self.payFrequencyTriggers = $el.find('input:radio')
                    .bind('change keyup', self.fn.payFrequency.change);

                self.payDaysTriggers = $(opts.payFrequency.container).find('input:radio, select')
                    .unbind().bind('change keyup', self.fn.payDays.change);

                if (opts.validationRules) {
                    if (self.payFrequencyTriggers.length) self.payFrequencyTriggers.rules("add", opts.validationRules);
                    if (self.payDaysTriggers.length) self.payDaysTriggers.rules("add", opts.validationRules);
                }

                return self;
            };

            return $(this).each(function () {
                var $el = $(this);
                $el.data('payDateWidget', new instantiator($el, opts));
            });
        },
        ajaxView: function (opts) { // jquery plugin
            if (typeof (opts) == 'String' && opts == 'api')
                return $(this).data('ajaxView');

            var instantiator = function ($el, opts) {
                var self = this;
                self.indicator = $('<div class="ajax-loader-wait"><div></div></div>');
                var lastValue = '';
                self.fn = {
                    change: function (event) {
                        var $changeEl = $(this);
                        if (opts.changeIsValid.call(this) && $changeEl.val() != lastValue) {
                            lastValue = $changeEl.val();
                            // remove event listeners from form elements
                            $(opts.container).find('input, select, textarea').unbind();
                            // TODO: should remove rules added dynamically to the validator also

                            $(opts.container).hide('fast', function () {
                                $(opts.container).before(self.indicator.hide()).prev('.ajax-loader-wait').show('fast');
                                setTimeout(function () {
                                    $(opts.container).load(opts.url, opts.data.call($changeEl), self.fn.loadSuccess);
                                }, 300);
                            });
                            $(opts.container).show();
                        }
                    },
                    loadSuccess: function (response, status, xhr) {
                        $(opts.container).prev('.ajax-loader-wait').remove();
                        if (status == "error") return;

                        var $form = $(this).find('form');
                        if ($form.length) { // render form in view to get model metadata, then remove the form
                            $form.replaceWith($form.children().clone(true));
                            __MVC_AddAjaxFormFields();
                        }

                        $(this).show('fast');
                    }
                };

                self.triggers = $el.bind('change', self.fn.change);


                return self;
            };
            if ($(this).is(':radio')) { // radio is collection, do not create an ajaxView for each button
                var $el = $(this);
                return $el.data('ajaxView', new instantiator($el, opts));
            }
            else {
                return $(this).each(function () {
                    var $el = $(this);
                    $el.data('ajaxView', new instantiator($el, opts));
                });
            }
        },
        ajaxSubmit: function (opts) { // jquery plugin
            if (opts === undefined)
                opts = {};
            else if (typeof (opts) == 'String' && opts == 'api')
                return $(this).data('ajaxSubmit');

            $.extend({ url: '', success: false, data: false }, opts);

            var instantiator = function ($form, opts) {
                var self = this;
                self.$form = $($form);
                self.triggers = opts.triggers || self.$form.find("input, button").filter(':submit, :image').filter(':not(.ajaxIgnore)');
                self.url = opts.url || $form.attr('action');
                self.validator = undefined;
                self.indicator = $('<div class="ajax-loader"/>');
                self.fn = {
                    submit: function (event, fromSelfBind) {
                        if (!fromSelfBind) return false;

                        self.validator = self.$form.data('validator');

                        if ($.fn.autoNumeric) // strip numeric formatting character
                            self.$form.find($.fn.autoNumeric.defaults.className).cleanNumeric();
                        // iovation track (Commented out for wind-down)
                        //var addData = typeof (io_bbout_element_id) !== 'undefined' ? '&' + $('#' + io_bbout_element_id).serialize() : '';
                        if (self.$form.valid()) {// if validation passes
                            if (opts.data) {
                                var data = opts.data.call($form);
                                //data += addData;
                                $.post(self.url, data, self.fn.success);
                            } else {
                                var data = $form.serialize();
                                //data += addData;
                                $.post(self.url, data, self.fn.success);
                            }
                            self.triggers.each(function () {
                                $(this).attr('disabled', true)
                                    .attr('oldSrc', $(this).attr('src'))
                                    .attr('src', '/ExternalContent/Images/common/crawler_pleasewait.png')
                                    .addClass('ajaxProcessing');
                            });
                        }
                        else { // show errors
                            self.validator && self.validator.focusInvalid();
                        }
                        return false;
                    },
                    success: function (result) { // result is json: AjaxSubmitResult
                        self.triggers.each(function () {
                            $(this).attr('disabled', false)
                                .attr('src', $(this).attr('oldSrc'))
                                .removeClass('ajaxProcessing');
                        });

                        if (!result.IsValid && self.validator) { // server errors
                            self.validator.showErrors(result.Errors);
                            self.validator.focusInvalid();
                            return;
                        }
                        // server validation passed code here
                        // process AjaxSubmitResult to
                        // redirect page, process another ajax request, etc
                        if (opts.success)
                            opts.success.call(self, result);
                        else
                            ILP.util.tryProcessJsonActionResult(result);
                    }
                };
                function submitHandler(e) {
                    e.preventDefault()
                    self.fn.submit(e, true);
                    return false;
                }
                self.triggers.unbind('click').click(submitHandler);
                self.$form.unbind('submit').submit(submitHandler);
                return self;
            };

            return $(this).each(function () {
                var $form = $(this);
                if ($($form[0]).is('form')) {
                    $form.data('ajaxSubmit', new instantiator($form, opts));
                }
            });
        },
        clearForm: function (opts) {
            if (opts === undefined)
                opts = {};
            else if (typeof (opts) == 'String' && opts == 'api')
                return $(this).data('clearForm');

            //$.extend({ url: '', success: false, data: false }, opts);

            var instantiator = function ($form, opts) {
                var self = this;
                self.clear = function () {
                    $form.find(':input').each(function () {
                        switch (this.type) {
                            case 'password':
                            case 'select-multiple':
                            case 'select-one':
                            case 'text':
                            case 'textarea':
                                $(this).val('');
                                break;
                            case 'checkbox':
                            case 'radio':
                                this.checked = false;
                        }
                    });
                }

                self.clear();

                return self;
            };

            return $(this).each(function () {
                var $form = $(this);
                if ($($form[0]).is('form')) {
                    $form.data('clearForm', new instantiator($form, opts));
                }
            });
        },
        loadFancy: function (opts) {
            $.extend({
                url: '',
                success: false,
                data: false,
                validate: true,
                addForm: true,
                extendForm: false
            }, opts);

            var instantiator = function ($el, opts) {

                var self = this;
                self.indicator = $('<div class="ajax-loader"/>');
                self.load = function () {
                    $el.hide('fast', function () {
                        $el.before(self.indicator.hide()).prev('.ajax-loader').show('fast');
                        setTimeout(function () {
                            $el.load(opts.url, opts.data, self.success);
                        }, 300);
                    });
                };
                self.success = function (response, status) {
                    $el.prev('.ajax-loader').remove();
                    if (status == "error") return;
                    else if (status == 'success') {
                        $el.show('fast');
                        if (opts.validate && opts.addForm)
                            __MVC_AjaxFormLoad();
                        else if (opts.validate && opts.extendForm) {
                            var $form = $(this).find('form');
                            if ($form.length) { // render form in view to get model metadata, then remove the form
                                $form.replaceWith($form.children().clone(true));
                                __MVC_AddAjaxFormFields();
                            }
                        }
                        if (opts.success)
                            opts.success.call(this, response, status);
                    }
                }

                self.load();

                return self;
            };

            return $(this).each(function () {
                var $el = $(this);
                $el.data('loadFancy', new instantiator($el, opts));

            });
        },
        cleanNumeric: function (options) {
            return this.each(function () {// iterate and reformat each matched element
                var $el = $(this);
                if ($el.val() !== '')
                    $el.val($.fn.autoNumeric.Strip($el.attr('id')));
            });
        }
    }
}
