"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var Helpers_1 = __importDefault(require("../Helpers"));
var GridCanvas = /** @class */ (function () {
    function GridCanvas(container) {
        this.container = container;
        this.rectangles = [];
        this.offsetRectangles = [];
        this.texts = [];
        this.lines = [];
        this.hidden = [];
        this.gridCells = [[]];
        this.width = 0;
        this.height = 0;
        this.gridHeight = 0;
        this.gridWidth = 0;
        this.offsetX = 0;
        this.offsetY = 0;
        this.scale = 0;
        this.gridlines = false;
        this.borders = {
            widths: {
                none: 0,
                thin: 1,
                medium: 2,
                thick: 3
            },
            styles: {
                none: 'solid',
                solid: 'solid',
                double: 'double'
            },
            names: {
                t: 'top',
                r: 'right',
                b: 'bottom',
                l: 'left'
            }
        };
        this.helpers = new Helpers_1.default();
        this.canvas = document.createElement('canvas');
        var ctx = this.canvas.getContext('2d');
        if (ctx) {
            this.canvasContext = ctx;
        }
        this.bufferCanvas = document.createElement('canvas');
        ctx = this.bufferCanvas.getContext('2d');
        if (ctx) {
            this.bufferCanvasContext = ctx;
        }
        this.canvas.style.setProperty('display', 'none');
        container.appendChild(this.canvas);
    }
    GridCanvas.prototype.render = function (options) {
        var _this = this;
        this.width = options.width;
        this.height = options.height;
        this.gridlines = options.gridlines === undefined ? false : options.gridlines;
        this.offsetX = options.offsetX === undefined ? 0 : options.offsetX;
        this.offsetY = options.offsetY === undefined ? 0 : options.offsetY;
        this.scale = options.scale === undefined ? 1 : options.scale;
        if (options.fit === 'width') {
            this.scale = this.width / this.gridWidth;
        }
        else if (options.fit === 'height') {
            this.scale = this.height / this.gridHeight;
        }
        else if (options.fit === 'contain') {
            var scaleWidth = this.width / this.gridWidth;
            var scaleHeight = this.height / this.gridHeight;
            this.scale = scaleHeight < scaleWidth ? scaleHeight : scaleWidth;
        }
        this.resetElements();
        // reset canvas
        this.clearCanvas();
        // draw rects
        this.gridCells.forEach(function (row) {
            row.forEach(function (gridCell) {
                _this.drawOffsetRect(gridCell);
            });
        });
        this.gridCells.forEach(function (row) {
            row.forEach(function (gridCell) {
                _this.drawRect(gridCell);
            });
        });
        this.gridCells.forEach(function (row) {
            row.forEach(function (gridCell) {
                _this.drawText(gridCell);
            });
        });
        this.gridCells.forEach(function (row) {
            row.forEach(function (gridCell) {
                _this.drawLines(gridCell);
            });
        });
        for (var i = 0; i < this.lines.length; i++) {
            this.drawLine(this.lines[i][0], this.lines[i][1], this.lines[i][2]);
        }
        // this.createGraphics();
        this.drawCanvas();
        return this.canvas.toDataURL();
    };
    GridCanvas.prototype.resetElements = function () {
        this.bufferCanvas.width = this.width;
        this.bufferCanvas.height = this.height;
        this.canvas.width = this.width;
        this.canvas.height = this.height;
        // reset
        this.lines = [];
        this.offsetRectangles = [];
        this.rectangles = [];
        this.texts = [];
        this.hidden = [];
    };
    GridCanvas.prototype.clearCanvas = function () {
        this.bufferCanvasContext.save();
        this.bufferCanvasContext.clearRect(0, 0, this.width, this.height);
        this.bufferCanvasContext.scale(this.scale, this.scale);
    };
    GridCanvas.prototype.drawCanvas = function () {
        this.bufferCanvasContext.restore();
        this.canvasContext.clearRect(0, 0, this.width, this.height);
        this.canvasContext.drawImage(this.bufferCanvas, 0, 0);
    };
    GridCanvas.prototype.drawRect = function (cell) {
        // let t = this.translateCanvas(1);
        // let color = this.getBackgroundColor(cell);
        this.bufferCanvasContext.beginPath();
        this.bufferCanvasContext.fillStyle = "#" + cell.params.content.style['background-color'];
        this.bufferCanvasContext.fillRect(cell.params.x, cell.params.y, cell.dataset.overflow, cell.dataset.height);
        // this.resetCanvas(t);
    };
    GridCanvas.prototype.drawOffsetRect = function (cell) {
        // let t = this.translateCanvas(1);
        this.bufferCanvasContext.beginPath();
        this.bufferCanvasContext.fillStyle = "#" + cell.params.content.style['background-color'];
        this.bufferCanvasContext.fillRect(cell.dataset.x - 0.5, cell.dataset.y - 0.5, cell.dataset.width + 0.5, cell.dataset.height + 0.5);
        // this.resetCanvas(t);
    };
    GridCanvas.prototype.drawLines = function (cell) {
        // if (!coords) {
        //   console.log(cell, coords);
        // }
        var gridlineColor = 'd4d4d4';
        // // top line
        if (cell.params.content.style.tbs !== 'none' && cell.params.content.style.tbw !== 'none') {
            this.lines.push([
                { x: cell.dataset.x, y: cell.dataset.y },
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y },
                { width: this.borders.widths[cell.params.content.style.tbw], color: cell.params.content.style.tbc }
            ]);
        }
        // right line
        if (cell.params.content.style.rbs !== 'none' && cell.params.content.style.rbw !== 'none') {
            this.lines.push([
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y },
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y + cell.dataset.height },
                { width: this.borders.widths[cell.params.content.style.rbw], color: cell.params.content.style.rbc }
            ]);
        }
        else if (this.gridlines) {
            this.lines.push([
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y },
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y + cell.dataset.height },
                { width: 1, color: gridlineColor }
            ]);
        }
        // bottom line
        if (cell.params.content.style.bbs !== 'none' && cell.params.content.style.bbw !== 'none') {
            this.lines.push([
                { x: cell.dataset.x, y: cell.dataset.y + cell.dataset.height },
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y + cell.dataset.height },
                { width: this.borders.widths[cell.params.content.style.bbw], color: cell.params.content.style.bbc }
            ]);
        }
        else if (this.gridlines) {
            this.lines.push([
                { x: cell.dataset.x, y: cell.dataset.y + cell.dataset.height },
                { x: cell.dataset.x + cell.dataset.overflow, y: cell.dataset.y + cell.dataset.height },
                { width: 1, color: gridlineColor }
            ]);
        }
        // left line
        if (cell.params.content.style.lbs !== 'none' && cell.params.content.style.lbw !== 'none') {
            this.lines.push([
                { x: cell.dataset.x, y: cell.dataset.y },
                { x: cell.dataset.x, y: cell.dataset.y + cell.dataset.height },
                { width: this.borders.widths[cell.params.content.style.lbw], color: cell.params.content.style.lbc }
            ]);
        }
        else if (this.gridlines) {
            this.lines.push([
                { x: cell.dataset.x, y: cell.dataset.y },
                { x: cell.dataset.x, y: cell.dataset.y + cell.dataset.height },
                { width: 1, color: gridlineColor }
            ]);
        }
    };
    GridCanvas.prototype.drawLine = function (start, end, options) {
        var t = this.translateCanvas(options.width || 1);
        this.bufferCanvasContext.beginPath();
        this.bufferCanvasContext.lineWidth = options.width || 1;
        this.bufferCanvasContext.strokeStyle =
            options.color.indexOf('rgb') > -1 ? options.color : "#" + (options.color || '000000').replace('#', '');
        this.bufferCanvasContext.moveTo(start.x, start.y);
        this.bufferCanvasContext.lineTo(end.x, end.y);
        this.bufferCanvasContext.stroke();
        this.resetCanvas(t);
    };
    GridCanvas.prototype.drawText = function (cell) {
        var _this = this;
        // check access
        if (cell.permission === 'no') {
            return;
        }
        var v = this.cleanValue(cell.params.content.formatted_value || cell.params.content.value);
        if (!v.length)
            return;
        var color = cell.style && cell.style.color ? cell.style.color : "#" + cell.params.content.style['color'];
        this.bufferCanvasContext.fillStyle = color;
        this.bufferCanvasContext.font = this.getFontString(cell); //  `${cell.params.content.style["font-style"]} ${cell.params.content.style["font-weight"]} ${cell.params.content.style["font-size"]} "${cell.params.content.style["font-family"].replace(/"/g, "").replace(/'/g, "")}", sans-serif`;
        this.bufferCanvasContext.textAlign = (cell.params.content.style['text-align'] || 'left');
        //   .replace('justify', 'left')
        //   .replace('start', 'left');
        // cell.params.content.style['font-size'] = '9pt';
        // let m = canvasContext.measureText(v);
        var x = 0;
        var xPad = 3;
        var y = 0;
        var yPad = 5;
        switch (cell.params.content.style['text-align']) {
            case 'right':
                x = cell.dataset.x + cell.dataset.width - xPad;
                break;
            case 'middle':
            case 'center':
                x = cell.dataset.x + cell.dataset.width / 2;
                break;
            default:
                x = cell.dataset.x + xPad;
                break;
        }
        var wrapOffset = 0;
        var fontHeight = this.bufferCanvasContext.measureText('M').width;
        var lines = [];
        var wrap = (cell.params.content.style['text-wrap'] && cell.params.content.style['text-wrap'] === 'wrap') ||
            cell.params.content.style['word-wrap'] === 'break-word';
        if (wrap) {
            lines = this.findLines(v, fontHeight, cell.dataset.width - xPad * 2);
            wrapOffset = lines.offset;
        }
        switch (cell.params.content.style['vertical-align']) {
            case 'top':
                y = cell.dataset.y + fontHeight + yPad;
                break;
            case 'center':
            case 'middle':
                y = cell.dataset.y + cell.dataset.height / 2 - wrapOffset / 2 + fontHeight / 2;
                break;
            default:
                y = cell.dataset.y + cell.dataset.height - yPad - wrapOffset;
                break;
        }
        this.bufferCanvasContext.save();
        this.bufferCanvasContext.beginPath();
        this.bufferCanvasContext.rect(cell.dataset.x, cell.dataset.y, cell.dataset.overflow, cell.dataset.height);
        this.bufferCanvasContext.clip();
        if (wrap) {
            lines.lines.forEach(function (line) {
                _this.bufferCanvasContext.fillText(line.value, x, y + line.y);
                if (cell.params.content.link) {
                    var yLine = Math.round(y + 2 + line.y);
                    var tWidth = Math.round(_this.bufferCanvasContext.measureText(line.value).width);
                    var xLine = x;
                    switch (cell.params.content.style['text-align']) {
                        case 'right':
                            xLine = x - tWidth;
                            break;
                        case 'middle':
                        case 'center':
                            xLine = x - tWidth / 2;
                            break;
                        default:
                            break;
                    }
                    _this.drawLine({ x: xLine, y: yLine }, { x: xLine + tWidth, y: yLine }, { width: 1, color: color });
                }
            });
        }
        else {
            if (cell.params.content.style['number-format'] &&
                cell.params.content.style['number-format'].indexOf('0.00') > -1 &&
                /(¥|€|£|\$)/.test(v)) {
                var num = v.split(' ');
                this.bufferCanvasContext.fillText(num.length > 1 ? num[1] : v, x, y);
                if (num.length > 1) {
                    this.bufferCanvasContext.textAlign = 'left';
                    this.bufferCanvasContext.fillText(num[0], cell.dataset.x + xPad, y);
                }
            }
            else {
                this.bufferCanvasContext.fillText(v, x, y);
            }
            if (cell.params.content.link) {
                var yLine = Math.round(y + 2);
                var tWidth = Math.round(this.bufferCanvasContext.measureText(v).width);
                var xLine = x;
                switch (cell.params.content.style['text-align']) {
                    case 'right':
                        xLine = x - tWidth;
                        break;
                    case 'middle':
                    case 'center':
                        xLine = x - tWidth / 2;
                        break;
                    default:
                        break;
                }
                this.drawLine({ x: xLine, y: yLine }, { x: xLine + tWidth, y: yLine }, { width: 1, color: color });
            }
        }
        this.bufferCanvasContext.restore(); // discard clipping region
    };
    GridCanvas.prototype.findLines = function (str, fontHeight, cellWidth) {
        var words = str.split(' ');
        var lines = [];
        var word = [];
        var lineY = 0;
        var lineOffset = fontHeight + 4; // leading?
        for (var w = 0; w < words.length; w++) {
            var wordWidth = this.bufferCanvasContext.measureText(words[w]).width + 2;
            if (wordWidth > cellWidth) {
                var letters = words[w].split('');
                var width_1 = 0;
                wordWidth = 0;
                word = [];
                for (var i = 0; i < letters.length; i++) {
                    width_1 = this.bufferCanvasContext.measureText(word.join('')).width + 2;
                    if (width_1 < cellWidth) {
                        word.push(letters[i]);
                        wordWidth = width_1;
                    }
                    else {
                        lines.push({
                            value: word.join(''),
                            width: wordWidth
                        });
                        word = [letters[i]];
                    }
                }
                if (word.length) {
                    lines.push({
                        value: word.join(''),
                        width: wordWidth
                    });
                }
            }
            else {
                lines.push({
                    value: words[w],
                    width: wordWidth
                });
            }
        }
        var rows = [];
        var width = 0;
        var lineWords = [];
        for (var i = 0; i < lines.length; i++) {
            width += lines[i].width;
            if (width < cellWidth) {
                lineWords.push(lines[i].value);
            }
            else {
                rows.push({
                    value: lineWords.join(' '),
                    y: lineY
                });
                lineY += lineOffset;
                lineWords = [lines[i].value];
                width = lines[i].width;
            }
        }
        if (lineWords.length) {
            rows.push({
                value: lineWords.join(' '),
                y: lineY
            });
        }
        return {
            lines: rows,
            offset: fontHeight * (rows.length - 1) + (rows.length - 1) * 4
        };
    };
    GridCanvas.prototype.cleanValue = function (value) {
        return (value + '').trim().replace(/\s\s+/g, ' ');
    };
    GridCanvas.prototype.getFontString = function (cell) {
        return cell.params.content.style['font-style'] + " " + cell.params.content.style['font-weight'] + " " + cell.params.content.style['font-size'] + " \"" + cell.params.content.style['font-family'] + "\", sans-serif";
    };
    GridCanvas.prototype.translateCanvas = function (w) {
        var translate = (w % 2) / 2;
        this.bufferCanvasContext.translate(translate, translate);
        return translate;
        // canvasContext.translate(-iTranslate, -iTranslate);
    };
    GridCanvas.prototype.resetCanvas = function (translate) {
        this.bufferCanvasContext.translate(-translate, -translate);
    };
    return GridCanvas;
}());
exports.default = GridCanvas;
//# sourceMappingURL=GridCanvas.js.map