import { FormatError } from '@syncfusion/ej2-pdf';
var _PdfBinaryCharacterMapReader = /** @class */ (function () {
    function _PdfBinaryCharacterMapReader() {
        this._maximumSize = 16;
    }
    _PdfBinaryCharacterMapReader.prototype._convertHexToInt = function (data, size) {
        var n = 0;
        for (var i = 0; i <= size; i++) {
            n = (n << 8) | data[Number.parseInt(i.toString(), 10)];
        }
        return n >>> 0;
    };
    _PdfBinaryCharacterMapReader.prototype._hexArrayToString = function (data, size) {
        if (size === 1) {
            return String.fromCharCode(data[0], data[1]);
        }
        if (size === 3) {
            return String.fromCharCode(data[0], data[1], data[2], data[3]);
        }
        return String.fromCharCode.apply(String, data.subarray(0, size + 1));
    };
    _PdfBinaryCharacterMapReader.prototype._addHexData = function (data, incrementData, size) {
        var c = 0;
        for (var i = size; i >= 0; i--) {
            c += data[Number.parseInt(i.toString(), 10)] + incrementData[Number.parseInt(i.toString(), 10)];
            data[Number.parseInt(i.toString(), 10)] = c & 255;
            c >>= 8;
        }
    };
    _PdfBinaryCharacterMapReader.prototype._performHexIncrement = function (data, size) {
        var c = 1;
        for (var i = size; i >= 0 && c > 0; i--) {
            c += data[Number.parseInt(i.toString(), 10)];
            data[Number.parseInt(i.toString(), 10)] = c & 255;
            c >>= 8;
        }
    };
    _PdfBinaryCharacterMapReader.prototype._process = function (data, characterMap, enhance) {
        var stream = new _PdfBinaryCMapStream(data);
        var header = stream._readByteData(); // eslint-disable-line
        characterMap.vertical = !!(header & 1);
        var useCharacterMap; // eslint-disable-line
        var start = new Uint8Array(this._maximumSize);
        var end = new Uint8Array(this._maximumSize);
        var char = new Uint8Array(this._maximumSize);
        var charCode = new Uint8Array(this._maximumSize);
        var temp = new Uint8Array(this._maximumSize);
        var code;
        var b; // eslint-disable-line
        while ((b = stream._readByteData()) >= 0) { // eslint-disable-line
            var type = b >> 5;
            if (type === 7) {
                switch (b & 0x1f) {
                    case 0:
                        stream._readStringFromData();
                        break;
                    case 1:
                        useCharacterMap = stream._readStringFromData();
                        break;
                }
                continue;
            }
            var sequence = !!(b & 0x10);
            var dataSize = b & 15;
            if (dataSize + 1 > this._maximumSize) {
                throw new FormatError('BinaryCMapReader has encountered an invalid dataSize value.');
            }
            var universalCharset = 1;
            var childItemsCount = stream._readNumber();
            switch (type) {
                case 0:
                    stream._readHexData(start, dataSize);
                    stream._readHexDataNumber(end, dataSize);
                    this._addHexData(end, start, dataSize);
                    characterMap._insertCodeSpaceRange(dataSize + 1, this._convertHexToInt(start, dataSize), this._convertHexToInt(end, dataSize));
                    for (var i = 1; i < childItemsCount; i++) {
                        this._performHexIncrement(end, dataSize);
                        stream._readHexDataNumber(start, dataSize);
                        this._addHexData(start, end, dataSize);
                        stream._readHexDataNumber(end, dataSize);
                        this._addHexData(end, start, dataSize);
                        characterMap._insertCodeSpaceRange(dataSize + 1, this._convertHexToInt(start, dataSize), this._convertHexToInt(end, dataSize));
                    }
                    break;
                case 1:
                    stream._readHexData(start, dataSize);
                    stream._readHexDataNumber(end, dataSize);
                    this._addHexData(end, start, dataSize);
                    stream._readNumber();
                    for (var i = 1; i < childItemsCount; i++) {
                        this._performHexIncrement(end, dataSize);
                        stream._readHexDataNumber(start, dataSize);
                        this._addHexData(start, end, dataSize);
                        stream._readHexDataNumber(end, dataSize);
                        this._addHexData(end, start, dataSize);
                        stream._readNumber();
                    }
                    break;
                case 2:
                    stream._readHexData(char, dataSize);
                    code = stream._readNumber();
                    characterMap._mapOne(this._convertHexToInt(char, dataSize), code);
                    for (var i = 1; i < childItemsCount; i++) {
                        this._performHexIncrement(char, dataSize);
                        if (!sequence) {
                            stream._readHexDataNumber(temp, dataSize);
                            this._addHexData(char, temp, dataSize);
                        }
                        code = stream._readSignedData() + (code + 1);
                        characterMap._mapOne(this._convertHexToInt(char, dataSize), code);
                    }
                    break;
                case 3:
                    stream._readHexData(start, dataSize);
                    stream._readHexDataNumber(end, dataSize);
                    this._addHexData(end, start, dataSize);
                    code = stream._readNumber();
                    characterMap._mapCharacterIdentifierRange(this._convertHexToInt(start, dataSize), this._convertHexToInt(end, dataSize), code);
                    for (var i = 1; i < childItemsCount; i++) {
                        this._performHexIncrement(end, dataSize);
                        if (!sequence) {
                            stream._readHexDataNumber(start, dataSize);
                            this._addHexData(start, end, dataSize);
                        }
                        else {
                            start.set(end);
                        }
                        stream._readHexDataNumber(end, dataSize);
                        this._addHexData(end, start, dataSize);
                        code = stream._readNumber();
                        characterMap._mapCharacterIdentifierRange(this._convertHexToInt(start, dataSize), this._convertHexToInt(end, dataSize), code);
                    }
                    break;
                case 4:
                    stream._readHexData(char, universalCharset);
                    stream._readHexData(charCode, dataSize);
                    characterMap._mapOne(this._convertHexToInt(char, universalCharset), this._hexArrayToString(charCode, dataSize));
                    for (var i = 1; i < childItemsCount; i++) {
                        this._performHexIncrement(char, universalCharset);
                        if (!sequence) {
                            stream._readHexDataNumber(temp, universalCharset);
                            this._addHexData(char, temp, universalCharset);
                        }
                        this._performHexIncrement(charCode, dataSize);
                        stream._readHexSignedData(temp, dataSize);
                        this._addHexData(charCode, temp, dataSize);
                        characterMap._mapOne(this._convertHexToInt(char, universalCharset), this._hexArrayToString(charCode, dataSize));
                    }
                    break;
                case 5:
                    stream._readHexData(start, universalCharset);
                    stream._readHexDataNumber(end, universalCharset);
                    this._addHexData(end, start, universalCharset);
                    stream._readHexData(charCode, dataSize);
                    characterMap._mapRangeToDestination(this._convertHexToInt(start, universalCharset), this._convertHexToInt(end, universalCharset), this._hexArrayToString(charCode, dataSize));
                    for (var i = 1; i < childItemsCount; i++) {
                        this._performHexIncrement(end, universalCharset);
                        if (!sequence) {
                            stream._readHexDataNumber(start, universalCharset);
                            this._addHexData(start, end, universalCharset);
                        }
                        else {
                            start.set(end);
                        }
                        stream._readHexDataNumber(end, universalCharset);
                        this._addHexData(end, start, universalCharset);
                        stream._readHexData(charCode, dataSize);
                        characterMap._mapRangeToDestination(this._convertHexToInt(start, universalCharset), this._convertHexToInt(end, universalCharset), this._hexArrayToString(charCode, dataSize));
                    }
                    break;
                default:
                    throw new Error("BinaryCMapReader.process - unknown type: " + type);
            }
        }
        if (useCharacterMap) {
            return enhance(useCharacterMap);
        }
        return characterMap;
    };
    return _PdfBinaryCharacterMapReader;
}());
export { _PdfBinaryCharacterMapReader };
var _PdfBinaryCMapStream = /** @class */ (function () {
    function _PdfBinaryCMapStream(data) {
        this._maximumSize = 16;
        this._maxEncodedNumberSize = 19;
        this._buffer = data;
        this._pos = 0;
        this._end = data.length;
        this._tempBuffer = new Uint8Array(this._maxEncodedNumberSize);
    }
    _PdfBinaryCMapStream.prototype._readByteData = function () {
        return (this._pos >= this._end) ? -1 : this._buffer[this._pos++];
    };
    _PdfBinaryCMapStream.prototype._readNumber = function () {
        var n = 0;
        var last;
        do {
            var b = this._readByteData(); //eslint-disable-line
            last = !(b & 0x80);
            n = (n << 7) | (b & 0x7f);
        } while (!last);
        return n;
    };
    _PdfBinaryCMapStream.prototype._readSignedData = function () {
        var n = this._readNumber();
        return n & 1 ? ~(n >>> 1) : n >>> 1;
    };
    _PdfBinaryCMapStream.prototype._readHexData = function (number, size) {
        number.set(this._buffer.subarray(this._pos, this._pos + size + 1));
        this._pos += size + 1;
    };
    _PdfBinaryCMapStream.prototype._readHexDataNumber = function (number, size) {
        var last;
        var stack = this._tempBuffer; //eslint-disable-line
        var sp = 0;
        do {
            var b = this._readByteData(); //eslint-disable-line
            last = !(b & 0x80);
            stack[sp++] = b & 0x7f;
        } while (!last);
        var i = size;
        var buffer = 0;
        var bufferSize = 0;
        while (i >= 0) {
            while (bufferSize < 8 && stack.length > 0) {
                buffer |= stack[--sp] << bufferSize;
                bufferSize += 7;
            }
            number[Number.parseInt(i.toString(), 10)] = buffer & 255;
            i--;
            buffer >>= 8;
            bufferSize -= 8;
        }
    };
    _PdfBinaryCMapStream.prototype._readHexSignedData = function (number, size) {
        this._readHexDataNumber(number, size);
        var sign = number[Number.parseInt(size.toString(), 10)] & 1 ? 255 : 0;
        var c = 0;
        for (var i = 0; i <= size; i++) {
            c = ((c & 1) << 8) | number[Number.parseInt(i.toString(), 10)];
            number[Number.parseInt(i.toString(), 10)] = (c >> 1) ^ sign;
        }
    };
    _PdfBinaryCMapStream.prototype._readStringFromData = function () {
        var length = this._readNumber();
        var buffer = new Array(length); //eslint-disable-line
        for (var i = 0; i < length; i++) {
            buffer[Number.parseInt(i.toString(), 10)] = this._readNumber();
        }
        return String.fromCharCode.apply(String, buffer);
    };
    return _PdfBinaryCMapStream;
}());
export { _PdfBinaryCMapStream };
