//incase dev leaves in console.log, it wont break IE
if (typeof console === 'undefined') var console = { log: function () { } };

/* Global JS for all Shuls sites */
try {
    if (Event.observe) {
        Event.observe(window, 'load', function () {
            try {
                $$('a.icon_popup').each(function (el) {
                    el.tabIndex = 9;
                });
            } catch (e) { } // do nothing
        });
    }
} catch (e) { }

if (fb_app_id !== '') {
    window.fbAsyncInit = function () {
        FB.init({
            appId: fb_app_id, // App ID
            channelUrl: '/facebook_channel.php', // Channel File
            status: true,
            cookie: true,
            xfbml: true
        });
    };
}

(function (d, s, id) {
    var js,
        fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = '//connect.facebook.net/en_US/all.js#xfbml=1';
    fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');

$j(function ($) {
    // jQuery onReady function

    setTimeout(function () {
        $j('.autocomplete_fix').each(function () {
            $j(this).removeAttr("readonly");
        });
    }, 500);

    $j(document).on("click", ".autocomplete_fix", function () { $(this).removeAttr("readonly"); });

    // calendar popup fix for relative positioning
    $('.popup_calendar_div').each(function () {
        $(this).appendTo('body');
    });

    //something in transactions
    $j('.txs-func tbody:not(.sub_tx):not(:first):not(:last) tr').each(function () {
        var $this = $j(this);
        var $that = $this;
        $this.css({
            'font-weight': '700'
        });
        /*  .hover(function (e) {
                $(this).css('filter',e.type === 'mouseenter'?"brightness(90%)":'none');
            });*/
        $this.find('.tx_anchor').click(function () {
            var $this = $that;
            var sub_tx_tbody = $this.parent().next('tbody.sub_tx');

            $j('.notes', this).toggle();
            sub_tx_tbody
                .css(
                    'background',
                    'linear-gradient(to bottom, rgb(150,150,150) 0%, rgb(231,231,231) 10%, rgb(231,231,231) 98%, rgb(200,200,200) 100%)'
                )
                .find('td')
                .css({
                    background: 'inherit'
                })
                .end()
                .toggle('fast');

            $j(this).toggleClass('tx_anchor_expanded');
            if ($j(this).hasClass('tx_anchor_expanded')) {
                $j(this).html('<i class="fa fa-chevron-up" aria-hidden="true"></i>');
            } else {
                $j(this).html('<i class="fa fa-chevron-down" aria-hidden="true"></i>');
            }
            return false;
        });
    });

    if ($('.has_facebook_included').length > 0) {
        //force the width
        $('.fb-like-box').attr(
            'data-width',
            $('.fb-like-box')
                .parents('.content_body')
                .width()
        );
    }

    //ie check
    var rootFolder = window.location.pathname.substring(1, window.location.pathname.indexOf('/', 1)).toLowerCase();
    if ((rootFolder === 'admin' || window.IEReject) && $j.reject) {
        var rejectOptions = {
            reject: {
                all: false, // Covers Everything (Nothing blocked)
                msie: true // Covers MSIE 5-6 (Blocked by default)
            },
            beforeReject: function () {
                if (isIE11()) {
                    this.reject = { all: true };
                }
            },
            closeCookie: true, // Set cookie to reember close for this session
            imagePath: '/pics/jquery_reject/',
            display: ['firefox', 'chrome'],
            browserInfo: {
                // Settings for which browsers to display
                firefox: {
                    text: 'Firefox', // Text below the icon
                    url: 'http://getfirefox.com' // URL For icon/text link
                },
                chrome: {
                    text: 'Chrome',
                    url: 'http://www.google.com/chrome/'
                }
            },
            header: 'Administrator functions are not fully supported on your browser',
            paragraph1: 'Please use one of the browsers listed below.',
            paragraph2: 'You can click on the icons below to go to the download page.',
            closeMessage: '',
            closeLink: 'I\'ll take my chances'
        };
        if (window.IEReject) {
            $.extend(rejectOptions, IEReject);
        }
        $j.reject(rejectOptions);
    }

    if (fb_app_id !== '') {
        $(document).on('click', '.fb_connect', function () {
            FB.login(
                function (response) {
                    if (response.status === 'connected') {
                        document.location =
                            '/login.php?connect_facebook=true&url=' + encodeURIComponent(document.location.href);
                    }
                },
                { scope: 'email,user_birthday,publish_actions,rsvp_event' }
            );
        });

        $(document).on('click', '.fb_login', function () {
            FB.login(
                function (response) {
                    if (response.status === 'connected') {
                        document.location = facebook_login_url;
                    }
                },
                { scope: 'email' }
            );
        });
    }

    $(document).on('click', '.google_login', function () {
        document.location = google_login_url;
    });

    menu_open = false;
    menus = ['login', 'help', 'admin_menu'];
    for (var abc = 0; abc < 3; abc++) {
        (function (abc) {
            $(document).on('click', '#header_' + menus[abc] + '_button', function () {
                var name = menus[abc];
                if ($('#header_' + menus[abc] + '_menu').is(':visible')) {
                    $('#header_' + menus[abc] + '_menu').hide();
                    menu_open = false;
                    $('#header_' + menus[abc] + '_button').removeClass('header_button_open');
                } else {
                    if (menu_open) menu_open.hide();
                    $('.header_button').removeClass('header_button_open');
                    menu_open = $('#header_' + menus[abc] + '_menu')
                        .show()
                        .position({
                            my: 'right top',
                            at: 'right bottom-1',
                            of: $('#header_' + menus[abc] + '_button')
                        });
                    $('#header_' + menus[abc] + '_button').addClass('header_button_open');
                }
            });
        })(abc);
    }
    //make tooltips
    if ($j.tooltip) {
        $j('#header_admin_menu_menu ul').tooltip({
            position: {
                my: 'center top+10',
                at: 'right+20 bottom',
                using: function (position, feedback) {
                    $(this)
                        .css(position)
                        .addClass('header_menu_tooltip');
                }
            }
        });
    }

    $j.cachedScript = function( url, options ) {
        // Allow user to set any option except for dataType, cache, and url
        options = $.extend( options || {}, {
            dataType: "script",
            cache: true,
            url: url
        });

        // Use $.ajax() since it is more flexible than $.getScript
        // Return the jqXHR object so we can chain callbacks
        return jQuery.ajax( options );
    };

    $j(function () {
        $j(document).on('keydown.autocomplete', '.account_name_autocomplete', function () {
            $j(this)
                .autocomplete({
                    source: '/admin/ajax.user_autocomplete.php?type=accounts',
                    minLength: 2,
                    select: function (event, ui) {
                        $parent = $j(this).parent('.account_name_autocomplete_area');
                        if (ui.item) {
                            saved_attr = ui.item.label;
                            $parent.find('.account_name_hidden_id').attr('hidden_name', ui.item.label);
                            $parent.find('.account_name_hidden_id').val(ui.item.id);
                            $parent.find('.account_name_autocomplete').val(ui.item.label);
                            $parent.find('.account_name_minus_1_checkbox').prop('checked', false);
                            $parent.find('.account_name_hidden_id').change();
                            $parent.find('.account_name_none_selected').hide();
                        }
                        return false;
                    }
                })
                .bind('keypress', function (e) {
                    if (13 === e.keyCode) {
                        return false;
                    }
                })
                .change(function () {
                    $parent = $j(this).parent('.account_name_autocomplete_area');

                    if ($parent.find('.account_name_hidden_id').attr('hidden_name') !== $j(this).val()) {
                        $parent.find('.account_name_none_selected').show();
                        $parent.find('.account_name_hidden_id').val(0);
                    }
                    return false;
                });
        });
        $j(document).on('click', '.account_name_minus_1_checkbox', function () {
            $parent = $j(this).closest('.account_name_autocomplete_area');

            $parent.find('.account_name_hidden_id').attr('hidden_name', '');
            $parent.find('.account_name_autocomplete').val('');
            $parent.find('.account_name_none_selected').show();
            if ($j(this).prop('checked')) {
                $parent.find('.account_name_hidden_id').val(-1);
            } else {
                $parent.find('.account_name_hidden_id').val(0);
            }
            $parent.find('.account_name_hidden_id').change();
        });

        $j('body').on('click', '.delete-button', function () {
            var msg = 'Are you sure you want to remove this file?';
            if (!window.confirm(msg)) {
                return false;
            }

            var anchor = $(this);
            var href = anchor.attr('href');
            var isDownloadList = anchor.closest('.private-download-list').length > 0;
            var uploader, downloader, file, row;

            // if we found a row that means we're in the downloader
            // then we need to find the file in the uploader so we can remove it too
            if (isDownloadList) {
                row = anchor.closest('tr');
                downloader = anchor.closest('.private-download-list');

                var id = downloader.attr('id').replace(/[a-zA-Z]/gi, '');
                uploader = $j('#scupload' + id);

                file = uploader.find('a[href="' + href + '"]').closest('.dz-preview');
            }
            // since we found no row we're in the uploader
            // then we need to find the file in the downloader so we can remove it too
            else {
                uploader = anchor.closest('.dropzone');

                var id = uploader.attr('id').replace(/[a-zA-Z]/gi, '');
                downloader = $j('#scdownload' + id);

                row = downloader.find('a[href="' + href + '"]').closest('tr');
                file = anchor.closest('.dz-preview');
            }

            $j.post(
                href,
                {
                    is_compact: downloader.closest('.is-compact').length > 0 ? 1 : 0
                },
                function () {
                    if (file) {
                        file.fadeOut(function () {
                            file.remove();

                            // if we have no files then reset the dropzone
                            if (!$('.dropzone .dz-preview').length) {
                                Dropzone.forElement('#' + uploader.attr('id')).emit('reset');
                            }
                        });
                    }
                    if (row) {
                        row.fadeOut(function () {
                            row.remove();
                        });
                    }
                }
            );

            return false;
        });
    });

    // shortcut hotkeys for admins

    if ($j('#header_admin_menu_menu').length) {
        if ($j('#header_admin_menu_menu').find('a[href*="/admin/transaction_add.php"]').length !== 0) {
            $j(document).bind('keydown', 'alt+t', function () {
                window.location.href = '/admin/transaction_add.php';
            });
        }
    }

    //When user clicks Escape key, close out admin screen, help screen and login screen
    document.onkeydown = function (evt) {
        evt = evt || window.event;
        var isEscape = false;
        if ("key" in evt) {
            isEscape = (evt.key === "Escape" || evt.key === "Esc");
        } else {
            isEscape = (evt.keyCode === 27);
        }
        if (isEscape) {
            $j('#header_admin_menu_menu').hide();
            $j('#header_login_menu').hide();
            $j('#header_help_menu').hide();
        }
    };

    $j(document).on('change', '.custom_gender_select', function () {
        if ($j(this).val() == 'custom') {
            $j(this)
                .next('.custom_gender_options')
                .css('display', 'inline');
        } else {
            $j(this)
                .next('.custom_gender_options')
                .hide();
        }
    });
});

function isIE() {
    var myNav = navigator.userAgent.toLowerCase();
    return myNav.indexOf('msie') != -1 ? parseInt(myNav.split('msie')[1]) : false;
}

function refreshPrivateFilesDownloadList(uploader, args) {
    var id = uploader.attr('id').replace(/[a-zA-Z]/gi, '');
    var downloader = uploader.siblings('#scdownload' + id);

    if (!downloader.length) {
        return false;
    }

    $j.get(
        '/admin/ajax.private_files.php',
        {
            action: 'view_download_list',
            args: args,
            is_compact: downloader.hasClass('is-compact') ? 1 : 0,
            id: id
        },
        function (response) {
            downloader.html(response);
        }
    );
}
function decorateFilePreview(file, file_id, args) {
    var closeBtn = $j('<a>delete x</a>')
        .addClass('delete-button')
        .attr('style', 'font-size:14px;color:red;display:block;')
        .attr('href', '/admin/ajax.private_files.php?action=delete_private_file&file_id=' + file_id);
    var downloadBtn = $j('<a target="_blank">download ↓</a>')
        .addClass('private_download_link')
        .attr('data-file-id', file_id)
        .attr('style', 'font-size:14px;color:black;display:block;')
        .attr('href', '/admin/ajax.private_files.php?action=download&file_id=' + file_id);

    $j('.dz-filename span').each(function () {
        var target = $j(this);

        if (target.text() == cleanFileName(file.name)) {
            target
                .closest('.dz-details')
                .append(downloadBtn)
                .append(closeBtn);

            return false;
        }
    });
}

function cleanFileName(filename) {
    return filename.replace(/[`'"]/g, '');
}

function handlePrivateFileUpload(uploader, xmlinfo, args, file) {
    $j.ajax({
        url: '/admin/ajax.private_files.php',
        type: 'POST',
        data: {
            xmlinfo: xmlinfo,
            args: args,
            action: 'upload'
        },
        dataType: 'json',
        success: function (response) {
            if (response.success) {
                var file_id = response.file_id;
                if (file_id) {
                    decorateFilePreview(file, file_id, args);
                }

                refreshPrivateFilesDownloadList(uploader, args);
            } else {
                window.alert(response.msg || 'There was an unknown error. Please retry.');
            }
        },
        error: function () {
            window.alert('There was an error uploading the file. Please retry.');
        }
    });
}

function _getElement(id) {
    if (document.getElementById && document.getElementById(id)) {
        return document.getElementById(id);
    } else if (document.all && document.all[id]) {
        return document.all[id];
    } else {
        return false;
    }
}

function toggleBlock(id) {
    if (_getElement(id)) {
        if (_getElement(id).style.display == 'none') {
            _getElement(id).style.display = 'block';
        } else {
            _getElement(id).style.display = 'none';
        }
    }
}

var $login_menu;

/*
 * Detects support for HTML 5 placeholders and provides a jQuery fallback for "faking" placeholders
 * Author: Jack Franklin
 * Credit: Idea taken from looking at code on http://procssforhightrafficwebsites.com/code/index.html
 */
$j(document).ready(function () {
    (function ($) {
        $(function () {
            if (!('placeholder' in document.createElement('input'))) {
                //don't do any work if we don't have to!
                var inputs = $('input[type="text"][placeholder]');
                var origColour = inputs.eq(0).css('color');

                inputs
                    .each(function (i) {
                        var $t = $(this);
                        if ($t.val() === '') {
                            $t.val($t.attr('placeholder')).css('color', '#585858');
                        }
                    })
                    .focus(function () {
                        var $t = $(this);
                        if ($t.val() === $t.attr('placeholder')) $t.val('').css('color', origColour);
                    })
                    .blur(function () {
                        var $t = $(this);
                        if ($t.val() === '') {
                            $t.val($t.attr('placeholder')).css('color', '#585858');
                        }
                    });
                var $password_fields = $('input[type="password"][placeholder]');
                origColour = $password_fields.eq(0).css('color');

                $password_fields
                    .each(function (i) {
                        var $t = $(this);

                        $copy = $('<input type="text">')
                            .val($t.attr('placeholder'))
                            .css('color', '#585858')
                            .hide()
                            .focus(function () {
                                $copy.hide();
                                $t.show().focus();
                            });
                        $t.after($copy);
                        $t.data('placeholder', $copy);
                        if ($t.val() === '') {
                            $t.hide();
                            $copy.show();
                        }
                    })
                    .blur(function () {
                        var $t = $(this);
                        if ($t.val() === '') {
                            $copy = $t.data('placeholder');
                            $copy.show();
                            $t.hide();
                        }
                    });
            }
        });
    })(jQuery);

    //person hover.
    $j(document).on('click', '.person_hover', function () {
        var person_id = $j(this).attr('p_id');
        var $div = $j('<div/>').load('/admin/person.php?action=ajax&id=' + person_id, function () {
            var $h1 = $div.find('h1');
            $h1.remove();
            $div.dialog({
                width: 500,
                modal: true,
                title: $h1.html(),
                open: function () {
                    //close when i click anywhere.
                    $j('.ui-widget-overlay').bind('click', function () {
                        $div.dialog('close');
                    });
                }
            });
        });
        return false;
    });

    $j('DIV.rbad').each(function () {
        var div = $j(this);
        var neturl =
            '/network.php?id=' +
            div.data('id') +
            '&si=' +
            div.data('si') +
            '&k=' +
            div.data('k') +
            '&s=' +
            div.data('s') +
            '&d=' +
            div.data('d') +
            '&p=' +
            div.data('p') +
            '&coa=' +
            div.data('coa') +
            '&c=' +
            div.data('c');
        $j.ajax({
            url: neturl,
            cache: false
        }).success(function (html) {
            div.html(html);
            $j(window).trigger('resize');
        });
    });
});

function conferencePopup(is_live) {
    var url = is_live
        ? 'https://plus.google.com/events/cmiml9i533tprfikscgpfat43n4'
        : 'https://www.shulcloud.com/conference';
    var pic = is_live
        ? 'http://images.shulcloud.com/shuls/74703/Jan-2016-ShulCloud-Conference-Email-r3-live.png'
        : 'http://images.shulcloud.com/shuls/74703/Jan-2016-ShulCloud-Conference-Email-r3.png';
    var title = 'January 2016 Conference';
    var btn = is_live ? 'Participate Now' : 'RSVP Now';

    $j(function () {
        //
        $j('body').append(
            $j(
                '<div id="conference-dialog-message" style="text-align:left">' +
                '<a href="' +
                url +
                '" target="_blank">' +
                '<img border="0" width="550" src="' +
                pic +
                '"/>' +
                '</a>' +
                '</div>'
            )
        );
        $j('#conference-dialog-message').dialog({
            modal: true,
            width: 590,
            title: title,
            position: { my: 'center', at: 'center top', of: window },
            buttons: [
                {
                    text: btn,
                    click: function () {
                        $j(this).dialog('close');
                        var win = window.open(url, '_blank');
                        win.focus();
                    }
                },
                {
                    text: 'Close',
                    click: function () {
                        $j(this).dialog('close');
                        $j('#conference-dialog-message').remove();
                    }
                }
            ]
        });
    });
}

function setPointer(theRow, classn) {
    if (typeof theRow.style === 'undefined') {
        return false;
    }
    theRow.className = classn;
    return true;
}

function sure() {
    return confirm('Are you sure you would like to remove this?');
}

/*
Javascript popup window
By Michael Butler 07/01/09

Usage:
to auto generate the popup window, simply include this script and add this click handler:
onclick="return Popup.display('Hello World',this)"
to use an existing div as the popup (the div must have 3 divs beneath it)
onclick="return Popup.display('Hello World',this,'Div_Id')"
*/

var Popup = {};

Popup.display = function (theText, clickedEl, divId, iWidth) {
    var inserted = null;

    if (!divId) {
        divId = 'myPopup';
    }
    var oDiv = $(divId);
    if (!oDiv) {
        oDiv = this.insertDiv();
        inserted = true;
    }
    if (!oDiv) {
        alert('Div not found.');
        return false;
    }

    if (!oDiv.hasClassName('styled')) {
        this.styleDiv(oDiv);
        oDiv.addClassName('styled');
    }

    if (iWidth) {
        oDiv.style.width = '' + iWidth + 'px';
    }

    oDiv.show();
    this.moveDiv(oDiv, clickedEl);

    var children = oDiv.childElements();

    children[1].update(theText);

    Event.observe(children[0].down(), 'click', function (e) {
        var el = Event.element(e);
        el.up()
            .up()
            .fade({ duration: 0.5 });
    });

    if (!this.dragg) {
        new Draggable(divId, { handle: 'hd' });
        this.dragg = true;
    }

    if (inserted) {
        this.moveDiv(oDiv, clickedEl);
    }

    return false;
};

Popup.moveDiv = function (oDiv, clickedEl) {
    var loc = this.findPos(clickedEl);

    oDiv.style.position = 'absolute';

    var dimen = oDiv.getDimensions();
    var wdimen = document.viewport.getDimensions();
    var offset = document.viewport.getScrollOffsets();
    var offsety = offset.top;
    var w;
    var h;

    if (typeof window.innerWidth === 'number') {
        //Non-IE
        w = window.innerWidth;
        h = window.innerHeight;
    } else if (
        document.documentElement &&
        (document.documentElement.clientWidth || document.documentElement.clientHeight)
    ) {
        //IE 6+ in 'standards compliant mode'
        w = document.documentElement.clientWidth;
        h = document.documentElement.clientHeight;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        w = document.body.clientWidth;
        h = document.body.clientHeight;
    }

    //	console.log("loc[1] " + loc[1]);
    //	console.log("offsety " + offsety);
    //	console.log("h " + h);
    //	console.log("dimen.height " + dimen.height);
    //
    if (loc[0] > w / 2) {
        oDiv.style.left = '' + (loc[0] - dimen.width) + 'px';
    } else {
        oDiv.style.left = '' + (loc[0] + 16) + 'px';
    }
    if (loc[1] - offsety > h / 2) {
        oDiv.style.top = '' + (loc[1] - dimen.height) + 'px';
    } else {
        oDiv.style.top = '' + (loc[1] + 10) + 'px';
    }
};

Popup.styleDiv = function (oDiv, clickedEl) {
    oDiv.style.position = 'absolute';
    oDiv.style.margin = 0;
};

Popup.insertDiv = function () {
    var html =
        '<div id="myPopup" style="display:none;"><div class="hd"><div class="close">&times;</div></div><div class="bd"></div><div class="ft"></div></div>';
    var n = $(window.document.body);
    var newN = n.insert(html);
    return $('myPopup');
};

Popup.findPos = function (obj) {
    var curleft = (curtop = 0);
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while ((obj = obj.offsetParent));
    } else {
        curleft = 20;
        curtop = 20;
    }

    return [curleft, curtop];
};

var toggleStyles = function () {
    var linkTag = $('id_template_css');
    var adminLinkTag = $('id_admin_css');
    if (linkTag.href == '#') {
        linkTag.href = linkTag.readAttribute('altval');
    } else {
        linkTag.writeAttribute('altval', linkTag.href);
        linkTag.href = '#';
    }

    if (adminLinkTag) {
        adminLinkTag.href = '';
    }
};

function showPhotoGallerySearch() {
    $('gallery_sort').style.display = 'none';
    //$('gallery_search').style.display="";
    Effect.SlideDown('gallery_search_a');
}

function showPhotoGallerySort(test) {
    //$('gallery_sort').style.display="";
    if (test) {
        $('gallery_search_a').style.display = 'none';
        Effect.SlideDown('gallery_search_a');
    } else {
        $('gallery_search_a').style.display = 'none';
        Effect.SlideDown('gallery_sort');
    }
}

function closeSortTab() {
    //$('gallery_sort').style.display="none";
    Effect.SlideUp('gallery_sort');
}

function closeSearchTab() {
    //$('gallery_search').style.display="none";
    Effect.SlideUp('gallery_search_a');
}

function selectSelectByValue(select, val) {
    for (var i = 0; i < select.options.length; i++) {
        if (select.options[i].value == val) {
            select.selectedIndex = i;
            return;
        }
    }
}

function hebrewDateFromEnglish(frm, input_name_eng, input_heb_name) {
    var $eng = $j("input[name='info[dob]']");
    if (input_name_eng) $eng = $j('input[name=\'' + input_name_eng + '\']');
    var $heb = $j("input[name='info[hebrew_dob]']");
    if (input_heb_name) $heb = $j('input[name=\'' + input_heb_name + '\']');

    var dataStr = 'date=' + $eng.val();

    if (frm['info[after_sunset]']) {
        dataStr = dataStr + '&after_sunset=' + frm['info[after_sunset]'].value;
        dontShowAlert = true;
    }

    $j.ajax({
        url: '/ajax/site_member_secular_to_jewish_date.php',
        data: dataStr,
        dataType: 'json',
        success: function (data) {
            $heb.val(data.year + '-' + data.month + '-' + data.day);
            var heb_id = $heb.attr('id');
            $j("select[id='" + heb_id.replace('id_', 'hday_') + "']").val(data.day);
            $j("select[id='" + heb_id.replace('id_', 'hmonth_') + "']").val(data.month);
            $j("select[id='" + heb_id.replace('id_', 'hyear_') + "']").val(data.year);
        }
    });
}
function strtotime(str, now) {
    // http://kevin.vanzonneveld.net
    // +   original by: Caio Ariede (http://caioariede.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: David
    // +   improved by: Caio Ariede (http://caioariede.com)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Wagner B. Soares
    // +   bugfixed by: Artur Tchernychev
    // %        note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
    // *     example 1: strtotime('+1 day', 1129633200);
    // *     returns 1: 1129719600
    // *     example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
    // *     returns 2: 1130425202
    // *     example 3: strtotime('last month', 1129633200);
    // *     returns 3: 1127041200
    // *     example 4: strtotime('2009-05-04 08:30:00');
    // *     returns 4: 1241418600

    var i,
        match,
        s,
        strTmp = '',
        parse = '';

    strTmp = str;
    strTmp = strTmp.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
    strTmp = strTmp.replace(/[\t\r\n]/g, ''); // unecessary chars

    if (strTmp == 'now') {
        return new Date().getTime() / 1000; // Return seconds, not milli-seconds
    } else if (!isNaN((parse = Date.parse(strTmp)))) {
        return parse / 1000;
    } else if (now) {
        now = new Date(now * 1000); // Accept PHP-style seconds
    } else {
        now = new Date();
    }

    strTmp = strTmp.toLowerCase();

    var __is = {
        day: {
            sun: 0,
            mon: 1,
            tue: 2,
            wed: 3,
            thu: 4,
            fri: 5,
            sat: 6
        },
        mon: {
            jan: 0,
            feb: 1,
            mar: 2,
            apr: 3,
            may: 4,
            jun: 5,
            jul: 6,
            aug: 7,
            sep: 8,
            oct: 9,
            nov: 10,
            dec: 11
        }
    };

    var process = function (m) {
        var ago = m[2] && m[2] == 'ago';
        var num = (num = m[0] == 'last' ? -1 : 1) * (ago ? -1 : 1);

        switch (m[0]) {
            case 'last':
            case 'next':
                switch (m[1].substring(0, 3)) {
                    case 'yea':
                        now.setFullYear(now.getFullYear() + num);
                        break;
                    case 'mon':
                        now.setMonth(now.getMonth() + num);
                        break;
                    case 'wee':
                        now.setDate(now.getDate() + num * 7);
                        break;
                    case 'day':
                        now.setDate(now.getDate() + num);
                        break;
                    case 'hou':
                        now.setHours(now.getHours() + num);
                        break;
                    case 'min':
                        now.setMinutes(now.getMinutes() + num);
                        break;
                    case 'sec':
                        now.setSeconds(now.getSeconds() + num);
                        break;
                    default:
                        var day;
                        if (typeof (day = __is.day[m[1].substring(0, 3)]) !== 'undefined') {
                            var diff = day - now.getDay();
                            if (diff == 0) {
                                diff = 7 * num;
                            } else if (diff > 0) {
                                if (m[0] == 'last') {
                                    diff -= 7;
                                }
                            } else {
                                if (m[0] == 'next') {
                                    diff += 7;
                                }
                            }
                            now.setDate(now.getDate() + diff);
                        }
                }
                break;

            default:
                if (/\d+/.test(m[0])) {
                    num *= parseInt(m[0], 10);

                    switch (m[1].substring(0, 3)) {
                        case 'yea':
                            now.setFullYear(now.getFullYear() + num);
                            break;
                        case 'mon':
                            now.setMonth(now.getMonth() + num);
                            break;
                        case 'wee':
                            now.setDate(now.getDate() + num * 7);
                            break;
                        case 'day':
                            now.setDate(now.getDate() + num);
                            break;
                        case 'hou':
                            now.setHours(now.getHours() + num);
                            break;
                        case 'min':
                            now.setMinutes(now.getMinutes() + num);
                            break;
                        case 'sec':
                            now.setSeconds(now.getSeconds() + num);
                            break;
                    }
                } else {
                    return false;
                }
                break;
        }
        return true;
    };

    match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
    if (match != null) {
        if (!match[2]) {
            match[2] = '00:00:00';
        } else if (!match[3]) {
            match[2] += ':00';
        }

        s = match[1].split(/-/g);

        for (i in __is.mon) {
            if (__is.mon[i] == s[1] - 1) {
                s[1] = i;
            }
        }
        s[0] = parseInt(s[0], 10);

        s[0] =
            s[0] >= 0 && s[0] <= 69
                ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '')
                : s[0] >= 70 && s[0] <= 99
                    ? '19' + s[0]
                    : s[0] + '';
        return parseInt(
            this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''),
            10
        );
    }

    var regex =
        '([+-]?\\d+\\s' +
        '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' +
        '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' +
        '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' +
        '|(last|next)\\s' +
        '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' +
        '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' +
        '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' +
        '(\\sago)?';

    match = strTmp.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
    if (match == null) {
        return false;
    }

    for (i = 0; i < match.length; i++) {
        if (!process(match[i].split(' '))) {
            return false;
        }
    }

    return now.getTime() / 1000;
}

function date(format, timestamp) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: MeEtc (http://yass.meetcweb.com)
    // +   improved by: Brad Touesnard
    // +   improved by: Tim Wiel
    // +   improved by: Bryan Elliott
    //
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: David Randall
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +  derived from: gettimeofday
    // +      input by: majak
    // +   bugfixed by: majak
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Alex
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Thomas Beaucourt (http://www.webapp.fr)
    // +   improved by: JT
    // +   improved by: Theriault
    // +   improved by: RafaÃ…â€š Kukawski (http://blog.kukawski.pl)
    // %        note 1: Uses global: php_js to store the default timezone
    // %        note 2: Although the function potentially allows timezone info (see notes), it currently does not set
    // %        note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
    // %        note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
    // %        note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
    // *     example 3: date('Y W o', 1062462400);
    // *     returns 3: '2003 36 2003'
    // *     example 4: x = date('Y m d', (new Date()).getTime()/1000);
    // *     example 4: (x+'').length == 10 // 2009 01 09
    // *     returns 4: true
    // *     example 5: date('W', 1104534000);
    // *     returns 5: '53'
    // *     example 6: date('B t', 1104534000);
    // *     returns 6: '999 31'
    // *     example 7: date('W U', 1293750000.82); // 2010-12-31
    // *     returns 7: '52 1293750000'
    // *     example 8: date('W', 1293836400); // 2011-01-01
    // *     returns 8: '52'
    // *     example 9: date('W Y-m-d', 1293974054); // 2011-01-02
    // *     returns 9: '52 2011-01-02'
    var that = this,
        jsdate,
        f,
        formatChr = /\\?([a-z])/gi,
        formatChrCb,
        // Keep this here (works, but for code commented-out
        // below for file size reasons)
        //, tal= [],
        _pad = function (n, c) {
            if ((n = n + '').length < c) {
                return new Array(++c - n.length).join('0') + n;
            } else {
                return n;
            }
        },
        txt_words = [
            'Sun',
            'Mon',
            'Tues',
            'Wednes',
            'Thurs',
            'Fri',
            'Satur',
            'January',
            'February',
            'March',
            'April',
            'May',
            'June',
            'July',
            'August',
            'September',
            'October',
            'November',
            'December'
        ],
        txt_ordin = {
            1: 'st',
            2: 'nd',
            3: 'rd',
            21: 'st',
            22: 'nd',
            23: 'rd',
            31: 'st'
        };
    formatChrCb = function (t, s) {
        return f[t] ? f[t]() : s;
    };
    f = {
        // Day
        d: function () {
            // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function () {
            // Shorthand day name; Mon...Sun
            return f.l().slice(0, 3);
        },
        j: function () {
            // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function () {
            // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function () {
            // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function () {
            // Ordinal suffix for day of month; st, nd, rd, th
            return txt_ordin[f.j()] || 'th';
        },
        w: function () {
            // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function () {
            // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j()),
                b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5) + 1;
        },

        // Week
        W: function () {
            // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
                b = new Date(a.getFullYear(), 0, 4);
            return 1 + Math.round((a - b) / 864e5 / 7);
        },

        // Month
        F: function () {
            // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function () {
            // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function () {
            // Shorthand month name; Jan...Dec
            return f.F().slice(0, 3);
        },
        n: function () {
            // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function () {
            // Days in month; 28...31
            return new Date(f.Y(), f.n(), 0).getDate();
        },

        // Year
        L: function () {
            // Is leap year?; 0 or 1
            return (new Date(f.Y(), 1, 29).getMonth() === 1) | 0;
        },
        o: function () {
            // ISO-8601 year
            var n = f.n(),
                W = f.W(),
                Y = f.Y();
            return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
        },
        Y: function () {
            // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function () {
            // Last two digits of year; 00...99
            return (f.Y() + '').slice(-2);
        },

        // Time
        a: function () {
            // am or pm
            return jsdate.getHours() > 11 ? 'pm' : 'am';
        },
        A: function () {
            // AM or PM
            return f.a().toUpperCase();
        },
        B: function () {
            // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2, // Hours
                i = jsdate.getUTCMinutes() * 60, // Minutes
                s = jsdate.getUTCSeconds(); // Seconds
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function () {
            // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function () {
            // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function () {
            // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function () {
            // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function () {
            // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function () {
            // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function () {
            // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },

        // Timezone
        e: function () {
            // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
            /*              return this.date_default_timezone_get();
             */
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function () {
            // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0), // Jan 1
                c = Date.UTC(f.Y(), 0), // Jan 1 UTC
                b = new Date(f.Y(), 6), // Jul 1
                d = Date.UTC(f.Y(), 6); // Jul 1 UTC
            return 0 + (a - c !== b - d);
        },
        O: function () {
            // Difference to GMT in hour format; e.g. +0200
            var a = jsdate.getTimezoneOffset();
            return (a > 0 ? '-' : '+') + _pad(Math.abs((a / 60) * 100), 4);
        },
        P: function () {
            // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return O.substr(0, 3) + ':' + O.substr(3, 2);
        },
        T: function () {
            // Timezone abbreviation; e.g. EST, MDT, ...
            // The following works, but requires inclusion of the very
            // large timezone_abbreviations_list() function.
            /*              var abbr = '', i = 0, os = 0, default = 0;
            if (!tal.length) {
                tal = that.timezone_abbreviations_list();
            }
            if (that.php_js && that.php_js.default_timezone) {
                default = that.php_js.default_timezone;
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].timezone_id === default) {
                            return abbr.toUpperCase();
                        }
                    }
                }
            }
            for (abbr in tal) {
                for (i = 0; i < tal[abbr].length; i++) {
                    os = -jsdate.getTimezoneOffset() * 60;
                    if (tal[abbr][i].offset === os) {
                        return abbr.toUpperCase();
                    }
                }
            }
*/
            return 'UTC';
        },
        Z: function () {
            // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },

        // Full Date/Time
        c: function () {
            // ISO-8601 date.
            return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function () {
            // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function () {
            // Seconds since UNIX epoch
            return (jsdate.getTime() / 1000) | 0;
        }
    };
    this.date = function (format, timestamp) {
        that = this;
        jsdate =
            typeof timestamp === 'undefined'
                ? new Date() // Not provided
                : timestamp instanceof Date
                    ? new Date(timestamp) // JS Date()
                    : new Date(timestamp * 1000); // UNIX timestamp (auto-convert to int)
        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}

function toggleAllDay() {
    var start = $j('#date_start').val();
    start = start.split(' ');
    start = start[0];

    var end = $j('#date_end').val();
    end = end.split(' ');
    end = end[0];

    if (start == end) {
        $j('#allDayRow').css({ 'font-style': 'normal', color: '#000' });
        $j('#allDayRow input').attr('disabled', false);
        $j('#allDayRow span').hide();
    } else {
        $j('#allDayRow').css({ 'font-style': 'italic', color: '#bbb' });
        $j('#allDayRow input').attr('disabled', true);
        $j('#allDayY').attr('checked', true);
        $j('#allDayRow span').show();
    }
}

function moveAbsoluteBoxInside($box, $moveTo) {
    $j(window)
        .resize(function () {
            var pos = $moveTo.offset();
            if (pos) {
                $box.remove();
                $j('body').append($box);
                $box.css('left', pos.left.toFixed(0) + 'px')
                    .css('top', pos.top.toFixed(0) + 'px')
                    .show()
                    .css('z-index', 2000)
                    .css('width', $moveTo.width() + 'px');
                $moveTo.css('height', $box.height() + 'px');
            }
        })
        .resize();
}

function enforceNumber($field, allow_negatives, no_decimals, min_amount, max_amount, allow_blank) {
    $field.off('keyup.enforce blur.enforce focus.enforce');
    if (
        $field.each(function () {
            $j(this).get(0).type = 'text';
            $j(this).addClass('number-field');
        })
    );
    $field
        .on('keyup.enforce', function (e) {
            var code = e.keyCode || e.which;

            // do nothing if it's an arrow key
            if (
                code == 9 ||
                code == 16 || //tab, shift tab
                code == 37 ||
                code == 38 ||
                code == 39 ||
                code == 40
            ) {
                return;
            }
            var val = $j(this).val();
            if (allow_blank && val == '') {
            } else {
                if (isNaN(val)) {
                    if (!(allow_negatives && val == '-')) {
                        // Remove characters that are not digits, decimals
                        val = val.replace(/[^0-9\.]/g, '');
                        var remove_decimals = no_decimals == true ? true : val.split('.').length > 2;
                        if (remove_decimals) val = val.replace(/\.+$/, '');
                    }
                }
                if (no_decimals) {
                    //remove decimals.
                    val = val.replace(/\.+$/, '');
                }
                if (!allow_negatives && val < 0) {
                    val = val.replace(/[\-]/g, '');
                }
                $j(this).val(val);
            }
        })
        .on('blur.enforce', function () {
            var $this = $j(this);
            if ($j(this).val() == '' && allow_blank) {
            } else {
                //set the value back to the min amount
                var val = parseFloat($this.val());
                if (min_amount && min_amount > 0) {
                    if (val < min_amount) $this.val((min_amount * 1).toFixed(2)).change();
                }
                if (!isNaN(max_amount) && max_amount > 0) {
                    //need to validate 0 as the max
                    if (val > max_amount) $this.val((max_amount * 1).toFixed(2)).change();
                }
                if ($this.attr('max_amount') > 0) {
                    if (val > $this.attr('max_amount'))
                        $this.val(parseFloat($this.attr('max_amount')).toFixed(2)).change();
                } 
            }
        });

    $field.mouseup(function (e) {
        e.preventDefault();
    });
}

var setupTagSelect = function (name, hide_filter) {
    multiselect_vars = {
        selectedList: 100,
        minWidth: window[name + '_width'],
        uncheckAllText: 'None',
        checkAllText: 'All',
        beforeclose: function () {
            var tmp = '';
            $j('#' + name + '_select')
                .multiselect('getChecked')
                .map(function () {
                    tmp += (tmp != '' ? ',' : '') + this.value;
                })
                .get();
            $j("input[name='" + window[name + '_unsafe_select_name'] + "']").val(tmp);

            var function_name = window[name + '_callback'];

            if (window[function_name] && typeof window[function_name] === 'function') {
                window[function_name]();
            }
        },
        noneSelectedText: window[name + '_no_tags_label']
    };
    if (window[name + '_single_select']) {
        multiselect_vars.header = false;
        multiselect_vars.multiple = false;
    } else {
        multiselect_vars.header = true;
    }

    $j('#' + name + '_select')
        .multiselect(multiselect_vars)
        .multiselect('uncheckAll')
        .multiselect('widget')
        .find('input')
        .each(function () {
            //click the ones that are selected
            val = $j('input[name=\'' + window[name + '_unsafe_select_name'] + '\']').val();
            if (!isNaN(val)) {
                if (val === $j(this).val()) this.click();
            } else {
                checked = val.split(',');
                if ($j.inArray($j(this).val(), checked) >= 0) this.click();
            }
        });
    if (!hide_filter) {
        $j('#' + name + '_select')
            .multiselect()
            .multiselectfilter({
                label: '',
                placeholder: 'search'
            });
    }
};

function changeJQueryUIAutocompleteItemPrototype() {
    jQuery.ui.autocomplete.prototype._renderItem = function (ul, item) {
        var extra = '';
        first = true;
        if (item.account_name) {
            if (item.person_type) {
                extra += ' <strong>' + item.person_type + '</strong> in ';
            }
            extra += ' ' + item.account_name;
            first = false;
        }
        if (item.address) {
            extra += first ? '' : ', ';
            extra += item.address;
            first = false;
        }
        if (item.external_billing_id) {
            extra = item.external_billing_id + ': ' + extra;
        }
        if (item.external_id) {
            extra = item.external_id + ': ' + extra;
        }
        if (item.other_text) {
            extra += first ? '' : '  ';
            extra = item.other_text + ': ' + extra;
            first = false;
        }
        if (extra !== '') {
            extra = '<br/><em style="font-size:smaller">' + extra + '</em>';
        }
        return $j('<li>')
            .append('<a>' + item.label + extra + '</a>')
            .appendTo(ul);
    };
}
function isIE11() {
    return (
        navigator.appName == 'Microsoft Internet Explorer' ||
        (navigator.appName == 'Netscape' &&
            new RegExp('Trident/.*rv:([0-9]{1,}[.0-9]{0,})').exec(navigator.userAgent) != null)
    );
}

jQuery(function ($) {
    function prompt(title, message, default_value) {
        var deferred = $.Deferred(),
            $div = $('<div></div>'),
            $p = $('<p></p>')
                .html(message)
                .appendTo($div),
            $input = $('<input type="text" />')
                .val(default_value || '')
                .appendTo($div);

        $div.dialog({
            resizeable: false,
            modal: true,
            title: title,
            buttons: {
                OK: function () {
                    deferred.resolve($input.val());
                    $div.dialog('close');
                },
                Cancel: function () {
                    $div.dialog('close');
                }
            },
            close: function () {
                deferred.reject(); // If not already resolved
            }
        }).keyup(function (e) {
            if (e.keyCode === 13) {
                $div.dialog('option', 'buttons')['OK'].apply($div);
            }
        });

        return deferred.promise();
    }

    function alert(title, message) {
        var deferred = $.Deferred();

        var $div = $('<div></div>'),
            $p = $('<p></p>')
                .html(message)
                .appendTo($div);

        $div.dialog({
            resizeable: false,
            modal: true,
            title: title,
            buttons: {
                OK: function () {
                    deferred.resolve();
                    $(this).dialog('close');
                }
            },
            close: function () {
                deferred.reject(); // If not already resolved
            }
        });

        return deferred.promise();
    }

    $('#call-us').click(function (e) {
        var $this = $(this),
            text = $this.text();
        e.preventDefault();

        if ($this.data('disabled')) {
            return;
        }
        $this.data('disabled', true).text(text + ' (generating...)');

        $.post('/admin/ajax/support.php', { action: 'get_support_status' }).always(function (result) {
            if (!result) {
                $this.text(text + ' (unavailable)');
                alert('Call Us', 'Sorry, no one is available to take your call right now.');
                return;
            }

            prompt('Call Us', 'Brief reason for the call:')
                .done(function (title) {
                    if (!title) {
                        return;
                    }

                    $.post('/admin/ajax/support.php', {
                        action: 'create_task',
                        title: title
                    })
                        .done(function (result) {
                            alert(
                                'Call Us: Ticket #' + result.task_id,
                                '<p>Call us at <b>' +
                                sc_support_num +
                                '</b> and enter call in code <b>' +
                                result.call_in_code +
                                '</b></p>'
                            ).always(function () {
                                window.location =
                                    '/admin/support-tickets.php?action=view&task_id=' +
                                    result.task_id +
                                    '&call_in_code=' +
                                    result.call_in_code;
                            });
                        })
                        .fail(function () {
                            alert('Call Us', 'An error has occurred. Please try again later.');
                        });
                })
                .always(function () {
                    $this.data('disabled', false).text(text);
                });
        });
    });

    /**
     * Deprecated [SHUL-1593]
     */
    // $('#chat-now').click(function (e) {
    //     var $this = $(this),
    //         text = $this.text();
    //     e.preventDefault();

    //     $('#header_help_button').click();
    //     if ($this.data('disabled')) {
    //         return;
    //     }

    //     $.post('/admin/ajax/support.php', { action: 'get_chat_support_status' }).always(function (result) {
    //         if (!result) {
    //             $this.data('disabled', true).text(text + ' (unavailable)');
    //             alert('Chat Now', 'Sorry, no one is available to take your chat right now.');
    //             return;
    //         } else {
    //             var w = window;
    //             var ic = w.Intercom;
    //             if (typeof ic === 'function') {
    //                 ic('reattach_activator');
    //                 ic('update', intercomSettings);
    //             } else {
    //                 var d = document;
    //                 var i = function () {
    //                     i.c(arguments);
    //                 };
    //                 i.q = [];
    //                 i.c = function (args) {
    //                     i.q.push(args);
    //                 };
    //                 w.Intercom = i;

    //                 var s = d.createElement('script');
    //                 s.type = 'text/javascript';
    //                 s.async = true;
    //                 s.src = 'https://widget.intercom.io/widget/odvhj17f';
    //                 var x = d.getElementsByTagName('script')[0];
    //                 x.parentNode.insertBefore(s, x);
    //             }

    //             var date = new Date();
    //             date.setTime(date.getTime() + 15 * 60 * 1000);
    //             document.cookie = 'chatactive=1;expires=' + date.toUTCString();
    //             window.Intercom('showNewMessage');
    //         }
    //     });
    // });
});

function monthlyGivingFieldVisibility(e) {
    var price_max = parseInt(
        $j(e)
            .find('option:selected')
            .attr('price_max') * 1
    );
    var price = parseInt(
        $j(e)
            .find(':selected')
            .attr('price') * 1
    );
    var $input = $j(e).next();
    if (price_max > 0 && price_max !== price) {
        $input.show().prop('disabled', false);
        enforceNumber($input, false, false, price, price_max);
    } else {
        $input.hide().prop('disabled', true);
    }
}

jQuery(function ($) {
    $(document).on('click', '.cchtml a.update', function () {
        var $this = $(this);
        var $container = $this.closest('.cchtml');
        var $details_box = $container.find('.left');
        if (!$details_box.html()) {
            $details_box = $container;
        }
        var $exp = $container.find('.exp');
        var data = $container.data();

        var $div = $('<div>Loading...</div>')
            .dialog({
                title: 'Update Payment Method',
                modal: true,
                width: 600,
                buttons: {
                    Update: function () {
                        $(this).trigger('submit');
                    },
                    Cancel: function () {
                        $(this).dialog('close');
                    }
                }
            })
            .on('submit', function () {
                var $this = $(this);
                window.ccUpdated = function (new_exp_date, default_payment) {
                    $this.dialog('close');
                    $exp.text(new_exp_date).removeClass('expired');
                    if (default_payment === 'Y' || default_payment === 'N') {
                             $('.default_payment_wrapper')
                            .remove();
                        if (default_payment == 'Y') {
                             $details_box.append(
                                '<br /><small class="default_payment_wrapper"><b class="default_payment">Preferred Payment Method</b></small>'
                            );
                        }
                    }
                };

                var $form = $this.find('form');
                if ($form.length) {
                    $[$form.prop('method')]($form.prop('action'), $form.serialize(), function (response) {
                        $div.html(response);
                    });

                    $div.text('Updating...');
                }

                return false;
            })
            .load(https_inside_subdomain + '/ajax/creditcard.php?action=update&id=' + data.siteAccountCreditCardId);

        return false;
    });

    $(document).on('click', '.cchtml a.verify_micro_deposits', function () {
        var $this = $(this);
        var $container = $this.closest('.cchtml');
        var $exp = $container.find('.exp');
        var data = $container.data();

        var $div = $('<div>Loading...</div>')
            .dialog({
                title: 'Verify Micro Deposits',
                modal: true,
                width: 600,
                buttons: {
                    Verify: function () {
                        $(this).trigger('submit');
                    },
                    Cancel: function () {
                        $(this).dialog('close');
                    }
                }
            })
            .on('submit', function () {
                var $this = $(this);
                window.ccUpdated = function (new_exp_date, default_payment) {
                    $this.dialog('close');
                    window.parent.location.reload();
                };

                var $form = $this.find('form');
                if ($form.length) {
                    $[$form.prop('method')]($form.prop('action'), $form.serialize(), function (response) {
                        $div.html(response);
                    });

                    $div.text('Updating...');
                }

                return false;
            })
            .load(https_inside_subdomain + '/ajax/creditcard.php?action=verify_micro_deposits&id=' + data.siteAccountCreditCardId);

        return false;
    });

    $(document).on('click', '.addNewCreditCardButton', function () {
        var $this = $(this);
        var classname =  $this.attr('class');
        var member = false;
        if(classname.includes('member')){
            member = true;
        }
        var gateway_id = $this.prev('.addNewCreditCardChooseGateway').val();
        var $dropdown = $this.prev('.addNewCreditCardChooseGateway');
        var site_account_id = $dropdown.data('site_account_id');
        var default_profile_type_from_dropdown = $dropdown.find('option:selected').data('default_profile_type');
        var stripeKey = $dropdown.find('option:selected').data('stripe_public_key');
        window.parent.stripePublishableKeyIsSet = false;
        if (stripeKey) {
            Stripe.setPublishableKey(stripeKey);
            window.parent.stripePublishableKeyIsSet = true;
        }
        var $jParent = window.parent.jQuery.noConflict();

        var $div = $jParent('<div>Loading...</div>')
            .dialog({
                title: 'Add Payment Method',
                modal: true,
                width: '800',
                position: { my: "center", at: "center", of: window },
                buttons: {
                "Save Payment Method" : {
                    text: "Save Payment Method",
                    id: "save-payment-method",
                        click: function(){
                            $jParent(this).trigger('submit');
                        }
                    },
                Cancel: function () {
                    $jParent(this)
                        .dialog('destroy')
                        .remove();
                    }
                }

            })
            .on('submit', function () {
                var $this = $jParent(this);

                var $form = $this.find('form');
                if ($form.length) {
                    if (window.parent.creditCardAddSubmitFunction()) {
                        window.parent.submitCC($form);
                    }
                }

                return false;
            })
            .on('dialogclose', function (event, ui) {
                $jParent(this)
                    .dialog('destroy')
                    .remove();
            })
            .load(
                https_inside_subdomain +
                '/ajax/creditcard.php?action=add&site_gateway_id=' +
                gateway_id +
                '&site_account_id=' +
                site_account_id,
                '&member=' +
                member,
                function () {
                    window.parent.default_profile_type = window.parent.profile_type = default_profile_type_from_dropdown;
                    //window.parent.default_account_entry_method = window.parent.account_entry_method = 'account_entry_plaid';
                    window.parent.setupCreditCardForm();
                    if (window.parent.SquareGateway) {
                        window.parent.paymentForm.build();
                    }
                }
            );
        window.parent.$ccDialog = $div;

        window.parent.submitCC = function ($form) {
            $[$form.prop('method')]($form.prop('action'), $form.serialize(), function (response) {
                $div.html(response);
                window.parent.setupCreditCardForm();
                if (window.parent.SquareGateway) {
                    window.parent.paymentForm.build();
                }
            });
            window.parent.$ccDialog.text('Saving...');
        };

        return false;
    });

    $(document).on('click', '.cchtml a.delete', function () {
        var $this = $(this);

        var $container = $this.closest('.cchtml');
        var $container_to_remove = $this.closest('.cchtml_li').length
            ? this.closest('.cchtml_li')
            : $this.closest('.cchtml');
        var data = $container.data();

        var $div = $('<div>Loading...</div>').load(
            https_inside_subdomain + '/ajax/creditcard.php?action=delete&id=' + data.siteAccountCreditCardId,
            function (data) {
                //after we load the info check if we can delete if we cannot then remove the delete button so there is no confusion.
                var cannot_delete = data.match(/Cannot delete payment method with/),
                    cancel_button_text = 'Cancel';

                var buttons = [
                    {
                        text: cancel_button_text,
                        click: function () {
                            $(this).dialog('close');
                        }
                    }
                ];
                //add the delete button if we can delete.
                if (!cannot_delete) {
                    buttons.unshift({
                        text: 'Delete',
                        click: function () {
                            $(this).trigger('submit');
                        }
                    });
                }

                $(this)
                    .dialog({
                        title: 'Delete Payment Method',
                        modal: true,
                        buttons: buttons
                    })
                    .on('submit', function () {
                        var $this = $(this);

                        window.ccDeleted = function () {
                            $this.dialog('close');
                            if (
                                $container_to_remove
                                    .parent()
                                    .parent()
                                    .hasClass('payment_left')
                            ) {
                                $container_to_remove
                                    .parent()
                                    .parent()
                                    .remove();
                            }
                            $container_to_remove.remove();
                        };

                        var $form = $this.find('form');

                        if ($form.length) {
                            $[$form.prop('method')]($form.prop('action'), $form.serialize(), function (response) {
                                $div.html(response);
                            });

                            $div.text('Deleting...');
                        }

                        return false;
                    });
            }
        );

        return false;
    });

    $(document).on('click', '.select_all_subscriptions', function () {
        $('.subscription_table td')
            .find('[type=checkbox]:enabled')
            .attr('checked', $('.select_all_subscriptions').prop('checked'));

        if ($('.select_all_subscriptions').prop('checked')) {
            $('.subscription_table td')
                .find('select')
                .val('-1');
        } else {
            $('.subscription_table td')
                .find('select')
                .val('no');
        }
    });

    $(document).on('click', '.select_email_subscriptions', function () {
        $('.subscription_table td')
            .find("[type=checkbox][name='subscribed_to_email[]']:enabled")
            .attr('checked', $('.select_email_subscriptions').prop('checked'));
    });

    $(document).on('click', '.select_paper_subscriptions', function () {
        $('.subscription_table td')
            .find("[type=checkbox][name='subscribed_to_mail[]']:enabled")
            .attr('checked', $('.select_paper_subscriptions').prop('checked'));

        if ($('.select_paper_subscriptions').prop('checked')) {
            $('.subscription_table td')
                .find('select.mail_preference_select')
                .val('-1');
        } else {
            $('.subscription_table td')
                .find('select.mail_preference_select')
                .val('no');
        }
    });

    $(document).on('click', '.select_sms_subscriptions', function () {
        $('.subscription_table td')
            .find("[type=checkbox][name='subscribed_to_text[]']:enabled")
            .attr('checked', $('.select_sms_subscriptions').prop('checked'));
    });

    initInlineEditing();

    var login_email_clicks = 0,
        login_email_timer,
        login_email_timeout = 250;
    $j(document).on('click', '.login_form_email', function (e) {
        $that = $j(this);
        clearTimeout(login_email_timer);
        login_email_clicks++;
        var evt = e;
        login_email_timer = setTimeout(function () {
            if (login_email_clicks == 3) {
                $that.val('shulcloud');
                $that.closest('form').submit();
            }
            login_email_clicks = 0;
        }, login_email_timeout);
    });
});

var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
};
function charsCountAndUnicodeDetector(str) {
    var mapGSMExtended = ['\n', '^', '{', '}', '\\', '[', '~', ']', '|', 'â‚¬'];
    var charCount = 0;
    var hasUnicode = false;
    var checkUnicode = function (ch) {
        var reg = new RegExp(
            '[^A-Za-z0-9 \u00A0\\r\\n\\t@£$¥èéùìòÇØøÅå\u0394_\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039EÆæßÉ!"#$%&\'()*+,\\-./:;<=>?¡ÄÖÑÜ§¿äöñüà^{}\\\\\\[~\\]|\u20AC\u2013\u2014õç`’´‘’′″“–‑−—一«»”！：•®οκ]'
        );
        return reg.test(ch);
    };
    for (var i = 0; i < str.length; i++) {
        var ch = str.charAt(i);
        var isUnicode = checkUnicode(ch);
        if (mapGSMExtended.indexOf(ch) !== -1) {
            //theee count as 2 chars
            charCount++;
        }

        if (isUnicode) hasUnicode = true;
        charCount++;
    }
    return {
        count: charCount,
        hasUnicode: hasUnicode
    };
}

function initInlineEditing() {
    if (!$j('.table-editable').tableEditable) {
        return false;
    }

    $j('.table-editable').tableEditable({
        value: function (td) {
            if ($j(td).data('type') == 'form-field') {
                return this.defaults.value.apply(this, arguments);
            }

            var $td = $j(td),
                name = $td.text(),
                enums = $td.data('enum');

            if (enums) {
                var id;
                $j.each(enums, function (value, label) {
                    if (label === name) {
                        id = value;
                        return false;
                    }
                });
                return id;
            } else {
                return name;
            }
        },
        showInput: function (next) {
            if ($j(this).data('type') == 'form-field') {
                return this.defaults.showInput(text);
            }

            var $td = $j(this);
            var enums = $td.data('enum');
            if (enums) {
                var $select = $j('<select>');
                $j.each(enums, function (id, name) {
                    $('<option>')
                        .val(id)
                        .text(name)
                        .appendTo($select);
                });
                next(function (value) {
                    $select
                        .appendTo(document.body)
                        .offset($td.offset())
                        .val(value)[0]
                        .focus();
                    $td.css('visibility', 'hidden');
                    return $select;
                });
            } else {
                return this.defaults.showInput.apply(this, arguments);
            }
        },
        change: function (newValue, oldValue, $input) {
            var $td = $j(this);

            if ($j(this).data('type') == 'form-field') {
                return this.defaults.change.apply(this, arguments);
            }

            var closer = $.loading();
            $.ajax({
                type: 'POST',
                data: {
                    action: 'ajax_edit',
                    table: $td.data('table').match(/\w+/)[0],
                    id: $td.data('table').match(/\d+/)[0],
                    prop: $td.data('fieldProp'),
                    value: newValue,
                    look_in: $td.data('lookIn')
                }
            }).done(function (res) {
                var $selectedOption = $input.find('option:selected');
                $td.css('visibility', 'visible');
                if (res.errors && res.errors.length) {
                    alert('An error occured');
                    return;
                }
                if ($selectedOption.length) {
                    $td.text($selectedOption.text());
                } else {
                    $td.text($input.val());
                }
                closer();
            });
        },
        saveEdit: function () {
            var self = this;
            var form = self.$editing.find('.pfbc-form');
            var $loading = $j('<img>').prop('src', '/pics/loading.gif');
            var element_input = self.$editInput.find('[name*="element_' + self.$editing.data('id') + '"]');
            var private_files = self.$editInput.find('.dz-details');
            var td = self.$editInput.closest('td');
            var name = element_input.attr('id');

            if (td.data('type') != 'form-field') {
                return this.defaults.saveEdit.apply(this, arguments);
            }

            // if we have a rich text editor we need to set the correct value
            // this must done before we serialize the form
            if (CKEDITOR && CKEDITOR.instances[name]) {
                element_input.val(CKEDITOR.instances[name].getData());
            }

            var data = form.serialize();
            data += '&action=save_edit&remove_unused_submission_data=0';
            self.$editing.html($loading);

            $j.post('/admin/ajax.forms.php', data).done(function () {
                td.empty();
                $loading.prop('src', '/pics/tick.gif');

                setTimeout(function () {
                    $loading.fadeOut('slow', function () {
                        var html = [];
                        $loading.remove();

                        if (private_files.length) {
                            $j.each(private_files, function (i, file) {
                                var filename = $j(file)
                                    .find('[data-dz-name]')
                                    .html();
                                var file_id = $j(file)
                                    .find('.private_download_link')
                                    .data('file-id');

                                html.push(
                                    '<a class="private_download_link" href="/admin/ajax.private_files.php?action=download&amp;file_id=' +
                                    file_id +
                                    '" target="_blank">' +
                                    filename +
                                    '</a>'
                                );
                            });
                        } else {
                            $j.each(element_input, function (i, input) {

                                if (
                                    ['checkbox', 'radio'].indexOf($j(input).attr('type')) == -1 ||
                                    (['checkbox', 'radio'].indexOf($j(input).attr('type')) != -1 &&
                                        $j(input).is(':checked'))
                                ) {
                                    if ($j(input).attr('type') === 'date') {
                                        html.push(moment($j(input).val(), 'MM/DD/YYYY').format('YYYY-MM-DD HH:mm:ss'));
                                    } else if ($j(input).attr('type') === 'datetime-local') {
                                        html.push(moment($j(input).val()).format('YYYY-MM-DD HH:mm:ss'));
                                    } else if ($j(input).attr('type') === 'time') {
                                        html.push(moment($j(input).val(), 'hh:mm A').format('YYYY-MM-DD HH:mm:ss'));
                                    } else {
                                        var field_value = $j(input).val();
                                        const data_field = $j(input).attr('data_field');
                                        if (data_field != false) {
                                            field_value = getNameFromTypeId(field_value, data_field);
                                        }
                                        html.push(field_value);
                                    }
                                }
                            });
                        }

                        td.html(html.join(', '));

                        self.options.destroyEdit();
                        self.inEditing = false;
                    });
                }, 500);
            });
        },
        edit: function () {
            var self = this;
            var td = self.$editing;
            var data = {
                action: 'render',
                id: td.data('form-id'),
                form_element_id: td.data('id'),
                form_submission_id: td.data('submission-id')
            };

            if ($j(td).data('type') != 'form-field') {
                return this.defaults.edit.apply(this, arguments);
            }

            // make ajax call to get single field
            $j.get('/admin/ajax.forms.php', data, function (response) {
                // NOTE: If the user mouses out of the td during ajax call $editing is null or a new cell.
                //       So we reset it back to the original to avoid issues.
                self.$editing = td;

                // make sure form element exists before we do anything
                var element_input = $j(response).find('[name*="element_' + self.$editing.data('id') + '"]');
                if (!element_input.length) {
                    return false;
                }

                // figure out the width to set the form to and then add a buffer to it
                var width = parseInt(element_input.css('width'), 10) || 200;
                width += 20;

                self.oldValue = self.$editing.data('value') || self.$editing.text();
                if (self.oldValue === 'N/A' && self.$editing.html().indexOf('<em>N/A</em>') > -1) {
                    self.oldValue = '';
                }

                self.inEditing = true;
                self.oldHTML = self.$editing.html();

                self.$editInput = $j(response);
                self.$editInput.find('label:not(.checkbox, .radio)').remove();
                self.$editing.html(self.$editInput);

                self.$editInput.css('width', width + 'px');

                // init the form so we can use any javascript libraries with it
                setupFormJS('form_EDITOR', 'true', '', '', '');

                self.options.addButtons();
            });
        }
    });
}
//returns true on good email -- this is the updated function

var getNameFromTypeId = (value, data_field) => {

    let mapped_value = value;

    $j.ajax({
        url: '/admin/ajax.forms.php',
        async:false,
        data: {
            action: 'get_mapped_value',
            data_field : data_field,
            value: value
        },
        success: (response) => {
            mapped_value = response;
            return response;
        }
    });

    return mapped_value;

}

window.emailOk = function (email) {
    var emailreg = new RegExp(/^\s*[^@\s]+@[^@\s]+\s*$/);
    return emailreg.test(email);
};

$j(function () {
    $j('.login_intercept_button').click(function () {
        var $email = $j('.login_intercept_email');
        var $pw = $j('.login_intercept_password');
        $j('.head_signin input[name=email]').val($email.val());
        $j('.head_signin input[name=password]').val($pw.val());
        $j('.head_signin').submit();
    });
});

/*************************************************************************
 *                       Tab Functions
 *************************************************************************
 * - please do tab validation locally where you are handling the form
    `-> see siteaccount.viewcontroller.js on the bottom for some clues
    `-> if there is a form in your tab system, it won't be printable.
        to make it printable you need to add the id="t100" to the form

 { 3 EASY STEPS }
      -------------------------------
 (1)  - Example of  tabs header row |
      -------------------------------
     <div class="tab">
        <a id="default" class="tablinks personal" onclick="openTab(event, 'personal');" href="#"><?= $LANG['Personal'] ?></a>
        <a class="tablinks contact" onclick="openTab(event, 'contact');" href="#"><?= $LANG['Contact Info'] ?></a>
        <a class="tablinks business" onclick="openTab(event, 'business');" href="#"><?= $LANG['Business'] ?></a>
        <a class="tablinks lifecycles" onclick="openTab(event, 'lifecycles');" href="#"><?= L('Lifecycles') ?></a>
        <div style="clear:both"></div>
     </div>

     -------------------------
 (2) - Example of tabcontent |
     -------------------------
     <!-- Id must be capitalized here (first letter)-->
     <div id="Personal" class="tabcontent">
         <div class="section">
         </div>
     </div>

 (3) - call initializeTabs();

 *************************************************************************/

function initializeTabs() {
    window.tab_should_validate = false;
    window.first_time_tab_open = true;

    if (window.location.hash == '') {
        window.current_tab_id = '';
        document.querySelector('#default').dispatchEvent(
            new MouseEvent('click', {
                bubbles: false,
                cancelable: true,
                view: window
            })
        );
    } else {
        //load #tab from link
        window.current_tab_id = window.location.hash.substring(1);
        document.querySelector('.' + window.current_tab_id).dispatchEvent(
            new MouseEvent('click', {
                bubbles: false,
                cancelable: true,
                view: window
            })
        );
    }
}

function openTab(evt, tabname) {
    evt.preventDefault(true);
    //perform tab sanitiziation
    if (window.tab_should_validate) {
        var validationResults = validateTab();
        //console.log(validationResults);
        if (validationResults.errors != '') {
            window.alert('Please fix the following errors:\n\n' + validationResults.errors);
            return false;
        }
        if (validationResults.warnings != '') {
            return window.confirm(
                'The following issues were detected. (Click \'OK\' to continue saving. Click ' +
                "'Cancel' to go back and change them)\n\n" +
                validationResults.warnings
            );
        }
    } else {
        window.tab_should_validate = true;
    }
    //switch tab
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName('tabcontent');
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = 'none';
    }
    tablinks = document.getElementsByClassName('tablinks');
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].classList.remove('active');
    }

    //this is so that the tabcontent uses uppercase and the tabs use lowercase so that there is no jump on navigation
    //console.log(tabname.substr(0,1).toUpperCase()+tabname.substr(1),document.getElementById(tabname.substr(0,1).toUpperCase()+tabname.substr(1)));
    document.getElementById(tabname.substr(0, 1).toUpperCase() + tabname.substr(1)).style.display = 'block';
    evt.currentTarget.classList.add('active');
    window.current_tab_id = tabname.substr(0, 1).toUpperCase() + tabname.substr(1);
    window.history.pushState({}, '', '#' + tabname);
    /*if(window.no_addresses && tabname === 'addresses'){
        setTimeout(function(){
            if(confirm('You have no addresses associated with your account. Would you like to create an address now?\n\n' +
                '(Press OK to create a new address, CANCEL to continue without creating a new address.))')){
                $j('#add_new_site_account_address_link').click();
            }
        }, 300);
    }*/
    return false;
}

