function __reset(_input) {
    _input.val(_input.attr('value') ? _input.attr('value') : '');
}

function __isUniqueInState(form, _uid = '') {

    // no same-named item in same-state validation
    let nameKey = '{{@$nameKey ? $nameKey : "name"}}',
        namePlain = $.trim(form.find('[data-name="' + nameKey + '"]').val()),
        nameBase64 = btoa(namePlain),
        table = form.closest('.point-table-container').find('.point-table').first(),
        exists = false,
        state = '',
        uidPart = !!_uid ? ':not([data-uid="' + _uid + '"])' : '';
    if (form.find('[name="isRemoved"][value="1"]').is(':checked')) { // inactive
        if (form.find('[name="isRemovedDueToEntryError"][value="1"]').is(':checked')) { // entry error
            if (table.find('tr.point-row[data-name-base64="' + nameBase64 + '"][data-is-removed="1"][data-is-removed-due-to-entry-error="1"]' + uidPart).length) {
                exists = true;
                state = 'entry error';
            }
        } else { // historic
            if (table.find('tr.point-row[data-name-base64="' + nameBase64 + '"][data-is-removed="1"][data-is-removed-due-to-entry-error="0"]' + uidPart).length) {
                exists = true;
                state = 'historic';
            }
        }
    } else { // active
        if (table.find('tr.point-row[data-name-base64="' + nameBase64 + '"][data-is-removed="0"]' + uidPart).length) {
            exists = true;
            state = 'active';
        }
    }
    if (exists) {
        toastr.error(namePlain + ' already exists in ' + state + ' state!');
        return false;
    }

    return true;
}

function __initRTEs(_collection) {
    _collection.each(function() {

        let noteRTE = $(this);

        $(this).wrap(
            $('<div class="rte-holder"/>')
                .attr('data-shortcuts', '')
        );

        // give a unique id to this editor instance
        var editorID = Math.ceil(Math.random() * 99999),
            fieldName = $(this).attr('data-field-name') ? $(this).attr('data-field-name') : 'free_text';

        var el = this;
        var existingContent = $(el).html();
        var quill = new Quill(el, {
            theme: 'snow',
            modules: {
                toolbar: false,
                keyboard: {
                    bindings: {
                        'tab': {
                            key: 9,
                            handler: function(range, context) {
                                return true;
                            }
                        }
                    }
                }
            },
            formats: [
                'bold',
                'italic',
                'link',
                'size',
                'strike',
                'underline',
                'blockquote',
                'header',
                'indent',
                'list',
                'align',
            ]
        });

        var toolbar = $(quill.container).prev('.ql-toolbar');

        // add button for new shortcut
        if(!noteRTE.is('[use-shortcuts]') || !noteRTE.attr('use-shortcuts')) {
            var newSCButton = $('<button class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
                'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
            toolbar.append(newSCButton);
        }

        quill.root.innerHTML = existingContent;

        let onTextChange = function(delta, oldDelta, source) {
            var content = quill.root.innerHTML;
            let dataObject = {};
            dataObject[fieldName] = content;
            var dataValue = JSON.stringify(dataObject);
            let pElem = $(el).closest('[visit-moe]');
            if(!pElem.length) {
                pElem = $(el).closest('form');
            }
            let dataElem = pElem.find('input[name="' + ($(el).attr('data-container-name') ? $(el).attr('data-container-name') : 'data') + '"]');
            let v = dataElem.val();
            if(!!v) {
                try {
                    v = JSON.parse(v);
                    v[fieldName] = content;
                    v = JSON.stringify(v);
                }
                catch (e) {
                    v = JSON.stringify(dataObject);
                }
            }
            else {
                v = JSON.stringify(dataObject);
            }

            dataElem.val(v);

            $(el).trigger('rich-text-input');
        };

        if(!noteRTE.is('[ignore-changes]')) {
            quill.on('text-change', onTextChange);
        }

        $(quill.container)
            .find('.ql-editor[contenteditable]')
            .attr('data-field', fieldName)
            .attr('data-editor-id', editorID)
            .attr('with-shortcuts', 1);

        $(el).data('quillInstance', quill);

        // set value initially
        if(!noteRTE.is('[ignore-changes]')) {
            onTextChange();
        }
    });
}

parentSegment.find('[name="isRemoved"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-active-or-not-active], [if-active], [if-not-active], [if-active-and-pre-existing-or-not-active], [if-active-and-not-pre-existing]').addClass('d-none');
        if(form.find('[name="isRemoved"]:checked').length) form.find('[if-active-or-not-active]').removeClass('d-none');
        if(form.find('[name="isRemoved"]:checked').val() === '1') form.find('[if-not-active]').removeClass('d-none');
        else if(form.find('[name="isRemoved"]:checked').val() === '0') {
            form.find('[if-active]').removeClass('d-none');
            form.find('[name="removalEffectiveDate"]').val('');
            form.find('[name="removalReasonMemo"]').val('');
        }
        if(form.find('[name="isRemoved"]:checked').val() === '1' || form.find('[name="additionReasonCategory"]:checked').val() === 'ON_INTAKE') {
            form.find('[if-active-and-pre-existing-or-not-active]').removeClass('d-none');
        }
        if(form.find('[name="isRemoved"]:checked').val() === '0' && form.find('[name="additionReasonCategory"]:checked').val() !== 'ON_INTAKE') {
            form.find('[if-active-and-not-pre-existing]').removeClass('d-none');
        }
        return false;
    })
    .trigger('change');

