import { isNullOrUndefined } from '@syncfusion/ej2-base';
import { ElementBox, ParagraphWidget, TableRowWidget, TableCellWidget, BookmarkElementBox, FootnoteElementBox, HeaderFooterWidget, ShapeElementBox } from '../viewer/page';
import { WCharacterFormat } from '../format/character-format';
import { WRowFormat } from '../format/row-format';
import { HelperMethods } from '../editor/editor-helper';
import { revisionActionEvent } from '../../base/index';
import { ChangesSingleView } from '../track-changes/track-changes-pane';
/**
 * The revision class which holds the information related to changes made in the document
 */
var Revision = /** @class */ (function () {
    function Revision(documentHelper, author, date, ownerNode) {
        /**
         * Gets or sets the author name who made the change
         */
        this.author = null;
        /**
         * Indicates when the track changes made
         */
        this.date = null;
        /**
         * To set the custom data value.
         */
        this.customData = null;
        /**
         * @private
         */
        this.revisionID = '';
        /**
         * Used to update cursor position by ensuring items were removed or not
         */
        this.isContentRemoved = false;
        this.isTableRevision = false;
        /**
         * Indicates whether to skip unlinking ranges for table elements.
         */
        this.canSkipTableItems = false;
        this.skipUnLinkElement = false;
        /**
         * Private
         */
        this.hasChanges = false;
        this.author = author;
        if (isNullOrUndefined(this.author)) {
            this.author = "Unknown";
        }
        this.date = date;
        this.owner = documentHelper;
        this.ownerNode = ownerNode;
    }
    /**
     * Retrieves the content of the revision as an HTML string.
     *
     * @returns {string} The revision content as HTML string.
     */
    Revision.prototype.getContent = function () {
        var content = "";
        if (!isNullOrUndefined(this.owner.trackChangesPane.changes.get(this))) {
            var currentChangeView = this.owner.trackChangesPane.changes.get(this);
            if (!isNullOrUndefined(this.owner.revisions.groupedView.get(currentChangeView))) {
                var revisions = this.owner.revisions.groupedView.get(currentChangeView);
                var div = document.createElement('div');
                var ranges = [];
                for (var i = 0; i < revisions.length; i++) {
                    ranges = ranges.concat(revisions[i].getRange());
                }
                currentChangeView.tableElement = undefined;
                currentChangeView.layoutElementText(this, ranges, div, true);
                content = div.innerHTML;
            }
        }
        return content;
    };
    /**
      * Updates the date of the revisions shown in the track changes pane.
      * @param {string} value - The date to be set for the revision.
      * @returns {void}
      * Note: Revision dates are system-generated to preserve the audit trail and is strongly discouraged to modify it.
      * Calling this API permanently overwrites the original timestamp and cannot be recovered from the document history. This can undermine audit and compliance requirements.
      * Only use in controlled scenarios (e.g., data migration with approvals). For additional or custom timestamps, use the 'customData' property instead.
      */
    Revision.prototype.setDate = function (value) {
        if (!isNullOrUndefined(value) && value != '') {
            var date = new Date(value);
            if (date.toString() !== 'Invalid Date') {
                // if the input is already in Utc format no need to convert to Utc.
                if (value.indexOf('Z') < 0) {
                    this.date = HelperMethods.getUtcDate(date);
                }
                else {
                    this.date = value;
                }
                this.owner.trackChangesPane.setDateInternal(this);
            }
        }
    };
    /**
     * @private
     */
    Revision.prototype.getRange = function (updateRange) {
        if (this.ownerNode instanceof ParagraphWidget) {
            if (isNullOrUndefined(this.range) || isNullOrUndefined(updateRange) || updateRange || this.hasChanges) {
                this.range = this.ownerNode.getRevisionRange(this);
            }
            return this.range;
        }
        else {
            return this.ownerNode.getRevisionRange(this);
        }
    };
    /**
     * @private
     */
    Revision.prototype.handleAcceptReject = function (isFromAccept, isGroupAcceptOrReject) {
        var paragraphInfo = this.owner.selection.getParagraphInfo(this.owner.selection.start);
        var endParagraphInfo = this.owner.selection.getParagraphInfo(this.owner.selectionModule.end);
        var startIndex = this.owner.selection.getHierarchicalIndex(paragraphInfo.paragraph, paragraphInfo.offset.toString());
        var endIndex = this.owner.selection.getHierarchicalIndex(endParagraphInfo.paragraph, endParagraphInfo.offset.toString());
        this.owner.selectionModule.selectRevision(this, undefined, undefined, true);
        var selection = this.owner.selectionModule;
        var startPos = selection.start;
        var endPos = selection.end;
        if (!selection.start.isExistBefore(selection.end)) {
            startPos = selection.end;
            endPos = selection.start;
        }
        var blockInfo = selection.getParagraphInfo(startPos);
        var removeChanges = (!isNullOrUndefined(isFromAccept)) && ((this.revisionType === 'MoveFrom' || this.revisionType === 'Deletion') && isFromAccept) || ((this.revisionType === 'Insertion' || this.revisionType === 'MoveTo') && !isFromAccept);
        var comments;
        if (removeChanges) {
            var commentInfo = this.owner.editorModule.getSelectedComments();
            if (commentInfo.commentEndInfo.length > 0 || commentInfo.commentStartInfo.length > 0) {
                comments = this.owner.editorModule.checkAndRemoveComments(false, true);
            }
            else {
                removeChanges = false;
            }
        }
        this.owner.editorModule.initHistory(isFromAccept ? 'Accept Change' : 'Reject Change');
        var fieldBegin = selection.getHyperlinkField();
        if (isFromAccept && this.revisionType === 'Deletion' && !isNullOrUndefined(fieldBegin)
            && this.getRange(false).indexOf(fieldBegin) !== -1 && this.getRange(false).indexOf(fieldBegin.fieldEnd) !== -1 && this.getRange(false).indexOf(fieldBegin.fieldSeparator) === this.getRange(false).indexOf(fieldBegin.fieldEnd) - 1) {
            this.owner.editorHistoryModule.currentBaseHistoryInfo.isHyperlinkField = true;
        }
        this.owner.editorHistoryModule.currentBaseHistoryInfo.markerData.push(this.owner.editorModule.getMarkerData(undefined, undefined, this));
        if (this.revisionType === 'Deletion') {
            blockInfo = selection.getParagraphInfo(this.owner.selectionModule.start);
            selection.editPosition = this.owner.selectionModule.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString());
        }
        else {
            selection.editPosition = this.owner.selectionModule.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString());
        }
        this.owner.editorModule.updateInsertPosition();
        this.isContentRemoved = false;
        this.canSkipTableItems = false;
        this.skipUnLinkElement = false;
        // Implement to accept/reject the revision
        if (this.revisionType === 'Insertion' || this.revisionType === 'Deletion' || this.revisionType === 'MoveFrom' || this.revisionType === 'MoveTo') {
            this.owner.isShiftingEnabled = true;
            var rangeIndex = 0;
            while (this.getRange().length > 0) {
                if (this.getRange()[rangeIndex] instanceof ElementBox || this.getRange()[rangeIndex] instanceof WCharacterFormat || this.getRange()[rangeIndex] instanceof WRowFormat) {
                    if (this.getRange()[rangeIndex] instanceof BookmarkElementBox && isFromAccept && this.revisionType === 'Deletion') {
                        var inline = this.getRange()[rangeIndex];
                        if (this.owner.documentHelper.bookmarks.containsKey(inline.name)) {
                            this.owner.documentHelper.bookmarks.remove(inline.name);
                        }
                    }
                    var moveToNextItem = this.unlinkRangeItem(this.getRange()[rangeIndex], this, isFromAccept, startPos, endPos);
                    if (moveToNextItem) {
                        rangeIndex++;
                    }
                    else {
                        rangeIndex = 0;
                    }
                }
                else {
                    break;
                }
            }
        }
        this.isTableRevision = false;
        if (this.isContentRemoved) {
            var textPosition = selection.getTextPosBasedOnLogicalIndex(selection.editPosition);
            this.owner.selectionModule.selectContent(textPosition, true);
            this.owner.editorModule.updateEndPosition();
        }
        else {
            selection.selectRange(startPos, endPos);
            this.owner.editorModule.updateHistoryPosition(endPos, false);
            if (!isNullOrUndefined(this.owner.editorHistory) && !isNullOrUndefined(this.owner.editorHistory.currentHistoryInfo) && (this.owner.editorHistory.currentHistoryInfo.action === 'Accept All' || this.owner.editorHistory.currentHistoryInfo.action === 'Reject All') && !blockInfo.paragraph.isInHeaderFooter) {
                var start = this.owner.selection.getTextPosBasedOnLogicalIndex(startIndex);
                var end = this.owner.selection.getTextPosBasedOnLogicalIndex(endIndex);
                this.owner.selection.selectPosition(start, end, true);
                this.owner.editorHistory.currentHistoryInfo.insertPosition = this.owner.selection.startOffset;
                this.owner.editorHistory.currentHistoryInfo.endPosition = this.owner.selection.endOffset;
            }
        }
        if (this.owner.editorHistoryModule && this.owner.editorHistoryModule.currentBaseHistoryInfo
            && this.owner.editorHistoryModule.currentBaseHistoryInfo.action !== 'BackSpace') {
            this.owner.editorHistoryModule.currentBaseHistoryInfo.removedNodes.reverse();
        }
        if (this.owner.editorHistoryModule) {
            var editorHistory = this.owner.editorHistoryModule;
            if (editorHistory.currentHistoryInfo && (editorHistory.currentHistoryInfo.action === 'Accept All' || editorHistory.currentHistoryInfo.action === 'Reject All')) {
                if (this.owner.documentHelper.blockToShift) {
                    this.owner.documentHelper.layout.shiftLayoutedItems(false);
                }
            }
            editorHistory.updateHistory();
            if (removeChanges && this.owner.editorHistory && !isNullOrUndefined(this.owner.editorHistory.currentHistoryInfo)) {
                for (var k = 0; k < comments.length; k++) {
                    // Reset the removedIds array of the current comment element to an empty array.
                    if (comments[k].indexInOwner < 0) {
                        //Deleting revision from comment
                        var index = comments[k].getAllRevision().indexOf(this);
                        if (index !== -1) {
                            comments[k].removeRevision(index);
                        }
                        comments[k].removedIds = [];
                        this.owner.editorModule.initInsertInline(comments[k], false);
                    }
                }
                this.owner.editorHistory.currentHistoryInfo.endPosition = this.owner.selection.startOffset;
                this.owner.editorHistory.updateComplexHistory();
            }
        }
        if (!isGroupAcceptOrReject) {
            if (this.owner.selectionModule.start.paragraph.isInsideTable) {
                var table = this.owner.selectionModule.start.paragraph.containerWidget.ownerTable;
                this.owner.documentHelper.layout.reLayoutTable(table);
            }
            this.owner.editorModule.reLayout(this.owner.selectionModule);
        }
        if (blockInfo.paragraph.isInHeaderFooter) {
            this.owner.editorModule.updateHeaderFooterWidget();
        }
    };
    Revision.prototype.handleGroupAcceptReject = function (revision, isAccept) {
        var removeChanges = (!isNullOrUndefined(isAccept)) && ((this.revisionType === 'MoveFrom' || this.revisionType === 'Deletion') && isAccept) || ((this.revisionType === 'Insertion' || this.revisionType === 'MoveTo') && !isAccept);
        if (revision.length > 0) {
            if (!removeChanges) {
                var start = this.owner.selection.start.clone();
                var end = this.owner.selectionModule.end.clone();
                this.owner.editorModule.initComplexHistory(isAccept ? 'Accept All' : 'Reject All');
                this.owner.selectionModule.selectRevision(this);
                this.owner.selection.isModifyingSelectionInternally = true;
                while (revision.length > 0) {
                    if (isAccept) {
                        revision[revision.length - 1].handleAcceptReject(true, true);
                    }
                    else {
                        revision[revision.length - 1].handleAcceptReject(false, true);
                    }
                }
                if (this.owner.selectionModule.start.paragraph.isInsideTable) {
                    var table = this.owner.selectionModule.start.paragraph.containerWidget.ownerTable;
                    this.owner.documentHelper.layout.reLayoutTable(table);
                }
                this.owner.selection.isModifyingSelectionInternally = false;
                this.owner.selection.selectPosition(start, end, true);
                if (!isNullOrUndefined(this.owner.editorHistory) && !isNullOrUndefined(this.owner.editorHistory.currentHistoryInfo) && (this.owner.editorHistory.currentHistoryInfo.action === 'Accept All' || this.owner.editorHistory.currentHistoryInfo.action === 'Reject All')) {
                    this.owner.editorHistory.currentHistoryInfo.insertPosition = this.owner.selection.startOffset;
                    this.owner.editorHistory.currentHistoryInfo.endPosition = this.owner.selection.endOffset;
                }
                if (this.owner.editorHistoryModule) {
                    this.owner.editorHistoryModule.updateComplexHistory();
                }
            }
            else {
                this.deleteTrackedContents(isAccept);
            }
        }
    };
    Revision.prototype.deleteTrackedContents = function (isAccept) {
        //The boolean was used to check that if the revision from the item was was already removed or not.
        var isItemAlreadyUnlinked = this.owner.selectionModule.selectRevision(this, undefined, undefined, undefined, true, isAccept);
        if (!isItemAlreadyUnlinked) {
            var removeChanges = (!isNullOrUndefined(isAccept)) && ((this.revisionType === 'MoveFrom' || this.revisionType === 'Deletion') && isAccept) || ((this.revisionType === 'Insertion' || this.revisionType === 'MoveTo') && !isAccept);
            var comments = void 0;
            if (removeChanges) {
                var commentInfo = this.owner.editorModule.getSelectedComments();
                if (commentInfo.commentEndInfo.length > 0 || commentInfo.commentStartInfo.length > 0) {
                    comments = this.owner.editorModule.checkAndRemoveComments(false, true);
                }
                else {
                    removeChanges = false;
                }
            }
            this.owner.editorModule.initHistory(isAccept ? 'Accept Change' : 'Reject Change');
            this.owner.editorModule.deleteSelectedContents(this.owner.selectionModule, true);
            if (!isNullOrUndefined(this.owner.editorHistory) && this.owner.editorHistoryModule.currentBaseHistoryInfo) {
                this.owner.editorHistoryModule.currentBaseHistoryInfo.isAcceptOrReject = isAccept ? 'Accept' : 'Reject';
            }
            if (!isNullOrUndefined(this.owner.editorHistory) && !isNullOrUndefined(this.owner.editorHistory.currentHistoryInfo) && (this.owner.editorHistory.currentHistoryInfo.action === 'Accept All' || this.owner.editorHistory.currentHistoryInfo.action === 'Reject All')) {
                this.owner.editorHistory.currentHistoryInfo.insertPosition = this.owner.selection.startOffset;
                this.owner.editorHistory.currentHistoryInfo.endPosition = this.owner.selection.endOffset;
            }
            this.owner.editorModule.reLayout(this.owner.selectionModule, undefined, undefined, true);
            if (removeChanges && this.owner.editorHistory && !isNullOrUndefined(this.owner.editorHistory.currentHistoryInfo)) {
                for (var k = 0; k < comments.length; k++) {
                    // Reset the removedIds array of the current comment element to an empty array.
                    if (comments[k].indexInOwner < 0) {
                        //Deleting revision from comment
                        var index = comments[k].getAllRevision().indexOf(this);
                        if (index !== -1) {
                            comments[k].removeRevision(index);
                        }
                        comments[k].removedIds = [];
                        this.owner.editorModule.initInsertInline(comments[k], false);
                    }
                }
                this.owner.editorHistory.currentHistoryInfo.endPosition = this.owner.selection.startOffset;
                this.owner.editorHistory.updateComplexHistory();
            }
        }
    };
    /**
     * Method which accepts the selected revision, revision marks will be removed and changes will be included in the viewer.
     *
     * @returns {void}
     */
    Revision.prototype.accept = function () {
        var eventArgs = { author: this.author, cancel: false, revisionType: this.revisionType, actionType: 'Accept', source: this };
        this.owner.trigger(revisionActionEvent, eventArgs);
        if (eventArgs.cancel) {
            return;
        }
        var handled = false;
        if (!this.owner.documentHelper.isTrackedOnlyMode) {
            var revisions = [];
            if (!isNullOrUndefined(this.owner.trackChangesPane.changes.get(this))) {
                revisions = this.owner.revisions.groupedView.get(this.owner.trackChangesPane.changes.get(this));
            }
            if (revisions.length > 1) {
                this.handleGroupAcceptReject(revisions, true);
                handled = true;
            }
            if (!handled) {
                this.handleAcceptReject(true, false);
            }
        }
    };
    /**
     * Method which rejects the selected revision, revision marks will be removed leaving the original content.
     */
    Revision.prototype.reject = function () {
        var eventArgs = { author: this.author, cancel: false, revisionType: this.revisionType, actionType: 'Reject', source: this };
        this.owner.trigger(revisionActionEvent, eventArgs);
        if (eventArgs.cancel) {
            return;
        }
        var handled = false;
        if (!this.owner.documentHelper.isTrackedOnlyMode) {
            var revisions = [];
            if (!isNullOrUndefined(this.owner.trackChangesPane.changes.get(this))) {
                revisions = this.owner.revisions.groupedView.get(this.owner.trackChangesPane.changes.get(this));
            }
            if (revisions.length > 1) {
                this.handleGroupAcceptReject(revisions, false);
                handled = true;
            }
            if (!handled) {
                this.handleAcceptReject(false, false);
            }
        }
    };
    /**
     * Select the current revision.
     */
    Revision.prototype.select = function () {
        this.owner.selectionModule.selectRevision(this);
    };
    /**
     * Unlinks revision and its assosiated range
     * @private
     * @param item
     * @param revision
     * @param isFromAccept
     */
    /* eslint-disable  */
    Revision.prototype.unlinkRangeItem = function (item, revision, isFromAccept, start, end) {
        if (this.isTableRevision) {
            this.removeCurrentRevisionFromItem(item);
            if (revision.getRange().length === 0) {
                this.owner.revisions.remove(revision);
            }
            return false;
        }
        var removeChanges = (!isNullOrUndefined(isFromAccept)) && ((revision.revisionType === 'MoveFrom' || revision.revisionType === 'Deletion') && isFromAccept) || ((revision.revisionType === 'Insertion' || revision.revisionType === 'MoveTo') && !isFromAccept);
        if (this.owner.selectionModule.isTOC()) {
            if (removeChanges) {
                this.owner.editorModule.deleteSelectedContents(this.owner.selectionModule, true);
                if (revision.getRange().length === 0) {
                    this.owner.revisions.remove(revision);
                }
                this.isContentRemoved = true;
                this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'BackSpace';
            }
            else {
                while (this.getRange().length > 0) {
                    var currentElement = this.getRange()[0];
                    this.removeCurrentRevisionFromItem(currentElement);
                    if (revision.getRange().length === 0) {
                        this.owner.revisions.remove(revision);
                    }
                }
                this.owner.editorModule.addRemovedNodes(this.revisionID);
                this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'ClearRevisions';
            }
            return false;
        }
        if (item instanceof ElementBox && !this.canSkipTableItems) {
            if (removeChanges) {
                if (!this.skipeElementRemoval(item)) {
                    this.owner.editorModule.addRemovedNodes(item.clone());
                }
                else {
                    this.skipUnLinkElement = true;
                    return true;
                }
            }
            else {
                // Bug 873011: Handled the hyperlink formatting preservation when rejecting the RemoveHyperlink action.
                var fieldBegin = this.owner.selectionModule.getHyperlinkField();
                if (!isFromAccept && !isNullOrUndefined(fieldBegin) && fieldBegin == item && !isNullOrUndefined(fieldBegin.fieldEnd)) {
                    this.owner.editorModule.initComplexHistory('ClearRevisions');
                    this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'ClearRevisions';
                    this.updateRevisionID();
                    this.removeRevisionFromPara(start, end);
                    if (!isNullOrUndefined(this.owner.editorHistoryModule)) {
                        this.owner.editorHistoryModule.currentBaseHistoryInfo.isHyperlinkField = true;
                        var endInfo = this.owner.selectionModule.getParagraphInfo(end);
                        var endIndex = this.owner.selectionModule.getHierarchicalIndex(endInfo.paragraph, endInfo.offset.toString());
                        this.owner.editorHistoryModule.currentBaseHistoryInfo.endPosition = endIndex;
                        this.owner.editorHistoryModule.currentBaseHistoryInfo.selectionEnd = endIndex;
                        this.owner.editorHistoryModule.updateHistory();
                    }
                    if (this.owner.enableTrackChanges) {
                        this.owner.enableTrackChanges = false;
                        this.owner.editorModule.updateHyperlinkFormat(this.owner.selectionModule);
                        this.owner.enableTrackChanges = true;
                    }
                    else {
                        this.owner.editorModule.updateHyperlinkFormat(this.owner.selectionModule);
                    }
                    if (this.owner.editorHistoryModule && !isNullOrUndefined(this.owner.editorHistoryModule.currentHistoryInfo)) {
                        this.owner.editorHistoryModule.updateComplexHistory();
                    }
                }
                else {
                    this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'ClearRevisions';
                    this.updateRevisionID();
                    this.removeRevisionFromPara(start, end);
                }
            }
        }
        else if (!this.canSkipTableItems && (item instanceof WCharacterFormat) && (!removeChanges)) {
            this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'ClearRevisions';
            this.updateRevisionID();
            this.removeRevisionFromPara(start, end);
            var paragraphInfo = this.owner.selection.getParagraphInfo(start);
            var endParagraphInfo = this.owner.selection.getParagraphInfo(end);
            var startIndex = this.owner.selection.getHierarchicalIndex(paragraphInfo.paragraph, paragraphInfo.offset.toString());
            var endIndex = this.owner.selection.getHierarchicalIndex(endParagraphInfo.paragraph, endParagraphInfo.offset.toString());
            if (this.owner.documentHelper.isFollowedListLayoutRequired) {
                var paragraph = paragraphInfo.paragraph.combineWidget(this.owner.viewer);
                this.owner.documentHelper.layout.reLayoutParagraph(paragraph, 0, 0, undefined, undefined);
                var startPos = this.owner.selection.getTextPosBasedOnLogicalIndex(startIndex);
                start.setPositionInternal(startPos);
                var endPos = this.owner.selection.getTextPosBasedOnLogicalIndex(endIndex);
                end.setPositionInternal(endPos);
            }
        }
        else if (item instanceof WRowFormat && !removeChanges) {
            this.isTableRevision = true;
            var tableWidget = item.ownerBase.ownerTable;
            var currentRow = item.ownerBase;
            this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'RemoveRowTrack';
            if (this.owner.enableCollaborativeEditing) {
                this.owner.editorHistoryModule.currentBaseHistoryInfo.createAcceptRejectRowOperation('RemoveRowTrack', currentRow);
            }
            this.owner.editorModule.cloneTableToHistoryInfo(tableWidget.combineWidget(this.owner.viewer));
        }
        removeChanges = removeChanges && !this.canSkipTableItems;
        if (item instanceof ElementBox && removeChanges) {
            var currentPara = item.line.paragraph;
            this.removeAllRevisionsFromItem(item);
            if (item instanceof FootnoteElementBox) {
                if (item.footnoteType === 'Footnote') {
                    this.owner.editorModule.removeFootnote(item);
                }
                else {
                    this.owner.editorModule.removeEndnote(item);
                }
            }
            else if (item instanceof ShapeElementBox) {
                this.owner.editorModule.removeDeletedShapeRevision(item);
            }
            this.removeItem(item);
            this.isContentRemoved = true;
            var skipRelayout = !isNullOrUndefined(currentPara) && !isNullOrUndefined(currentPara.bodyWidget) && currentPara.bodyWidget instanceof HeaderFooterWidget && (isNullOrUndefined(currentPara.bodyWidget.page) || (!isNullOrUndefined(currentPara.bodyWidget.page) && currentPara.bodyWidget.page.index === -1));
            if (!skipRelayout) {
                this.owner.documentHelper.layout.reLayoutParagraph(currentPara, 0, 0);
            }
            if (isNullOrUndefined(currentPara.childWidgets)) {
                var textPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(this.owner.selectionModule.editPosition);
                this.owner.selectionModule.selectContent(textPosition, true);
            }
        }
        else if (item instanceof WCharacterFormat && removeChanges) {
            this.isContentRemoved = true;
            this.skipUnLinkElement = false;
            this.owner.editor.addRemovedRevisionInfo(item);
            this.removeAllRevisionsFromItem(item);
            if (revision.getRange().length === 1) {
                this.owner.editorModule.deleteSelectedContents(this.owner.selectionModule, true);
            }
            else {
                this.owner.editorModule.deleteSelectedContents(this.owner.selectionModule, true);
                this.removeRevisionFromPara(start, end);
                var rangeIndex = revision.getRange().indexOf(item);
                if (rangeIndex >= 0) {
                    revision.getRange().splice(rangeIndex, 1);
                }
                this.owner.trackChangesPane.updateCurrentTrackChanges(revision);
                while (this.getRange().length > 0) {
                    this.removeCurrentRevisionFromItem(this.getRange()[0]);
                }
            }
            this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'BackSpace';
            this.owner.editorHistoryModule.currentBaseHistoryInfo.isAcceptOrReject = isFromAccept ? 'Accept' : 'Reject';
        }
        else if (item instanceof WRowFormat && removeChanges) {
            var tableWidget = item.ownerBase.ownerTable;
            tableWidget = tableWidget.combineWidget(this.owner.viewer);
            var currentRow = item.ownerBase;
            this.owner.editor.addRemovedRevisionInfo(item);
            this.removeAllRevisionsFromItem(item);
            this.owner.editorHistoryModule.currentBaseHistoryInfo.action = 'DeleteCells';
            this.owner.editorHistoryModule.currentBaseHistoryInfo.isAcceptOrReject = isFromAccept ? 'Accept' : 'Reject';
            this.owner.editorModule.cloneTableToHistoryInfo(tableWidget);
            this.owner.editorModule.removeRevisionsInRow(currentRow);
            this.isContentRemoved = true;
            tableWidget.removeChild(tableWidget.childWidgets.indexOf(currentRow));
            this.canSkipTableItems = true;
            // Before destroying the table row widget, delete the field element from the row.
            this.owner.editorModule.removeFieldInBlock(currentRow);
            // Before destroying the table row widget, delete the bookmark element from the row.
            this.owner.editorModule.removeFieldInBlock(currentRow, true);
            // Before destroying the table row widget, delete the content control element from the row.
            this.owner.editorModule.removeFieldInBlock(currentRow, undefined, true);
            //currentRow.destroy();
            if (tableWidget.childWidgets.length === 0) {
                this.owner.selectionModule.editPosition = this.owner.selectionModule.getHierarchicalIndex(tableWidget, '0');
                this.owner.editorModule.removeBlock(tableWidget);
                //tableWidget.destroy();
            }
            else {
                this.owner.editorModule.updateTable(tableWidget, true);
            }
        }
        // if the range is of row format, we will remove the row and for history preservation we use whole table to be cloned, hence skipping this part
        if (!(item instanceof WRowFormat) || !removeChanges) {
            if (!this.skipUnLinkElement) {
                this.removeCurrentRevisionFromItem(item);
                if (removeChanges && item instanceof BookmarkElementBox) {
                    this.owner.editorModule.removedBookmarkElements.push(item);
                }
                if (item instanceof BookmarkElementBox) {
                    if (this.owner.documentHelper.bookmarks.containsKey(item.name)) {
                        if (this.owner.enableCollaborativeEditing && !isNullOrUndefined(this.owner.editorHistory.currentBaseHistoryInfo)) {
                            this.owner.editorHistory.currentBaseHistoryInfo.markerData.push({ bookmarkName: item.name });
                        }
                        this.owner.documentHelper.bookmarks.remove(item.name);
                    }
                }
            }
        }
        if (revision.getRange().length === 0) {
            this.owner.revisions.remove(revision);
        }
        return false;
    };
    Revision.prototype.removeRevisionFromPara = function (start, end) {
        var blockInfo = this.owner.selectionModule.getParagraphInfo(start);
        var endBlockInfo = this.owner.selectionModule.getParagraphInfo(end);
        var para = blockInfo.paragraph;
        while (para instanceof ParagraphWidget) {
            if (para.characterFormat.revisionLength > 0) {
                for (var i = 0; i < para.characterFormat.revisionLength; i++) {
                    if (para.characterFormat.getRevision(i).getRange().length === 0) {
                        var revisionIndex = para.characterFormat.getAllRevision().indexOf(para.characterFormat.getRevision(i));
                        para.characterFormat.removeRevision(revisionIndex);
                        i--;
                    }
                }
            }
            if (endBlockInfo.paragraph === para) {
                para = undefined;
            }
            else {
                para = para.nextWidget;
            }
        }
    };
    Revision.prototype.updateRevisionID = function () {
        this.owner.editorModule.addRemovedNodes(this.revisionID);
        while (this.getRange().length > 0) {
            this.removeCurrentRevisionFromItem(this.getRange()[0], true);
        }
        this.owner.trackChangesPane.updateCurrentTrackChanges(this);
    };
    /* eslint-disable @typescript-eslint/no-explicit-any */
    Revision.prototype.removeAllRevisionsFromItem = function (item) {
        if (item.revisions.length > 0) {
            for (var i = item.revisionLength - 1; i >= 0; i--) {
                var currentRevision = item.revisions[i];
                // let rangeIndex: number = currentRevision.getRange().indexOf(item);
                // item.revisions[revisionIndex].getRange().splice(rangeIndex, 1);
                item.removeRevision(item.getAllRevision().indexOf(currentRevision));
                this.owner.trackChangesPane.updateCurrentTrackChanges(currentRevision);
                // Added condition to removed the another revision from collection which is present in the item. The current revision will be removed at the end of the unlinkRangeItem method. 
                if (this.revisionID !== currentRevision.revisionID) {
                    if (currentRevision.getRange().length === 0) {
                        this.owner.revisions.remove(currentRevision);
                    }
                }
            }
        }
    };
    /**
     * Method to remove current revision from the item
     *
     * @private
     * @param {any} item - Specifies the item
     * @returns {void}
     */
    /* eslint-disable @typescript-eslint/no-explicit-any */
    Revision.prototype.removeCurrentRevisionFromItem = function (item, skipUpdate) {
        var revisionIndex = item.getAllRevision().indexOf(this);
        if (revisionIndex >= 0) {
            item.removeRevision(revisionIndex);
            if (!skipUpdate) {
                this.owner.trackChangesPane.updateCurrentTrackChanges(this);
            }
        }
    };
    /**
     * @private
     * @param {Element} element - Specifies the element.
     * @returns {boolean} Resturs skip element removal
     */
    Revision.prototype.skipeElementRemoval = function (element) {
        var elementPara = element.paragraph;
        if (elementPara.characterFormat.revisionLength > 0) {
            for (var i = 0; i < elementPara.characterFormat.revisionLength; i++) {
                var currentRevision = elementPara.characterFormat.getRevision(i);
                var rangeIndex = currentRevision.getRange().indexOf(element);
                if (rangeIndex >= 0 && currentRevision.revisionID === this.revisionID) {
                    return true;
                }
            }
        }
        return false;
    };
    Revision.prototype.removeItem = function (element) {
        var paraWidget = element.line.paragraph;
        this.owner.editorModule.unLinkFieldCharacter(element);
        this.owner.editorModule.triggerChangeDetected(element);
        var elementIndex = element.line.children.indexOf(element);
        var previousNode = element.previousNode;
        element.line.children.splice(elementIndex, 1);
        if (!isNullOrUndefined(previousNode)) {
            this.owner.editorModule.combineElementRevisionToPrevNxt(previousNode);
        }
        var paraFloatingElementIndex = element.line.paragraph.floatingElements.indexOf(element);
        element.line.paragraph.floatingElements.splice(paraFloatingElementIndex, 1);
        var blockFloatingElementIndex = element.line.paragraph.bodyWidget.floatingElements.indexOf(element);
        if (blockFloatingElementIndex > -1) {
            element.line.paragraph.bodyWidget.floatingElements.splice(blockFloatingElementIndex, 1);
        }
        this.owner.editorModule.removeEmptyLine(paraWidget);
    };
    Revision.prototype.canSkipCloning = function () {
        if (!isNullOrUndefined(this.owner) && this.owner.editorHistoryModule && this.owner.editorHistoryModule.currentBaseHistoryInfo) {
            var baseHistoryInfo = this.owner.editorHistoryModule.currentBaseHistoryInfo;
            if (baseHistoryInfo.action === 'DeleteCells') {
                return true;
            }
        }
        return false;
    };
    /**
     * @private
     *
     */
    Revision.prototype.destroy = function () {
        this.author = undefined;
        this.revisionType = undefined;
        this.revisionID = undefined;
        this.date = undefined;
        this.range = [];
        this.range = undefined;
        this.owner = undefined;
        this.ownerNode = undefined;
        this.customData = undefined;
    };
    /**
     * @private
     * @returns {Revision} - Returns revision
     */
    Revision.prototype.clone = function () {
        if (this.canSkipCloning()) {
            return this;
        }
        var revision = new Revision(undefined, this.author, this.date);
        revision.revisionID = this.revisionID;
        revision.revisionType = this.revisionType;
        revision.customData = this.customData;
        return revision;
    };
    /**
     * @private
     */
    Revision.prototype.cloneRevision = function () {
        var revision = new Revision(this.owner, this.author, this.date);
        revision.revisionID = this.revisionID;
        revision.revisionType = this.revisionType;
        revision.author = this.author;
        revision.date = this.date;
        revision.customData = this.customData;
        return revision;
    };
    /**
     * Method to clone the revisions for the element
     *
     * @param {Revision[]} revisions - revision array.
     * @returns {string[]} - returns clones revisions.
     */
    Revision.cloneRevisions = function (revisions) {
        var clonedRevisions = [];
        for (var i = 0; i < revisions.length; i++) {
            clonedRevisions.push(revisions[i].revisionID);
        }
        return clonedRevisions;
    };
    return Revision;
}());
export { Revision };
/**
 * Represents the revision collections in the document.
 */