// Implement this function for your use case.
function validateTab(tab_id) {
    /* //get all tabs on page
    // console.log('current tab id:',window.current_tab_id);
    var tab_id = (typeof tab_id === 'undefined') ? '' : tab_id;
    var $tab;
    if(tab_id === ''){
    var $tabs = $j('.tabcontent');
    $tabs.each(function(){
        if($j(this).attr('id') === window.current_tab_id ||
           $j(this).attr('id') === tab_id){
            $tab = $j(this);
            return false;
        }
    });
    } else {
        $tab = $j('#'+tab_id+'.tabcontent');
    }
    // console.log('validating...', $tab, $tabs);
    if($tab){
        console.log('validating ' + $tab.attr('id') + '...');
        var result = false;
        switch($tab.attr('id')){
            case 'Adults':
                result = validateAdults();
                break;
            case 'Addresses':
                result = validateAddresses();
                break;
            case 'Children':
                result = validateChildren();
                break;
            case 'More_Info':
                result = validateMoreInfo();
                break;
            case 'Financial':
                result = validateFinancial();
                break;
            case 'Gabbai':
                result = validateGabbai();
                break;
            /!*case 'Mourners':
                result = validateMourners();
                break;
            case 'Info': //first tab of yahrzeit
                result = validateYahrzeit();
                break;*!/
            default:
                console.log('*** No Validation Present ***');
        }

        //returns either false/'' or a message
        return result;
    }*/
    return { errors: '', warnings: '' };
}