parentSegment.find('[name="additionReasonCategory"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-addition-on-intake-or-during-visit], [if-addition-on-intake], [if-addition-during-visit], [if-active-and-pre-existing-or-not-active], [if-active-and-not-pre-existing], [if-entry-type-not-empty]').addClass('d-none');
        if(form.find('[name="additionReasonCategory"]:checked').length) form.find('[if-addition-on-intake-or-during-visit]').removeClass('d-none');
        form.find('[if-addition-or-removal-on-intake-or-during-visit]').addClass('d-none');
        if(form.find('[name="additionReasonCategory"]:checked').length || form.find('[name="removalReasonCategory"]:checked').length) {
            form.find('[if-addition-or-removal-on-intake-or-during-visit]').removeClass('d-none');
        }
        if(form.find('[name="additionReasonCategory"]:checked').val() === 'ON_INTAKE') {
            form.find('[if-addition-on-intake]').removeClass('d-none');
            __reset(form.find('[data-name="start_date"]'));
            __reset(form.find('[data-name="prescriber"]'));
        }
        else if(form.find('[name="additionReasonCategory"]:checked').val() === 'DURING_VISIT') {
            form.find('[if-addition-during-visit]').removeClass('d-none');
            form.find('[data-name="start_date"]').val('{{$patient->core_note_id !== $note->id ? $note->effective_dateest : date("Y-m-d")}}');
            form.find('[data-name="prescriber"]').val('{{$patient->core_note_id !== $note->id ? ($note->hcpPro ? $note->hcpPro->displayName() : "")  : ""}}');
        }
        if(form.find('[name="isRemoved"]:checked').val() === '1' || form.find('[name="additionReasonCategory"]:checked').val() === 'ON_INTAKE') {
            form.find('[if-active-and-pre-existing-or-not-active]').removeClass('d-none');
        }
        if(form.find('[name="isRemoved"]:checked').val() === '0' && form.find('[name="additionReasonCategory"]:checked').val() !== 'ON_INTAKE') {
            form.find('[if-active-and-not-pre-existing]').removeClass('d-none');
        }
        if(form.find('[name="additionReasonCategory"]:checked').length || form.find('[name="removalReasonCategory"]:checked').length) {
            form.find('[if-entry-type-not-empty]').removeClass('d-none');
        }
        return false;
    })
    .trigger('change');

parentSegment.find('[name="removalReasonCategory"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-removal-on-intake-or-during-visit], [if-removal-on-intake], [if-removal-during-visit], [if-entry-type-not-empty]').addClass('d-none');
        if(form.find('[name="removalReasonCategory"]:checked').length) form.find('[if-removal-on-intake-or-during-visit]').removeClass('d-none');
        form.find('[if-addition-or-removal-on-intake-or-during-visit]').addClass('d-none');
        if(form.find('[name="additionReasonCategory"]:checked').length || form.find('[name="removalReasonCategory"]:checked').length) {
            form.find('[if-addition-or-removal-on-intake-or-during-visit]').removeClass('d-none');
        }
        if(form.find('[name="removalReasonCategory"]:checked').val() === 'ON_INTAKE') {
            form.find('[if-removal-on-intake]').removeClass('d-none');
            __reset(form.find('[data-name="start_date"]'));
            __reset(form.find('[data-name="prescriber"]'));
            __reset(form.find('[name="removalEffectiveDate"]'));
            __reset(form.find('[name="removalReasonMemo"]'));
        }
        else if(form.find('[name="removalReasonCategory"]:checked').val() === 'DURING_VISIT') {
            form.find('[if-removal-during-visit]').removeClass('d-none');
            __reset(form.find('[data-name="start_date"]'));
            __reset(form.find('[data-name="prescriber"]'));
            form.find('[name="removalEffectiveDate"]').val('{{$patient->core_note_id !== $note->id ? $note->effective_dateest : date("Y-m-d")}}');
            form.find('[name="removalReasonMemo"]').val('{{$patient->core_note_id !== $note->id ? ($note->hcpPro ? $note->hcpPro->displayName() : "")  : ""}}');
        }
        if(form.find('[name="additionReasonCategory"]:checked').length || form.find('[name="removalReasonCategory"]:checked').length) {
            form.find('[if-entry-type-not-empty]').removeClass('d-none');
        }
        return false;
    })
    .trigger('change');

