function sqGridProgressBar(grid, rowIndex, colIndex, row, params) {
    var element = document.createElement('div');
    element.classList.add('grid-widget-progress');

    var progressText = grid.getUserData(rowIndex, 'progressText');
    if (progressText === "stopped") {
        progressText = 'Stopped';
    }

    var progressWidth = grid.getUserData(rowIndex, 'progress');
    if (progressWidth === null) {
        progressWidth = -2;
    }

    var tooltipText = grid.getUserData(rowIndex, 'tooltipText');
    if (tooltipText === null) {
        tooltipText = "";
    }

    if(progressWidth == -1){
        tooltipText = progressText
    }

    var paused = grid.getUserData(rowIndex, 'paused');

    IncrementalDOM.elementOpenStart('div');
    IncrementalDOM.attr("class", "grid-widget-progress");
    /*     IncrementalDOM.attr("onmouseenter", function (e) {
            if (tooltipText != "") {
                clearTimeout(window.sqGridPopupTimer);
                grid.popupElement.innerHTML = tooltipText;
                grid.popupElement.style.display = 'block';
                var viewportOffset = e.target.getBoundingClientRect();
                var viewportOffsetPopup = grid.popupElement.getBoundingClientRect();
                var top = viewportOffset.top;
                var left = viewportOffset.left;
                var height = viewportOffsetPopup.height;
                grid.popupElement.style.top = (e.clientY - height - 5) + 'px';
                grid.popupElement.style.left = (e.clientX + 5) + 'px';
                e.target.onmouseleave = function (e) {
                    if (e.toElement.classList.contains('sq-grid-popup')) {
                        clearTimeout(window.sqGridPopupTimer);
                        return;
                    }
                    clearTimeout(window.sqGridPopupTimer);
                    window.sqGridPopupTimer = setTimeout(function () {
                        grid.popupElement.style.display = 'none';
                        window.sqGridPopupTimer = null;
                    }, 0);
                };
            }
        }); */
    IncrementalDOM.attr("onmousemove", function (e) {
        if (tooltipText != "" && tooltipText != null) {
            clearTimeout(window.sqGridPopupTimer);
            grid.popupElement.innerHTML = tooltipText;
            grid.popupElement.style.display = 'block';
            var viewportOffset = e.target.getBoundingClientRect();
            var viewportOffsetPopup = grid.popupElement.getBoundingClientRect();
            var top = viewportOffset.top;
            var left = viewportOffset.left;
            var height = viewportOffsetPopup.height;
            grid.popupElement.style.top = (e.clientY - height - 5) + 'px';
            grid.popupElement.style.left = (e.clientX + 5) + 'px';
            e.target.onmouseleave = function (e) {
                if (e.toElement.classList.contains('sq-grid-popup')) {
                    clearTimeout(window.sqGridPopupTimer);
                    return;
                }
                clearTimeout(window.sqGridPopupTimer);
                window.sqGridPopupTimer = setTimeout(function () {
                    grid.popupElement.style.display = 'none';
                    window.sqGridPopupTimer = null;
                }, 0);
            };
        }
    });
    IncrementalDOM.elementOpenEnd('div');

    if (progressWidth >= 0 && progressWidth < 100) {
        // progress buttons
        IncrementalDOM.elementOpenStart('div', null, null, "class", "grid-widget-progress-btns"); {
            IncrementalDOM.attr("onmousedown", function (e) {
                if (e.target.classList.contains("grid-widget-progress-btns-pause")) {
                    sqGridSendEvent(e, "actionPause", rowIndex);
                    /* var pause = grid.getUserData(rowIndex, 'pause');
                    if (pause) {
                        pause(rowIndex, row, 'pause');
                    } else if (actionLink && callAction) {
                        callAction(actionLink, grid.getRowId(rowIndex), 'pause')
                    } */
                }
                if (e.target.classList.contains("grid-widget-progress-btns-stop")) {
                    sqGridSendEvent(e, "actionStop", rowIndex);
                    /* var stop = grid.getUserData(rowIndex, 'stop');
                    if ((stop || (actionLink && callAction)) && confirm(Ltsq("Do you really want to stop?"))) {
                        if (stop) {
                            stop(rowIndex, row, 'stop');
                        } else {
                            callAction(actionLink, grid.getRowId(rowIndex), 'stop')
                        }
                    } */
                }
                if (e.target.classList.contains("grid-widget-progress-btns-continue")) {
                    sqGridSendEvent(e, "actionContinue", rowIndex);
                    /* var cont = grid.getUserData(rowIndex, 'continue');
                    if (cont) {
                        cont(rowIndex, row, 'continue');
                    } else if (actionLink && callAction) {
                        callAction(actionLink, grid.getRowId(rowIndex), 'continue')
                    } */
                }
            });
            IncrementalDOM.elementOpenEnd('div');
            if (!paused) {
                IncrementalDOM.elementOpenStart('div');
                IncrementalDOM.attr("class", "grid-widget-progress-btns-pause");
                IncrementalDOM.elementOpenEnd('div');
                IncrementalDOM.elementClose('div');
            }
            IncrementalDOM.elementOpenStart('div');
            IncrementalDOM.attr("class", "grid-widget-progress-btns-stop");
            IncrementalDOM.elementOpenEnd('div');
            IncrementalDOM.elementClose('div');
            if (paused) {
                IncrementalDOM.elementOpenStart('div');
                IncrementalDOM.attr("class", "grid-widget-progress-btns-continue");
                IncrementalDOM.elementOpenEnd('div');
                IncrementalDOM.elementClose('div');
            }
        }
        IncrementalDOM.elementClose('div');

        // progress text
        IncrementalDOM.elementOpen('div', null, null, "class", "grid-widget-progress-text", "style", "color:inherit;");
        if (paused) {
            IncrementalDOM.text("Paused");
        } else {
            IncrementalDOM.text(progressText);
        }
        IncrementalDOM.elementClose('div');

        // progress bar
        IncrementalDOM.elementOpen('div', null, null, "class", "grid-widget-progress-bar"); {
            IncrementalDOM.elementOpen('div', null, null, "style", "width: " + progressWidth + "%");
            IncrementalDOM.elementClose('div');
        }
        IncrementalDOM.elementClose('div');
    } else if (progressWidth == 100) {
        IncrementalDOM.elementOpen('div', null, null, "class", "grid-widget-progress-text", "style", "color:inherit;");
        IncrementalDOM.text("Completed");
        IncrementalDOM.elementClose('div');
    } else {
        IncrementalDOM.elementOpenStart('div');
        IncrementalDOM.attr("class", "grid-widget-progress-text");
        if (progressWidth == -1) {
            IncrementalDOM.attr("style", "color: red;");
        }
        IncrementalDOM.elementOpenEnd('div');
        if (progressWidth == -1) {
            IncrementalDOM.elementOpenStart('div');
            IncrementalDOM.attr("class", "grid-widget-tooltip");
            IncrementalDOM.elementOpenEnd('div'); {
                IncrementalDOM.text("ERROR");
                IncrementalDOM.elementOpen('div', null, null, "class", "sq-grid-icon");
                IncrementalDOM.elementClose('div');
            }
            IncrementalDOM.elementClose('div');
        } else {
            var currentElement = IncrementalDOM.currentElement();
            currentElement.innerHTML = progressText;
        }
        IncrementalDOM.elementClose('div');
    }

    IncrementalDOM.elementClose('div');
}