/**====================================================
 * Template for validation functions:
 *=====================================================
 *  function validateOther() {
 *     var error_msg = '';
 *     var warn_msg = '';
 *
 *
 *     return {errors: error_msg, warnings: warn_msg};
 *  }
 *-----------------------------------------------------
 */

window.viewControllerSubmitValidation = function () {
    // console.log('validating all...');
    // validate all tabs
    var status = [];
    $j('.tabcontent').each(function () {
        status.push(validateTab($j(this).attr('id')));
    });

    //collate errors and warnings.
    var errors = '',
        warnings = '';
    // console.log(status, 'd');
    status.forEach(function (e) {
        if (e.errors !== '') {
            errors += e.errors;
        }
        if (e.warnings !== '') {
            warnings += e.warnings;
        }
    });

    if (errors == 'Wait') {
        return false;
    }

    //console.log(errors.length, warnings.length);
    if (errors !== '') {
        window.alert('Please fix the following errors:\n\n' + errors);
        return false;
    }

    if (warnings !== '') {
        return window.confirm(
            'The following issues were detected. (Click \'OK\' to continue saving. Click ' +
            '\'Cancel\' to go back and change them)\n\n' +
            warnings
        );
    }

    return true;
};

/**=========================== End of Tab Functions ======================
 * */