parentSegment.find('[name="isRemovedDueToEntryError"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-not-entry-error]').removeClass('d-none');
        if(form.find('[name="isRemovedDueToEntryError"]:checked').val() === '1') form.find('[if-not-entry-error]').addClass('d-none');
        return false;
    })
    .trigger('change');

parentSegment.find('#frm-add-{{$label}}')
    .off('submit')
    .on('submit', function () {

        let form = $(this);

        // require additionReasonCategory if active
        form.find('[name="additionReasonCategory"]').removeAttr('required');
        if(!form.find('[name="additionReasonCategory"]:checked').length) {
            if(form.find('[name="isRemoved"][value="0"]').is(':checked')) {
                form.find('[name="additionReasonCategory"]').attr('required', 'required');
            }
            else if(form.find('[name="isRemoved"][value="1"]').is(':checked')) {
                form.find('[name="additionReasonCategory"]').removeAttr('required');
                form.find('[name="additionReasonCategory"][value="ON_INTAKE"]').prop('checked', true); // make ON_INTAKE if in-active
            }
        }

        // require removalReasonCategory if not active
        form.find('[name="removalReasonCategory"]').removeAttr('required');
        if(!form.find('[name="removalReasonCategory"]:checked').length) {
            if(form.find('[name="isRemoved"][value="1"]').is(':checked')) {
                form.find('[name="removalReasonCategory"]').attr('required', 'required');
            }
        }

        // ensure an entry-type is selected
        if(!form.find('[name="additionReasonCategory"]:checked').length && !form.find('[name="removalReasonCategory"]:checked').length) {
            toastr.error('Entry type not selected.')
            return false;
        }

        if (!form[0].checkValidity()) {
            form[0].reportValidity();
            return false;
        }

        if(!__isUniqueInState(form)) return false;

        showMask();

        // add [data-name] values to payload
        let dataField = form.find('[name="data"]').first();
        let parsed = null;
        if(dataField.val()) {
            parsed = JSON.parse(dataField.val());
        }

        @if($label !== 'medication')
        // store plan content
        let planContent = parsed && parsed.planValue ? parsed.planValue : '';
        let reviewContent = parsed && parsed.reviewValue ? parsed.reviewValue : '';
        // if(!$.trim($('<div/>').html(planContent).text())) {
        //     toastr.error('Directions cannot be empty');
        //     return false;
        // }
        if(parsed.planValue) delete parsed.planValue;
        if(parsed.reviewValue) delete parsed.reviewValue;
        @endif

        form.find('[data-name]:not([data-container-name])').each(function() {
            if(!parsed) parsed = {};

            let keys = $(this).attr('data-name').split('->');
            let currentNode = parsed;
            for (let i = 0; i < keys.length; i++) {
                if(i !== keys.length - 1) {
                    if(typeof currentNode[keys[i]] === 'undefined') {
                        currentNode[keys[i]] = {};
                    }
                    currentNode = currentNode[keys[i]];
                }
                else {
                    if($(this).is(':checkbox')) {
                        currentNode[keys[i]] = $(this).prop('checked');
                    }
                    else {
                        currentNode[keys[i]] = $(this).val();
                    }
                }
            }

        });
        if(parsed) {
            dataField.val(JSON.stringify(parsed));
        }

        let payload = {};
        form.serializeArray().map(x => {payload[x.name] = x.value;});

        @if($label === 'medication')
            form.find('[data-name][data-container-name]').each(function() {
                let dataContainer = $(this).attr('data-container-name');
                if(!payload[dataContainer]) {
                    payload[dataContainer] = {};
                }
                else {
                    payload[dataContainer] = JSON.parse(payload[dataContainer]);
                }
                payload[dataContainer][$(this).attr('data-name')] = $(this).val();
                payload[dataContainer] = JSON.stringify(payload[dataContainer]);
            });
        @else
            if(!!reviewContent && $.trim($('<div/>').html(reviewContent).text())) {
                payload.childReviewData = JSON.stringify({
                    value: reviewContent
                })
            }
            if(!!planContent && $.trim($('<div/>').html(planContent).text())) {
                payload.childPlanData = JSON.stringify({
                    value: planContent
                })
            }
        @endif

        $.post(form.attr('action'), payload, _data => {
            if(!hasResponseError(_data)) {
                hideMask();
                refreshDynamicStagPopup();
                refreshAffectedSegmentsByType('{{$label}}');
                if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();

                // only for canvas-migrate
                if(form.closest('.point-content').length) {
                    fastReload();
                }
            }
        }, 'json');
        return false;
    });