var RevisionCollection = /** @class */ (function () {
    function RevisionCollection(owner) {
        /**
         * @private
         */
        this.revisions = [];
        /**
         * @private
         */
        this.changes = [];
        /**
         * @private
         */
        this.isAcceptAllOrRejectAll = false;
        this.owner = owner;
    }
    /**
     * @private
     */
    RevisionCollection.prototype.get = function (index) {
        if (index >= this.revisions.length || index < 0) {
            throw new ReferenceError('Provided index is not within the range');
        }
        return this.revisions[index];
    };
    Object.defineProperty(RevisionCollection.prototype, "length", {
        get: function () {
            return this.revisions.length;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @private
     */
    RevisionCollection.prototype.checkAndGetPreviousRevisionToCombine = function (revision) {
        var range = revision.getRange();
        var revisionToCombine;
        if (range.length > 0) {
            var firstElement = range[0];
            if (firstElement instanceof ElementBox) {
                var previousElement = this.owner.editor.getPreviousNodeRevision(firstElement.previousNode);
                var currentParagraph = firstElement.paragraph.getSplitWidgets()[0];
                var skipAuthorCheck = currentParagraph.containerWidget instanceof TableCellWidget && currentParagraph.containerWidget.ownerRow.rowFormat.revisionLength > 0;
                var previousBlock = currentParagraph.previousRenderedWidget;
                var commonRevision = [];
                if ((previousElement instanceof ElementBox && previousElement.revisionLength > 0 && this.isSameRevisionType(previousElement.getAllRevision(), revision, commonRevision, skipAuthorCheck)) ||
                    (isNullOrUndefined(previousElement) && previousBlock instanceof ParagraphWidget && previousBlock.characterFormat.revisionLength > 0
                        && this.isSameRevisionType(previousBlock.characterFormat.getAllRevision(), revision, commonRevision, skipAuthorCheck))) {
                    if (commonRevision.length > 0) {
                        revisionToCombine = commonRevision[0];
                    }
                }
            }
            else if (firstElement instanceof WCharacterFormat) {
                var block = firstElement.ownerBase;
                var splittedParagraph = block.getSplitWidgets();
                var skipAuthorCheck = splittedParagraph[splittedParagraph.length - 1].containerWidget instanceof TableCellWidget && splittedParagraph[splittedParagraph.length - 1].containerWidget.ownerRow.rowFormat.revisionLength > 0;
                var previousBlock = splittedParagraph[0].previousRenderedWidget;
                var previousElement = void 0;
                var commonRevision = [];
                if (block.isEmpty() && previousBlock instanceof ParagraphWidget) {
                    previousElement = previousBlock.characterFormat;
                }
                else {
                    var lastLine = splittedParagraph[splittedParagraph.length - 1].lastChild;
                    previousElement = this.owner.editor.getPreviousNodeRevision(lastLine.children[lastLine.children.length - 1]);
                    if (isNullOrUndefined(previousElement) && previousBlock instanceof ParagraphWidget) {
                        previousElement = previousBlock.characterFormat;
                    }
                }
                if (!isNullOrUndefined(previousElement) && previousElement.revisionLength > 0 && this.isSameRevisionType(previousElement.getAllRevision(), revision, commonRevision, skipAuthorCheck)) {
                    if (commonRevision.length > 0) {
                        revisionToCombine = commonRevision[0];
                    }
                }
            }
            else if (firstElement instanceof WRowFormat) {
                var rowWidget = firstElement.ownerBase;
                var skipAuthorCheck = rowWidget.ownerTable.containerWidget instanceof TableCellWidget && rowWidget.ownerTable.containerWidget.ownerRow.rowFormat.revisionLength > 0;
                var previousRow = rowWidget.previousRenderedWidget;
                var commonRevision = [];
                if (!isNullOrUndefined(previousRow) && previousRow.rowFormat.revisionLength > 0 && this.isSameRevisionType(previousRow.rowFormat.getAllRevision(), revision, commonRevision, skipAuthorCheck)) {
                    if (commonRevision.length > 0) {
                        revisionToCombine = commonRevision[0];
                    }
                }
            }
            if (isNullOrUndefined(revisionToCombine)) {
                var block = void 0;
                if (firstElement instanceof ElementBox) {
                    block = firstElement.paragraph;
                }
                else if (firstElement instanceof WCharacterFormat) {
                    block = firstElement.ownerBase;
                }
                else if (firstElement instanceof WRowFormat) {
                    block = firstElement.ownerBase.ownerTable;
                }
                var container = block.containerWidget;
                if (container instanceof TableCellWidget) {
                    var rowFormat = container.ownerRow.rowFormat;
                    var commonRevision = [];
                    if (rowFormat.revisionLength > 0 && this.isSameRevisionType(rowFormat.getAllRevision(), revision, commonRevision, true)) {
                        revisionToCombine = commonRevision[0];
                    }
                }
            }
        }
        return revisionToCombine;
    };
    /**
     * @private
     */
    RevisionCollection.prototype.checkAndGetNextRevisionToCombine = function (revision) {
        var range = revision.getRange();
        if (range.length > 0) {
            var firstElement = range[0];
            var lastElement = range[range.length - 1];
            if (firstElement instanceof ElementBox) {
                var nextNode = lastElement.nextNode;
                var currentParagraph = firstElement.paragraph.getSplitWidgets()[0];
                var skipAuthorCheck = currentParagraph.containerWidget instanceof TableCellWidget && currentParagraph.containerWidget.ownerRow.rowFormat.revisionLength > 0;
                var commonRevision = [];
                if ((nextNode instanceof ElementBox && nextNode.revisionLength > 0 && this.isSameRevisionType(nextNode.getAllRevision(), revision, commonRevision, skipAuthorCheck)) ||
                    (isNullOrUndefined(nextNode) && currentParagraph.characterFormat.revisionLength > 0 && this.isSameRevisionType(currentParagraph.characterFormat.getAllRevision(), revision, commonRevision, skipAuthorCheck))) {
                    if (commonRevision.length > 0) {
                        return commonRevision[0];
                    }
                }
            }
            else if (firstElement instanceof WCharacterFormat) {
                var block = firstElement.ownerBase;
                var splittedParagraph = block.getSplitWidgets();
                var skipAuthorCheck = splittedParagraph[splittedParagraph.length - 1].containerWidget instanceof TableCellWidget && splittedParagraph[splittedParagraph.length - 1].containerWidget.ownerRow.rowFormat.revisionLength > 0;
                var nextBlock = splittedParagraph[splittedParagraph.length - 1].nextRenderedWidget;
                var nextElement = void 0;
                if (nextBlock instanceof ParagraphWidget) {
                    if (nextBlock.isEmpty()) {
                        nextElement = nextBlock.characterFormat;
                    }
                    else {
                        nextElement = this.owner.editor.getNextNodeRevision(nextBlock.firstChild.children[0]);
                        if (isNullOrUndefined(nextElement) && nextBlock instanceof ParagraphWidget) {
                            nextElement = nextBlock.characterFormat;
                        }
                    }
                }
                var commonRevision = [];
                if (!isNullOrUndefined(nextElement) && nextElement.revisionLength > 0 && this.isSameRevisionType(nextElement.getAllRevision(), revision, commonRevision, skipAuthorCheck)) {
                    return commonRevision[0];
                }
            }
            else if (firstElement instanceof WRowFormat) {
                var rowWidget = firstElement.ownerBase;
                var skipAuthorCheck = rowWidget.ownerTable.containerWidget instanceof TableCellWidget && rowWidget.ownerTable.containerWidget.ownerRow.rowFormat.revisionLength > 0;
                var nextRow = rowWidget.nextRenderedWidget;
                var commonRevision = [];
                if (!isNullOrUndefined(nextRow) && nextRow.rowFormat.revisionLength > 0 && this.isSameRevisionType(nextRow.rowFormat.getAllRevision(), revision, commonRevision, skipAuthorCheck)) {
                    if (commonRevision.length > 0) {
                        return commonRevision[0];
                    }
                }
            }
        }
        return undefined;
    };
    /**
     * @private
     */
    RevisionCollection.prototype.addRevision = function (revision) {
        this.insertRevisionAt(this.changes.length, revision);
    };
    /**
     * @private
     */
    RevisionCollection.prototype.insertRevisionAt = function (index, revision) {
        var previousRevision = this.checkAndGetPreviousRevisionToCombine(revision);
        var nextRevision = this.checkAndGetNextRevisionToCombine(revision);
        if (previousRevision) {
            this.combineWithExistingRevision(index, revision, previousRevision, false);
            if (nextRevision) {
                this.combineWithNextRevision(revision, nextRevision);
            }
        }
        else if (nextRevision && !isNullOrUndefined(this.owner.trackChangesPane.changes.get(nextRevision))) {
            this.combineWithExistingRevision(index, revision, nextRevision, true);
        }
        else {
            this.insertNewRevision(index, revision);
        }
        this.changes.splice(index, 0, revision);
    };
    RevisionCollection.prototype.getIndexToInsertInGroup = function (revisions, revisionToCombine, currentRevision, index) {
        // if the previous row has a revision, It will return the row revision index not the child blocks. In that case we need to calculate the index based on the child blocks.
        if (revisionToCombine.ownerNode instanceof WRowFormat) {
            //Get previous revision to get the index to insert in grouped revision.
            var previousRevision = this.changes[index - 1];
            if (previousRevision === revisionToCombine) {
                return revisions.indexOf(revisionToCombine) + (this.changes.indexOf(revisionToCombine) < index ? 1 : 0);
            }
            else {
                if (revisions.indexOf(previousRevision) !== -1) {
                    return revisions.indexOf(previousRevision) + (this.changes.indexOf(previousRevision) < index ? 1 : 0);
                }
                else {
                    return revisions.indexOf(revisionToCombine) + (this.changes.indexOf(revisionToCombine) < index ? 1 : 0);
                }
            }
        }
        else {
            return revisions.indexOf(revisionToCombine) + (this.changes.indexOf(revisionToCombine) < index ? 1 : 0);
        }
    };
    RevisionCollection.prototype.combineWithExistingRevision = function (index, revision, revisionToCombine, nextRevision) {
        var currentChangeView = this.owner.trackChangesPane.changes.get(revisionToCombine);
        if (!currentChangeView) {
            return;
        }
        var revisions = this.owner.revisions.groupedView.get(currentChangeView);
        var insertIndex = this.getIndexToInsertInGroup(revisions, revisionToCombine, revision, index);
        revisions.splice(insertIndex, 0, revision);
        this.owner.trackChangesPane.changes.add(revision, currentChangeView);
        // When deleting the content it will be deleted in the reverse order. so that we need to update the owner node. If it is next node we need to update the revision because of owner node.
        if (nextRevision) {
            var revisionIndex = this.owner.revisions.revisions.indexOf(revisionToCombine);
            if (revisionIndex != -1) {
                this.owner.revisions.revisions.splice(revisionIndex, 1, revision);
                currentChangeView.revision = revision;
            }
        }
        if (revision.getRange().length > 0) {
            if (!isNullOrUndefined(currentChangeView.singleInnerDiv)) {
                this.clearChildren(currentChangeView.singleInnerDiv.querySelector("#textDiv"));
            }
            var ranges = [];
            for (var i = 0; i < revisions.length; i++) {
                ranges = ranges.concat(revisions[i].getRange());
            }
            currentChangeView.layoutElementText(revision, ranges, !isNullOrUndefined(currentChangeView.singleInnerDiv) ? currentChangeView.singleInnerDiv.querySelector("#textDiv") : undefined);
        }
    };
    RevisionCollection.prototype.clearChildren = function (element) {
        while (element.firstChild) {
            element.removeChild(element.firstChild);
        }
    };
    RevisionCollection.prototype.getNextRevision = function (index, previousRevision) {
        // If two revisions are present in the element there is possible of change in revision type. So that view will not be split. In this case, we need to check all the revision which are present in the element.
        // Retrun the revision are match to the previous revision. If not then it will return the next revision directly.
        var nextRevision = this.changes[index];
        if (nextRevision && previousRevision) {
            var range = nextRevision.getRange(true);
            if (range.length > 0) {
                var node = range[range.length - 1];
                var revisions = node.getAllRevision();
                for (var i = 0; i < revisions.length; i++) {
                    var revision = revisions[i];
                    if (previousRevision.author === revision.author && revision.revisionType === previousRevision.revisionType) {
                        return revision;
                    }
                }
            }
        }
        return nextRevision;
    };
    RevisionCollection.prototype.insertNewRevision = function (index, revision) {
        var previousRevision = this.changes[index - 1];
        var nextRevision = this.getNextRevision(index, previousRevision);
        var previousSingleView = previousRevision ? this.owner.trackChangesPane.changes.get(previousRevision) : undefined;
        var nextSingleView = nextRevision ? this.owner.trackChangesPane.changes.get(nextRevision) : undefined;
        var splitRevision = !isNullOrUndefined(previousRevision) && !isNullOrUndefined(previousSingleView) && previousSingleView === nextSingleView;
        // While inserting a new revision inside a tracked table cell, 
        // we do not want to split the remaining rows.
        // so we set splitRevision to false.
        if (splitRevision) {
            if (revision.ownerNode instanceof ParagraphWidget) {
                splitRevision = !(revision.ownerNode.containerWidget instanceof TableCellWidget && revision.ownerNode.containerWidget.ownerRow.rowFormat.revisionLength > 0);
            }
            else if (revision.ownerNode instanceof WCharacterFormat) {
                if (revision.ownerNode.ownerBase instanceof ParagraphWidget) {
                    splitRevision = !(revision.ownerNode.ownerBase.containerWidget instanceof TableCellWidget && revision.ownerNode.ownerBase.containerWidget.ownerRow.rowFormat.revisionLength > 0);
                    ;
                }
            }
            else if (revision.ownerNode instanceof WRowFormat) {
                if (revision.ownerNode.ownerBase instanceof TableRowWidget && revision.ownerNode.ownerBase.ownerTable.containerWidget instanceof TableCellWidget && revision.ownerNode.ownerBase.ownerTable.containerWidget.ownerRow.rowFormat.revisionLength > 0) {
                    splitRevision = false;
                }
            }
        }
        // When an inserted revision row is deleted by another user, a child revision will be created.
        // In that case, we don't want to split the remaining rows,
        // so we set splitRevision to false.
        if (revision.getRange().length > 0 && revision.getRange()[0].revisionLength > 1) {
            splitRevision = false;
        }
        var threadIndex = index;
        if (!isNullOrUndefined(previousSingleView) && !isNullOrUndefined(previousSingleView.outerSingleDiv)) {
            threadIndex = this.getChildIndexQuery(previousSingleView.outerSingleDiv);
        }
        var currentChangeView = new ChangesSingleView(this.owner, this.owner.trackChangesPane);
        this.owner.trackChangesPane.changesInfoDiv.insertBefore(currentChangeView.createSingleChangesDiv(revision), this.owner.trackChangesPane.changesInfoDiv.children[threadIndex + 1]);
        this.revisions.splice(threadIndex, 0, revision);
        this.owner.trackChangesPane.changes.add(revision, currentChangeView);
        this.owner.trackChangesPane.renderedChanges.add(revision, currentChangeView);
        currentChangeView.layoutElementText(revision, revision.getRange(), !isNullOrUndefined(currentChangeView.singleInnerDiv) ? currentChangeView.singleInnerDiv.querySelector("#textDiv") : undefined);
        this.groupedView.add(currentChangeView, [revision]);
        if (splitRevision) {
            // If two revisions are present in the element then we need to split the two revisions into two different views.
            var range = previousRevision.getRange(true);
            if (range.length > 0) {
                var node = range[range.length - 1];
                var revisions = node.getAllRevision();
                for (var i = 0; i < revisions.length; i++) {
                    var revision_1 = revisions[i];
                    var singleView = this.owner.trackChangesPane.changes.get(revision_1);
                    if (singleView) {
                        this.splitView(revision_1, singleView, currentChangeView, threadIndex + i + 1);
                    }
                }
            }
        }
    };
    /**
     * @private
     */
    RevisionCollection.prototype.splitView = function (previousRevision, previousSingleView, currentChangeView, threadIndex) {
        if (this.groupedView.containsKey(previousSingleView)) {
            var groupedRevisions = this.groupedView.get(previousSingleView);
            var previousIndex = groupedRevisions.indexOf(previousRevision);
            if (previousIndex !== -1) {
                var removedFromGroup = groupedRevisions.splice(previousIndex + 1);
                if (removedFromGroup.length > 0) {
                    this.createSplittedView(removedFromGroup, threadIndex);
                    // Resetting the revision in the revision collection and also in the single view revision,
                    // since the previous revision was split and included in the new single view.
                    var revisionIndex = this.revisions.indexOf(previousSingleView.revision);
                    if (revisionIndex !== -1) {
                        this.revisions.splice(revisionIndex, 1, previousRevision);
                    }
                    previousSingleView.revision = previousRevision;
                    //Adding the new revision into the revisionCollection for splitted single view.
                    this.revisions.splice(threadIndex, 0, removedFromGroup[0]);
                }
            }
            this.owner.trackChangesPane.updateCurrentTrackChanges(groupedRevisions[0]);
        }
    };
    RevisionCollection.prototype.createSplittedView = function (removedFromGroup, threadIndex) {
        var _this = this;
        var splittedView = new ChangesSingleView(this.owner, this.owner.trackChangesPane);
        var startRevision = removedFromGroup[0];
        removedFromGroup.forEach(function (movedRevision) {
            if (_this.owner.trackChangesPane.renderedChanges.containsKey(movedRevision)) {
                _this.owner.trackChangesPane.renderedChanges.remove(movedRevision);
            }
            if (_this.owner.trackChangesPane.changes.containsKey(movedRevision)) {
                _this.owner.trackChangesPane.changes.remove(movedRevision);
            }
            _this.owner.trackChangesPane.renderedChanges.add(movedRevision, splittedView);
            _this.owner.trackChangesPane.changes.add(movedRevision, splittedView);
        });
        this.owner.trackChangesPane.changesInfoDiv.insertBefore(splittedView.createSingleChangesDiv(startRevision), this.owner.trackChangesPane.changesInfoDiv.children[threadIndex + 1]);
        var ranges = [];
        for (var i = 0; i < removedFromGroup.length; i++) {
            ranges = ranges.concat(removedFromGroup[i].getRange());
        }
        splittedView.layoutElementText(startRevision, ranges, !isNullOrUndefined(splittedView.singleInnerDiv) ? splittedView.singleInnerDiv.querySelector("#textDiv") : undefined);
        this.groupedView.add(splittedView, removedFromGroup);
    };
    /**
     * @private
     */
    RevisionCollection.prototype.getChildIndexQuery = function (childElement) {
        var parent = childElement.parentElement;
        if (!parent)
            return -1;
        for (var i = 0; i < parent.children.length; i++) {
            if (parent.children[i] === childElement)
                return i;
        }
        return -1;
    };
    /**
     * @private
     */
    RevisionCollection.prototype.isSameRevisionType = function (previousRevision, currentRevision, commonRevision, skipAuthorCheck) {
        for (var i = 0; i < previousRevision.length; i++) {
            var isSameType = previousRevision[i].revisionType === currentRevision.revisionType;
            var isSameAuthor = previousRevision[i].author === currentRevision.author;
            if ((skipAuthorCheck && isSameType) || (!skipAuthorCheck && isSameType && isSameAuthor)) {
                commonRevision.push(previousRevision[i]);
                return true;
            }
        }
        return false;
    };
    RevisionCollection.prototype.remove = function (revision) {
        if (isNullOrUndefined(revision) || this.changes.indexOf(revision) < 0) {
            return;
        }
        if (this.owner.trackChangesPane.changes.containsKey(revision)) {
            var changesSingleView = this.owner.trackChangesPane.changes.get(revision);
            var removeIndex = this.changes.indexOf(revision);
            var previousRevision = this.changes[removeIndex - 1];
            var nextRevision = this.changes[removeIndex + 1];
            this.changes.splice(removeIndex, 1);
            var isParentRemoved = false;
            var removedIndex = this.revisions.indexOf(revision);
            var removedSortedRevisionIndex = this.owner.trackChangesPane.sortedRevisions.indexOf(revision);
            if (removedIndex !== -1) {
                this.revisions.splice(removedIndex, 1);
                isParentRemoved = true;
            }
            if (removedSortedRevisionIndex !== -1) {
                this.owner.trackChangesPane.sortedRevisions.splice(removedSortedRevisionIndex, 1);
            }
            var groupedRevision = this.groupedView.get(changesSingleView);
            var removeChild = groupedRevision.length === 1;
            if (removeChild && !isNullOrUndefined(changesSingleView.outerSingleDiv)) {
                this.owner.trackChangesPane.changesInfoDiv.removeChild(changesSingleView.outerSingleDiv);
            }
            if (groupedRevision) {
                var groupedIndex = groupedRevision.indexOf(revision);
                groupedRevision.splice(groupedIndex, 1);
                if (groupedRevision.length === 0) {
                    this.groupedView.remove(changesSingleView);
                    if (!isNullOrUndefined(previousRevision)) {
                        this.checkAndCombineWithNextRevision(previousRevision);
                    }
                }
                else {
                    var newParent = groupedRevision[0];
                    if (isParentRemoved) {
                        this.revisions.splice(removedIndex, 0, newParent);
                        this.owner.trackChangesPane.sortedRevisions.splice(removedSortedRevisionIndex, 0, newParent);
                        changesSingleView.revision = newParent;
                    }
                    newParent.hasChanges = true;
                    // // When removing the revision, it is necessary to split the view in the track changes pane. 
                    // const previousSingleView = previousRevision ? this.owner.trackChangesPane.changes.get(previousRevision) : undefined;
                    // const nextSingleView = nextRevision ? this.owner.trackChangesPane.changes.get(nextRevision) : undefined;
                    // const splitRevision = !isNullOrUndefined(previousRevision) && previousSingleView === nextSingleView;
                    // if (splitRevision) {
                    //     this.splitView(previousRevision, previousSingleView, nextSingleView);
                    // }
                }
            }
            this.owner.trackChangesPane.changes.remove(revision);
            if (this.owner.trackChangesPane.renderedChanges.containsKey(revision)) {
                this.owner.trackChangesPane.renderedChanges.remove(revision);
            }
        }
        else {
            this.changes.splice(this.changes.indexOf(revision), 1);
        }
    };
    RevisionCollection.prototype.checkAndCombineWithNextRevision = function (revisionToCheck) {
        var nextRevision = this.checkAndGetNextRevisionToCombine(revisionToCheck);
        if (!isNullOrUndefined(nextRevision)) {
            this.combineWithNextRevision(revisionToCheck, nextRevision);
        }
    };
    /**
     * @private
     */
    RevisionCollection.prototype.combineWithNextRevision = function (currentRevision, nextRevision) {
        var currentChangeView = this.owner.trackChangesPane.changes.get(currentRevision);
        var nextChangeView = this.owner.trackChangesPane.changes.get(nextRevision);
        if (!isNullOrUndefined(currentChangeView) && !isNullOrUndefined(nextChangeView) && currentChangeView !== nextChangeView) {
            var previousGroupedView = this.groupedView.get(currentChangeView);
            var nextGroupedView = this.groupedView.get(nextChangeView);
            if (!isNullOrUndefined(nextChangeView.outerSingleDiv)) {
                this.owner.trackChangesPane.changesInfoDiv.removeChild(nextChangeView.outerSingleDiv);
            }
            for (var i = 0; i < nextGroupedView.length; i++) {
                var revisionToMove = nextGroupedView[i];
                //Remove previous single view
                if (this.owner.trackChangesPane.renderedChanges.containsKey(revisionToMove)) {
                    this.owner.trackChangesPane.renderedChanges.remove(revisionToMove);
                }
                if (this.owner.trackChangesPane.changes.containsKey(revisionToMove)) {
                    this.owner.trackChangesPane.changes.remove(revisionToMove);
                }
                //Assign new single view
                this.owner.trackChangesPane.renderedChanges.add(revisionToMove, currentChangeView);
                this.owner.trackChangesPane.changes.add(revisionToMove, currentChangeView);
                previousGroupedView.push(revisionToMove);
                revisionToMove.hasChanges = true;
                //Remove the revision from revision collection
                var removeRevisionIndex = this.revisions.indexOf(revisionToMove);
                if (removeRevisionIndex !== -1) {
                    this.revisions.splice(removeRevisionIndex, 1);
                }
            }
            //Remove next single review
            this.groupedView.remove(nextChangeView);
        }
    };
    /**
     * Method which accepts all the revision in the revision collection
     *
     * @returns {void}
     */
    RevisionCollection.prototype.acceptAll = function () {
        if (!this.owner.isReadOnly && !this.owner.documentHelper.isTrackedOnlyMode) {
            this.handleRevisionCollection(true);
        }
    };
    /**
     * Method which rejects all the revision in the revision collection
     *
     * @returns {void}
     */
    RevisionCollection.prototype.rejectAll = function () {
        if (!this.owner.isReadOnly && !this.owner.documentHelper.isTrackedOnlyMode) {
            this.handleRevisionCollection(false);
        }
    };
    /**
     * @private
     * @param {boolean} isfromAcceptAll - Specifies the is accept all.
     * @param {Revision[]} changes - Specifies the revisions.
     * @returns {void}
     */
    RevisionCollection.prototype.handleRevisionCollection = function (isfromAcceptAll, changes) {
        var selection = this.owner.selectionModule;
        var startPos = selection.start;
        var endPos = selection.end;
        var revisionCollec = changes ? changes : this.revisions;
        if (revisionCollec.length <= 0) {
            return;
        }
        if (!selection.start.isExistBefore(selection.end)) {
            startPos = selection.end;
            endPos = selection.start;
        }
        startPos = startPos.clone();
        endPos = endPos.clone();
        if (isfromAcceptAll) {
            this.owner.editorModule.initComplexHistory('Accept All');
        }
        else {
            this.owner.editorModule.initComplexHistory('Reject All');
        }
        this.isAcceptAllOrRejectAll = true;
        while (revisionCollec.length > 0) {
            if (revisionCollec[0].getRange(false).length !== 0) {
                if (isfromAcceptAll) {
                    revisionCollec[0].accept();
                }
                else {
                    revisionCollec[0].reject();
                }
            }
            if (this.owner.enableHeaderAndFooter) {
                this.owner.editorModule.updateHeaderFooterWidget();
            }
        }
        this.isAcceptAllOrRejectAll = false;
        if (this.owner.editorHistoryModule) {
            this.owner.editorHistoryModule.updateComplexHistory();
        }
        this.owner.editorModule.isSkipOperationsBuild = this.owner.enableCollaborativeEditing;
        this.owner.editorModule.reLayout(this.owner.selectionModule, false);
        this.owner.editorModule.isSkipOperationsBuild = false;
    };
    RevisionCollection.prototype.clear = function () {
        this.changes = [];
        this.revisions = [];
    };
    /**
     * Disposes the internal objects which are maintained.
     * @private
     */
    RevisionCollection.prototype.destroy = function () {
        if (this.changes) {
            for (var i = 0; i < this.changes.length; i++) {
                var revision = this.changes[i];
                revision.destroy();
            }
            this.changes = [];
        }
        if (this.groupedView) {
            this.groupedView.clear();
        }
        this.groupedView = undefined;
        this.revisions = [];
        this.changes = undefined;
        this.owner = undefined;
    };
    return RevisionCollection;
}());
export { RevisionCollection };