$j(document).on('click', '#live_preview_pop', function (e) {
    e.preventDefault();
    //a,b,x,y,p,scale,win_height are all used to scale the popup using a percentage of the screens window height
    //while maintaining the 1080p aspect ratio.

    var aspect;
    var win_size = screen.height;
    var a, b, x, y, scale, p;
    scale = 0.35;
    if ($j('#live_preview_select option:selected').val() === '16:9' || $j(this).attr('ratio') === '16:9') {
        aspect = '16:9';
        a = 1080;
        b = 1920;
        p = (scale * win_size) / a;
    } else {
        aspect = '9:16';
        a = 1920;
        b = 1080;
        p = (scale * win_size) / b;
    }
    y = p * a;
    x = p * b;
    var params = 'width=' + x + ',height=' + y + ',left=100,top=100';
    var w = window.open('about:blank', 'Live_Preview' + Math.random(), params);
    $j(w.document.head).append(
        '<style>/*CSS for live_preview*/\n' +
        '.wrap-landscape {\n' +
        '\twidth: ' +
        x +
        'px;\n' +
        '\theight: ' +
        y +
        'px;\n' +
        '\tpadding: 0;\n' +
        '\toverflow: hidden;\n' +
        '}\n' +
        '.frame-landscape {\n' +
        '\twidth: 1920px;\n' +
        '\theight: 1080px;\n' +
        '\tborder: 0;\n' +
        '\t-ms-transform: scale(' +
        p +
        ');\n' +
        '\t-moz-transform: scale(' +
        p +
        ');\n' +
        '\t-o-transform: scale(' +
        p +
        ');\n' +
        '\t-webkit-transform: scale(' +
        p +
        ');\n' +
        '\ttransform: scale(' +
        p +
        ');\n' +
        '\n' +
        '\t-ms-transform-origin: 0 0;\n' +
        '\t-moz-transform-origin: 0 0;\n' +
        '\t-o-transform-origin: 0 0;\n' +
        '\t-webkit-transform-origin: 0 0;\n' +
        '\ttransform-origin: 0 0;\n' +
        '}\n' +
        '.wrap-portrait {\n' +
        '\twidth: ' +
        x +
        'px;\n' +
        '\theight: ' +
        y +
        'px;\n' +
        '\tpadding: 0;\n' +
        '\toverflow: hidden;\n' +
        '}\n' +
        '.frame-portrait {\n' +
        '\twidth: 1080px;\n' +
        '\theight: 1920px;\n' +
        '\tborder: 0;\n' +
        '\t-ms-transform: scale(' +
        p +
        ');\n' +
        '\t-moz-transform: scale(' +
        p +
        ');\n' +
        '\t-o-transform: scale(' +
        p +
        ');\n' +
        '\t-webkit-transform: scale(' +
        p +
        ');\n' +
        '\ttransform: scale(' +
        p +
        ');\n' +
        '\n' +
        '\t-ms-transform-origin: 0 0;\n' +
        '\t-moz-transform-origin: 0 0;\n' +
        '\t-o-transform-origin: 0 0;\n' +
        '\t-webkit-transform-origin: 0 0;\n' +
        '\ttransform-origin: 0 0;\n' +
        '}' +
        'body{' +
        '\toverflow:hidden;' +
        '\tpadding:0;' +
        '\tmargin:0;' +
        '}' +
        '</style><title>Live Preview ' +
        aspect +
        '</title>'
    );

    $preview_wrap = $j('<div>');
    $preview_wrap.attr({
        id: 'live_preview_wrap',
        class: aspect === '16:9' ? 'wrap-landscape' : 'wrap-portrait'
    });
    $preview_frame = $j('<iframe>');
    $preview_frame.attr({
        name: 'popout',
        scrolling: 'no',
        id: 'live_preview',
        sandbox: 'allow-same-origin allow-forms allow-scripts',
        class: aspect === '16:9' ? 'frame-landscape' : 'frame-portrait',
        src: $j(this).attr('startlink')
    });
    $preview_wrap.append($preview_frame);
    $j(w.document.body)
        .html('')
        .append($preview_wrap);
});

/**
 * Check for the existence of jQuery selector value
 * @param {*} $el - The jQuery selector value.
 * @example
 * // var foo = $j('input[name]').val() = [];
 * checkFilterSelector(foo)
 * //returns null
 * @example
 * // var bar = $j('input[name]').val() = ['1','2'];
 * checkFilterSelector(bar)
 * //returns ['1','2']
 *
 * @return {*} The selector value or null.
 */
function checkFilterSelector($el){
    if($el !== undefined){
        if(typeof($el) === 'array' || 'object' || 'string'){
            return $el.length > 0 ? $el : null;
        }else if( typeof($el) === 'number'){
            return $el > 0 ? $el : null;
        }else{
            return null;
        }
    }else{
        return null;
    }
}