parentSegment.find('.frm-edit-{{$label}}')
    .off('submit')
    .on('submit', function () {

        let form = $(this);

        if (!form[0].checkValidity()) {
            form[0].reportValidity();
            return false;
        }

        if(!__isUniqueInState(form, form.find('[name="uid"]').first().val())) return false;

        showMask();

        // add [data-name] values to payload
        let dataField = form.find('[name="data"]').first();
        let parsed = null;
        if(dataField.val()) {
            parsed = JSON.parse(dataField.val());
        }

        @if($label !== 'medication')

        let reviewContent = parsed && parsed.reviewValue ? parsed.reviewValue : '';
        let planContent = parsed && parsed.planValue ? parsed.planValue : '';

        /*let compareWith = false;
        if(form.find('.disallow-if-review-same-as')) {
            compareWith = $.trim(form.find('.disallow-if-review-same-as').text());
            if(compareWith && reviewContent) {
                let newValue = $('<div/>').html(reviewContent).text().replace(/[^a-zA-Z0-9]/g, '');
                if(newValue === compareWith) {
                    alert('New review should be different from the previous review!');
                    return false;
                }
            }
        }

        compareWith = false;
        if(form.find('.disallow-if-plan-same-as')) {
            compareWith = $.trim(form.find('.disallow-if-plan-same-as').text());
            if(compareWith && planContent) {
                let newValue = $('<div/>').html(planContent).text().replace(/[^a-zA-Z0-9]/g, '');
                if(newValue === compareWith) {
                    alert('New plan should be different from the previous plan!');
                    return false;
                }
            }
        }*/

        if(parsed.planValue) delete parsed.planValue;
        if(parsed.reviewValue) delete parsed.reviewValue;
        @endif

        form.find('[data-name]').each(function() {
            if(!parsed) parsed = {};

            let keys = $(this).attr('data-name').split('->');
            let currentNode = parsed;
            for (let i = 0; i < keys.length; i++) {
                if(i !== keys.length - 1) {
                    if(typeof currentNode[keys[i]] === 'undefined') {
                        currentNode[keys[i]] = {};
                    }
                    currentNode = currentNode[keys[i]];
                }
                else {
                    if($(this).is(':checkbox')) {
                        currentNode[keys[i]] = $(this).prop('checked');
                    }
                    else {
                        currentNode[keys[i]] = $(this).val();
                    }
                }
            }

        });
        if(parsed) {
            dataField.val(JSON.stringify(parsed));
        }

        let payload = {};
        form.serializeArray().map(x => {payload[x.name] = x.value;});

        @if($label === 'medication')
            form.find('[data-name][data-container-name]').each(function() {
                let dataContainer = $(this).attr('data-container-name');
                if(!payload[dataContainer]) {
                    payload[dataContainer] = {};
                }
                else {
                    payload[dataContainer] = JSON.parse(payload[dataContainer]);
                }
                payload[dataContainer][$(this).attr('data-name')] = $(this).val();
                payload[dataContainer] = JSON.stringify(payload[dataContainer]);
            });
        @else
            if(!!reviewContent && $.trim($('<div/>').html(reviewContent).text())) {
                payload.childReviewData = JSON.stringify({
                    value: reviewContent
                })
            }
            if(!!planContent && $.trim($('<div/>').html(planContent).text())) {
                payload.childPlanData = JSON.stringify({
                    value: planContent
                })
            }
            // if added/removed during-visit, require plan
            /*if(form.find('[name="isRemovedDueToEntryError"]:checked').val() !== '1' &&
                ((form.find('[name="isRemoved"]:checked').val() === '0' && form.find('[name="additionReasonCategory"]:checked').val() === 'DURING_VISIT') ||
                (form.find('[name="isRemoved"]:checked').val() === '1' && form.find('[name="removalReasonCategory"]:checked').val() === 'DURING_VISIT'))
            ) {
                if(!planContent) {
                    alert('Updates during visit require an accompanying plan!');
                    return false;
                }
            }*/
        @endif

        $.post(form.attr('url'), payload, _data => {
            if(!hasResponseError(_data)) {
                hideMask();
                refreshDynamicStagPopup();
                refreshAffectedSegmentsByType('{{$label}}');
                if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
            }
        }, 'json');
        return false;
    });

// special case for nutrition form handling
parentSegment.find('.frm-upsert-review-plan-{{$label}}')
    .off('submit')
    .on('submit', function () {
        let form = $(this);
        showMask();
        $.post(form.attr('url'), form.serialize(), _data => {
            if(!hasResponseError(_data)) {
                refreshAffectedSegmentsByType('{{$label}}');
                refreshDynamicStagPopup();
            }
        }).then(() => {
            hideMask();
        });
        return false;
    });