function setGridProgressBarAction(grid, rowIndex, callback) {
    grid.setUserData(rowIndex, 'stop', callback);
    grid.setUserData(rowIndex, 'pause', callback);
    grid.setUserData(rowIndex, 'continue', callback);
}

function displayGridProgressBar(grid, rowIndex, message, redrawGrid) {
    grid.setUserData(rowIndex, 'progress', -2);
    grid.setUserData(rowIndex, 'progressText', message);

    if (redrawGrid) {
        grid.bodyRedraw();
    }
}

function loadGridProgressBarActions(grid) {
    var actions = [];

    for (var i = 0; i < grid.rows.length; i++) {
        actions.push({
            rowId: grid.rows[i].cells[0],
            stop: grid.getUserData(i, 'stop'),
            pause: grid.getUserData(i, 'pause'),
            continue: grid.getUserData(i, 'continue'),

            progress: grid.getUserData(i, 'progress'),
            progressText: grid.getUserData(i, 'progressText'),
            paused: grid.getUserData(i, 'paused'),
            actionLink: grid.getUserData(i, 'actionLink'),
            callAction: grid.getUserData(i, 'callAction'),
        });
    }

    return actions;
}

function applyGridProgressBarActions(grid, actions) {
    for (var i = 0; i < actions.length; i++) {
        var action = actions[i];

        var rowIndex = grid.getRowIndex(action.rowId);
        if (rowIndex < 0) {
            continue;
        }

        grid.setUserData(rowIndex, 'stop', action.stop);
        grid.setUserData(rowIndex, 'pause', action.pause);
        grid.setUserData(rowIndex, 'continue', action.continue);

        grid.setUserData(rowIndex, 'progress', action.progress);
        grid.setUserData(rowIndex, 'progressText', action.progressText);
        grid.setUserData(rowIndex, 'paused', action.paused);
        grid.setUserData(rowIndex, 'actionLink', action.actionLink);
        grid.setUserData(rowIndex, 'callAction', action.callAction);
    }
}