/* exercise specific */
parentSegment.find('.frm-review-plan-exercise [data-name="active"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-active]')[this.checked ? 'removeClass' : 'addClass']('d-none');
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-exercise [data-name="walk->active"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-walk-active]')[this.checked ? 'removeClass' : 'addClass']('d-none');
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-exercise [data-name="jog->active"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-jog-active]')[this.checked ? 'removeClass' : 'addClass']('d-none');
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-exercise [data-name="elliptical->active"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-elliptical-active]')[this.checked ? 'removeClass' : 'addClass']('d-none');
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-exercise [data-name="swim->active"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-swim-active]')[this.checked ? 'removeClass' : 'addClass']('d-none');
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-exercise [data-name="bike->active"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form');
        form.find('[if-bike-active]')[this.checked ? 'removeClass' : 'addClass']('d-none');
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-exercise .btn-toggle-activity[data-type]')
    .off('click')
    .on('click', function () {
        let form = $(this).closest('form'),
            checkbox = form.find('[data-name="' + $(this).attr('data-type') + '->active"]'),
            current = checkbox.prop('checked');
        if(!current) {
            checkbox.prop('checked', true).trigger('change');
            $(this).removeClass('btn-default border').addClass('btn-info');
            $(this).closest('td').find('img').removeClass('opacity-35');
        }
        else {
            checkbox.prop('checked', false).trigger('change');
            $(this).removeClass('btn-info').addClass('btn-default border');
            $(this).closest('td').find('img').addClass('opacity-35');
        }
        return false;
    });
/* end of exercise specific */

/* behavior specific */
parentSegment.find('.frm-review-plan-behavior [data-name="tracking->other"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form'), input = form.find('[if-tracking-other]');
        if(this.checked) {
            input.prop('readonly', false).focus();
        }
        else {
            input.prop('readonly', true).val('');
        }
        return false;
    })
    .trigger('change');
parentSegment.find('.frm-review-plan-behavior [data-name="other"]')
    .off('change')
    .on('change', function () {
        let form = $(this).closest('form'), input = form.find('[if-other]');
        if(this.checked) {
            input.prop('readonly', false).focus();
        }
        else {
            input.prop('readonly', true).val('');
        }
        return false;
    })
    .trigger('change');
/* end of behavior specific */

/* lifestyle specific */
parentSegment.find('.frm-review-plan-lifestyle')
    .off('submit')
    .on('submit', function () {
        let form = $(this);
        if (!form[0].checkValidity()) {
            form[0].reportValidity();
            return false;
        }
        let dataField = 'data';
        if(form.find('[name="childReviewData"]').length) {
            dataField = 'childReviewData';
        }
        else if(form.find('[name="childPlanData"]').length) {
            dataField = 'childPlanData';
        }
        fillJsonDataField(form, dataField);
        showMask();
        $.post(form.attr('url'), form.serialize(), _data => {
            if(!hasResponseError(_data)) {
                $('.visit-segment[data-segment-template-name="intake_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                $('.visit-segment[data-segment-template-name="plan_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                $('.visit-segment[data-segment-template-name="{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                refreshDynamicStagPopup();
            }
        }).then(() => {
            hideMask();
        });
        return false;
    });
/* end of lifestyle specific */

parentSegment.find('.toggle-relevance')
    .off('click.toggle-relevance')
    .on('click.toggle-relevance', function () {
        if (+$(this).attr('data-relevant') === 0) {
            $.post('/api/visitPoint/markPointRelevantToNote', {
                noteUid: '{{$note->uid}}',
                pointUid: $(this).attr('data-point-uid')
            }, _data => {
                if (!hasResponseError(_data)) {
                    refreshDynamicStagPopup();
                    refreshAffectedSegmentsByType('{{$label}}');
                    if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
                }
            }, 'json');
        } else {
            if ($(this).attr('data-rel-uid')) {
                $.post('/api/visitPoint/undoMarkPointRelevantToNote', {
                    uid: $(this).attr('data-rel-uid')
                }, _data => {
                    if (!hasResponseError(_data)) {
                        refreshDynamicStagPopup();
                        refreshAffectedSegmentsByType('{{$label}}');
                        if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
                    }
                }, 'json');
            } else {
                console.log('Error - missing rel uid');
            }
        }
        return false;
    });

parentSegment.find('.tracker-input')
    .off('change.tracker-input')
    .on('change.tracker-input', function () {
        let trackerData = JSON.parse($.trim(parentSegment.find('.no_known_tracker').first().val()));

        // disallow if [data-num-active-items] and data-num-active-items is not 0
        if($(this).is('[data-num-active-items]')) {
            if(this.checked && +$(this).attr('data-num-active-items') !== 0) {
                toastr.error('There are active items');
                this.checked = false;
                return false;
            }
        }

        trackerData[$(this).attr('data-field-name')] = this.checked;
        trackerData = JSON.stringify(trackerData);
        $.post('/api/visitPoint/upsertGlobalSingleton', {
            category: 'NO_KNOWN_TRACKER',
            data: trackerData,
            noteUid: '{{$note->uid}}'
        }, _data => {
            if(!hasResponseError(_data)) {
                refreshDynamicStagPopup();
                refreshAffectedSegmentsByType('{{$label}}');
            }
        }, 'json');
    });

parentSegment.find('.btn-entry-type')
    .off('click')
    .on('click', function() {
        $(this).siblings().removeClass('btn-info').addClass('btn-default bg-white');
        $(this).removeClass('btn-default bg-white').addClass('btn-info');

        let form = $(this).closest('form');

        switch ($(this).attr('data-entry-type')) {
            case 'Pre-Existing':
                form.find('[name="removalReasonCategory"]').prop('checked', false).trigger('change');
                form.find('[name="isRemoved"][value="0"]').prop('checked', true).trigger('change');
                form.find('[name="additionReasonCategory"][value="ON_INTAKE"]').prop('checked', true).trigger('change');
                break;
            case 'Added during this visit':
                form.find('[name="removalReasonCategory"]').prop('checked', false).trigger('change');
                form.find('[name="isRemoved"][value="0"]').prop('checked', true).trigger('change');
                form.find('[name="additionReasonCategory"][value="DURING_VISIT"]').prop('checked', true).trigger('change');
                break;
            case 'Historic':
                form.find('[name="additionReasonCategory"]').prop('checked', false).trigger('change');
                form.find('[name="isRemoved"][value="1"]').prop('checked', true).trigger('change');
                form.find('[name="removalReasonCategory"][value="ON_INTAKE"]').prop('checked', true).trigger('change');
                break;
            case 'Removed during this visit':
                form.find('[name="additionReasonCategory"]').prop('checked', false).trigger('change');
                form.find('[name="isRemoved"][value="1"]').prop('checked', true).trigger('change');
                form.find('[name="removalReasonCategory"][value="DURING_VISIT"]').prop('checked', true).trigger('change');
                break;
        }

        return false;
    });

// do not default to Pre-Existing
// parentSegment.find('.btn-entry-type[data-entry-type="Pre-Existing"]').trigger('click');

const debounce = (func, wait) => {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
};

let debouncedWizardEditModeSaver = debounce(function(_trigger) {
    $(_trigger).closest('.stag-popup').find('.autosave-indicator').removeClass('show');
    $(_trigger).closest('.stag-popup').find('.autosave-indicator.saving').addClass('show');
    saveVisitForm(_trigger, true, false, () => {
        $(_trigger).closest('.stag-popup').find('.autosave-indicator').removeClass('show');
        $(_trigger).closest('.stag-popup').find('.autosave-indicator.saved').addClass('show');
    });
}, 500);

// auto save for segments with edit-mode
$(document).off('input.auto-save-input', '[if-edit-mode] [visit-moe] form input[type="text"]');
$(document).on('input.auto-save-input', '[if-edit-mode] [visit-moe] form input[type="text"]', function () {
    if($(this).closest('.point-table').is('.edit')) {
        debouncedWizardEditModeSaver(this);
    }
});
$(document).off('change.auto-save-select-change', '[if-edit-mode] [visit-moe] form select');
$(document).on('change.auto-save-select-change', '[if-edit-mode] [visit-moe] form select', function () {
    if($(this).closest('.point-table').is('.edit')) {
        debouncedWizardEditModeSaver(this);
    }
});
$(document).off('change.auto-save-checkbox-change', '[if-edit-mode] [visit-moe] form input[type="checkbox"]');
$(document).on('change.auto-save-checkbox-change', '[if-edit-mode] [visit-moe] form input[type="checkbox"]', function () {
    if($(this).closest('.point-table').is('.edit')) {
        debouncedWizardEditModeSaver(this);
    }
});
$(document).off('change.auto-save-radio-change', '[if-edit-mode] [visit-moe] form input[type="radio"]');
$(document).on('change.auto-save-radio-change', '[if-edit-mode] [visit-moe] form input[type="radio"]', function () {
    if($(this).closest('.point-table').is('.edit')) {
        debouncedWizardEditModeSaver(this);
    }
});
$(document).off('input.auto-save-textarea-input', '[if-edit-mode] [visit-moe] form textarea');
$(document).on('input.auto-save-textarea-input', '[if-edit-mode] [visit-moe] form textarea', function () {
    if($(this).closest('.point-table').is('.edit')) {
        debouncedWizardEditModeSaver(this);
    }
});

$(document).off('rich-text-input.auto-save-rich-text-input', '[if-edit-mode] [visit-moe] form [note-rte]');
$(document).on('rich-text-input.auto-save-rich-text-input', '[if-edit-mode] [visit-moe] form [note-rte]', function () {
    if($(this).closest('.point-table').is('.edit')) {
        debouncedWizardEditModeSaver(this);
    }
});

$(document).off('rich-text-input.auto-save-rich-text-input', '#frm-cc-regenerate [note-rte]');
$(document).on('rich-text-input.auto-save-rich-text-input', '#frm-cc-regenerate [note-rte]', function () {
    debouncedWizardEditModeSaver(this);
});

initStagSuggest();

parentSegment.find('.stag-sheet input[stag-suggest][key="name"]')
    .off('stag-suggest-selected')
    .on('stag-suggest-selected', (_e, _input, _data) => {
        _input = $(_input);
        @if($label === 'medication')
            _input.closest('tr').find('input[key="routedMedId"]').val(_data.routed_med_id);
            _input.closest('tr').find('input[key="routedDosageFormMedId"]').val(_data.routed_dosage_form_med_id);
            _input.closest('tr').find('input[key="gcnSeqno"]').val(_data.gcn_seqno);
            _input.closest('tr').find('input[key="medId"]').val(_data.medid);
        @elseif($label === 'problem')
            _input.closest('tr').find('input[key="dxid"]').val(_data.dxid);
            _input.closest('tr').find('input[key="icd"]').val(_data.sub_text);
        @elseif($label === 'allergy')
            _input.closest('tr').find('input[key="damConceptId"]').val(_data.dam_concept_id);
            _input.closest('tr').find('input[key="damConceptIdType"]').val(_data.dam_concept_id_typ);
        @endif
        return false;
    });

function getRowBefore(_tr) {
    return _tr.prev();
}

function moveToPrevRowInput(_td) {
    let tr = getRowBefore(_td.closest('tr'));
    tr.find('td:eq(' + _td.index() + ')').find('input, textarea').first().focus();
}

function getRowAfter(_tr) {
    return _tr.next();
}

function getOrCreateRowAfter(_tr) {
    let tr = getRowAfter(_tr);
    if(!tr.length) {
        tr = newRow(_tr).insertAfter(_tr);
        __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
    }
    return tr;
}

function createRowAfter(_tr) {
    let tr = newRow(_tr).insertAfter(_tr);
    __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
    return tr;
}

function newRow(_tr) {
    let newTr = _tr.clone(true);
    newTr.find('input, textarea').val('');
    newTr.find('textarea').attr('rows', 1).css({minHeight: '', height: ''});
    newTr.find('[stag-suggest-initialized]').removeAttr('stag-suggest-initialized');
    newTr.find('.stag-suggestions-container').remove();
    newTr.find('div[note-rte][key][bucket]').each(function() {
        let newRTE = $('<div note-rte class="rte-holder" ' +
            'key="' + $(this).attr('key') + '" ' +
            'bucket="' + $(this).attr('bucket') + '" ' +
            '/>');
        $(this).closest('td').empty().append(newRTE);
    });
    return newTr;
}

function createAndMoveToNextRowInput(_td) {
    let tr = createRowAfter(_td.closest('tr'));
    tr.find('input, textarea').first().focus();
}

function moveToNextRowInput(_td, _forceCreate = false) {
    let tr = _forceCreate ? getOrCreateRowAfter(_td.closest('tr')) : getRowAfter(_td.closest('tr'));
    if(tr.length) {
        tr.find('td:eq(' + _td.index() + ')').find('input, textarea').first().focus();
    }
}

function moveToPrevInput(_td) {
    _td.prev().find('input, textarea').first().focus();
}

function moveToNextInput(_td) {
    _td.next().find('input, textarea').first().focus();
}

function generateData(_parentSegment) {
    let lines = [];
    _parentSegment.find('.stag-sheet tbody tr').each(function() {
        let line = {
            data: {},
            childReviewData: {},
            childPlanData: {}
        };
        $(this).find('input, textarea').each(function() {
            line[$(this).attr('bucket')][$(this).attr('key')] = this.value;
        });
        $(this).find('[note-rte][key][bucket]').each(function() {
            line[$(this).attr('bucket')][$(this).attr('key')] = $(this).find('.ql-editor[contenteditable]').first().html();
        });
        line.data = JSON.stringify(line.data);
        line.childReviewData = JSON.stringify(line.childReviewData);
        line.childPlanData = JSON.stringify(line.childPlanData);
        lines.push(line);
    });
    return JSON.stringify(lines);
}

parentSegment
    .off('keydown', '.stag-sheet input, .stag-sheet textarea')
    .on('keydown', '.stag-sheet input, .stag-sheet textarea', function(_e) {
        switch (_e.which) {
            case 13: // ENTER: If shift NOT pressed, move to next row same column
                if (!_e.shiftKey || !$(this).is('textarea')) {
                    if($(this).closest('.stag-sheet').is('.allow-row-addition')) {
                        createAndMoveToNextRowInput($(this).closest('td'));
                        initStagSuggest();
                    }
                    else {
                        moveToNextRowInput($(this).closest('td'), false);
                    }
                    return false;
                }
                break;
            case 38: // UP: If caret already at 0, move up to prev row same column
                if (this.selectionStart === this.selectionEnd && this.selectionStart === 0) {
                    moveToPrevRowInput($(this).closest('td'));
                    return false;
                }
                break;
            case 40: // DOWN: If caret already at end, move down to next row same column
                if (this.selectionStart === this.selectionEnd && this.selectionStart === this.value.length) {
                    moveToNextRowInput($(this).closest('td'));
                    return false;
                }
                break;
            case 37: // LEFT: If caret already at 0, move left to prev column
                if (this.selectionStart === this.selectionEnd && this.selectionStart === 0) {
                    moveToPrevInput($(this).closest('td'));
                    return false;
                }
                break;
            case 39: // RIGHT: If caret already at end, move right to next column
                if (this.selectionStart === this.selectionEnd && this.selectionStart === this.value.length) {
                    moveToNextInput($(this).closest('td'));
                    return false;
                }
                break;
            case 8: // BACKSPACE: If caret already at 0, move left to prev column
                break;
        }

    });

parentSegment
    .off('click', '.stag-sheet tbody td')
    .on('click', '.stag-sheet tbody td', function(_e) {
        let focusable = $(this).find('input, textarea, .ql-editor[contenteditable]').first();
        if(!focusable.is(':focus')) {
            focusable.focus();
            return false;
        }
    });

parentSegment
    .off('click.delete-line', '.stag-sheet .delete-line')
    .on('click.delete-line', '.stag-sheet .delete-line', function() {
        let tr = $(this).closest('tr');
        let isFirst = (tr.index() === 0);
        if(isFirst) {
            newRow(tr).insertAfter(tr);
            __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
        }
        tr.remove();
        return false;
    });

parentSegment
    .off('click.add-line', '.stag-sheet .add-line')
    .on('click.add-line', '.stag-sheet .add-line', function() {
        let tr = $(this).closest('tr');
        newRow(tr).insertAfter(tr);
        __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
        initStagSuggest();
        return false;
    });

parentSegment
    .off('click.btn-save-lines', '.btn-save-lines')
    .on('click.btn-save-lines', '.btn-save-lines', function() {
        let numRows = parentSegment.find('.stag-sheet').find('tbody>tr').length;
        let numEmptyRows = numRows;
        let emptyRows = [];
        parentSegment.find('.stag-sheet').find('tbody>tr').each(function() { // loop A
            let isEmptyRow = true;
             $(this).find('input, textarea').each(function() { // loop B
                 if($.trim($(this).val())) {
                     isEmptyRow = false;
                     return false; // break from B
                 }
             });
             if(!isEmptyRow) numEmptyRows--;
             else emptyRows.push(this);
        });
        if(numEmptyRows > 0) {
            if(numEmptyRows === numRows && numRows === 1) return false; // if only 1 row and all empty in that - ignore and stop
            else { // else clear empty rows
                for (let i = 0; i < emptyRows.length; i++) {
                    $(emptyRows[i]).remove();
                }
            }
        }

        parentSegment.find('[name="dataJson"]').val(generateData(parentSegment));
        saveVisitForm(this);
        return false;
    });

parentSegment
    .off('click.switch-to-edit', '.point-table [if-read-mode] .inline-html-container:not(.click-to-copy)')
    .on('click.switch-to-edit', '.point-table [if-read-mode] .inline-html-container:not(.click-to-copy)', function() {
        let trigger = $(this).closest('[if-read-mode]')
            .find('form[url="/api/visitPoint/upsertChildReview"], form[url="/api/visitPoint/upsertChildPlan"]')
            .first().closest('[moe], [visit-moe]')
                .find('a[start][show]')
                .trigger('click');
        return false;
    });

parentSegment
    .off('click.upsert-rp-trigger', '.point-table [if-read-mode] .upsert-rp-trigger')
    .on('click.upsert-rp-trigger', '.point-table [if-read-mode] .upsert-rp-trigger', function() {
        let trigger = $(this).closest('[if-read-mode]')
            .find('form[url="/api/visitPoint/upsertChildReview"], form[url="/api/visitPoint/upsertChildPlan"]')
            .first().closest('[moe], [visit-moe]')
            .find('a[start][show]')
            .trigger('click');
        return false;
    });

parentSegment
    .off('click.update-core-data', '.update-core-data')
    .on('click.update-core-data', '.update-core-data', function() {
        $(this).closest('form').find('[if-core-data-edit-confirmed]').removeClass('d-none');
        return false;
    });