var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import { _isCommand, _PdfCommand, _PdfDecryptStream, _PdfName } from '@syncfusion/ej2-pdf';
import { _PdfBinaryCharacterMapReader } from './binary-cmap-reader';
import { _getEncodingBase64String } from './font-utils';
import { _PdfLexicalOperator } from '@syncfusion/ej2-pdf';
import { _PdfStream } from '@syncfusion/ej2-pdf';
import { _PdfFlateStream } from '@syncfusion/ej2-pdf';
var _PdfCharacterMap = /** @class */ (function () {
    function _PdfCharacterMap(builtInCMap) {
        if (builtInCMap === void 0) { builtInCMap = false; }
        this._map = []; //eslint-disable-line
        this._maximumMapRange = Math.pow(2, 24) - 1;
        this._codeSpaceRanges = [[], [], [], []];
        this._numberOfCodeSpaceRanges = 0;
        this._map = [];
        this._name = '';
        this._vertical = false;
        this._useCMap = null;
        this._builtInCMap = builtInCMap;
    }
    _PdfCharacterMap.prototype._forEach = function (callback) {
        var map = this._map; //eslint-disable-line
        var length = map.length;
        if (length <= 0x10000) {
            for (var i = 0; i < length; i++) {
                if (typeof (map[Number.parseInt(i.toString(), 10)]) !== 'undefined') {
                    callback(i, map[Number.parseInt(i.toString(), 10)]);
                }
            }
        }
        else {
            var keys = Object.keys(map); //eslint-disable-line
            for (var k = 0; k < keys.length; k++) {
                var i = keys[Number.parseInt(k.toString(), 10)]; //eslint-disable-line
                callback(i, map[Number.parseInt(i.toString(), 10)]);
            }
        }
    };
    _PdfCharacterMap.prototype._insertCodeSpaceRange = function (number, low, high) {
        this._codeSpaceRanges[number - 1].push(low, high);
        this._numberOfCodeSpaceRanges++;
    };
    _PdfCharacterMap.prototype._mapRangeToDestination = function (low, high, destinationLow) {
        if (high - low > this._maximumMapRange) {
            throw new Error('mapBfRange - ignoring data above _maximumMapRange.');
        }
        var lastByte = destinationLow.length - 1;
        while (low <= high) {
            this._map[low++] = destinationLow;
            var nextCharCode = destinationLow.charCodeAt(lastByte) + 1;
            if (nextCharCode > 0xff) {
                destinationLow = destinationLow.substring(0, lastByte - 1) + String.fromCharCode(destinationLow.charCodeAt(lastByte - 1) + 1) + '\x00';
                continue;
            }
            destinationLow = destinationLow.substring(0, lastByte) + String.fromCharCode(nextCharCode);
        }
    };
    _PdfCharacterMap.prototype._mapRangeToArray = function (low, high, array) {
        if (high - low > this._maximumMapRange) {
            throw new Error('mapBfRangeToArray - ignoring data above _maximumMapRange.');
        }
        var ii = array.length;
        var i = 0;
        while (low <= high && i < ii) {
            this._map[Number.parseInt(low.toString(), 10)] = array[i++];
            ++low;
        }
    };
    _PdfCharacterMap.prototype._mapOne = function (source, destination) {
        this._map[Number.parseInt(source.toString(), 10)] = destination;
    };
    _PdfCharacterMap.prototype._lookup = function (code) {
        return this._map[Number.parseInt(code.toString(), 10)];
    };
    _PdfCharacterMap.prototype._contains = function (code) {
        return this._map[Number.parseInt(code.toString(), 10)] !== undefined;
    };
    _PdfCharacterMap.prototype._mapCharacterIdentifierRange = function (low, high, destinationLow) {
        if (high - low > this._maximumMapRange) {
            throw new Error('mapCidRange - ignoring data above _maximumMapRange.');
        }
        while (low <= high) {
            this._map[low++] = destinationLow++;
        }
    };
    _PdfCharacterMap.prototype._readCharacterCodeFromString = function (text, offset, out) {
        var c = 0;
        var codespaceRanges = this._codeSpaceRanges; //eslint-disable-line
        for (var n = 0, nn = codespaceRanges.length; n < nn; n++) {
            c = ((c << 8) | text.charCodeAt(offset + n)) >>> 0;
            var codespaceRange = codespaceRanges[n]; //eslint-disable-line
            for (var k = 0, kk = codespaceRange.length; k < kk;) {
                var low = codespaceRange[k++];
                var high = codespaceRange[k++];
                if (c >= low && c <= high) {
                    out.charcode = c;
                    out.length = n + 1;
                    return;
                }
            }
        }
        out.charcode = 0;
        out.length = 1;
    };
    return _PdfCharacterMap;
}());
export { _PdfCharacterMap };
var _PdfCharacterMapFactory = /** @class */ (function () {
    function _PdfCharacterMapFactory() {
        this._cmapCompressionType = {
            NONE: 0,
            BINARY: 1
        };
        this._builtInCharacterMap = [
            'Adobe-GB1-UCS2',
            'Adobe-CNS1-UCS2',
            'Adobe-Japan1-UCS2',
            'Adobe-Korea1-UCS2',
            '78-EUC-H',
            '78-EUC-V',
            '78-H',
            '78-RKSJ-H',
            '78-RKSJ-V',
            '78-V',
            '78ms-RKSJ-H',
            '78ms-RKSJ-V',
            '83pv-RKSJ-H',
            '90ms-RKSJ-H',
            '90ms-RKSJ-V',
            '90msp-RKSJ-H',
            '90msp-RKSJ-V',
            '90pv-RKSJ-H',
            '90pv-RKSJ-V',
            'Add-H',
            'Add-RKSJ-H',
            'Add-RKSJ-V',
            'Add-V',
            'Adobe-CNS1-0',
            'Adobe-CNS1-1',
            'Adobe-CNS1-2',
            'Adobe-CNS1-3',
            'Adobe-CNS1-4',
            'Adobe-CNS1-5',
            'Adobe-CNS1-6',
            'Adobe-GB1-0',
            'Adobe-GB1-1',
            'Adobe-GB1-2',
            'Adobe-GB1-3',
            'Adobe-GB1-4',
            'Adobe-GB1-5',
            'Adobe-Japan1-0',
            'Adobe-Japan1-1',
            'Adobe-Japan1-2',
            'Adobe-Japan1-3',
            'Adobe-Japan1-4',
            'Adobe-Japan1-5',
            'Adobe-Japan1-6',
            'Adobe-Korea1-0',
            'Adobe-Korea1-1',
            'Adobe-Korea1-2',
            'B5-H',
            'B5-V',
            'B5pc-H',
            'B5pc-V',
            'CNS-EUC-H',
            'CNS-EUC-V',
            'CNS1-H',
            'CNS1-V',
            'CNS2-H',
            'CNS2-V',
            'ETHK-B5-H',
            'ETHK-B5-V',
            'ETen-B5-H',
            'ETen-B5-V',
            'ETenms-B5-H',
            'ETenms-B5-V',
            'EUC-H',
            'EUC-V',
            'Ext-H',
            'Ext-RKSJ-H',
            'Ext-RKSJ-V',
            'Ext-V',
            'GB-EUC-H',
            'GB-EUC-V',
            'GB-H',
            'GB-V',
            'GBK-EUC-H',
            'GBK-EUC-V',
            'GBK2K-H',
            'GBK2K-V',
            'GBKp-EUC-H',
            'GBKp-EUC-V',
            'GBT-EUC-H',
            'GBT-EUC-V',
            'GBT-H',
            'GBT-V',
            'GBTpc-EUC-H',
            'GBTpc-EUC-V',
            'GBpc-EUC-H',
            'GBpc-EUC-V',
            'H',
            'HKdla-B5-H',
            'HKdla-B5-V',
            'HKdlb-B5-H',
            'HKdlb-B5-V',
            'HKgccs-B5-H',
            'HKgccs-B5-V',
            'HKm314-B5-H',
            'HKm314-B5-V',
            'HKm471-B5-H',
            'HKm471-B5-V',
            'HKscs-B5-H',
            'HKscs-B5-V',
            'Hankaku',
            'Hiragana',
            'KSC-EUC-H',
            'KSC-EUC-V',
            'KSC-H',
            'KSC-Johab-H',
            'KSC-Johab-V',
            'KSC-V',
            'KSCms-UHC-H',
            'KSCms-UHC-HW-H',
            'KSCms-UHC-HW-V',
            'KSCms-UHC-V',
            'KSCpc-EUC-H',
            'KSCpc-EUC-V',
            'Katakana',
            'NWP-H',
            'NWP-V',
            'RKSJ-H',
            'RKSJ-V',
            'Roman',
            'UniCNS-UCS2-H',
            'UniCNS-UCS2-V',
            'UniCNS-UTF16-H',
            'UniCNS-UTF16-V',
            'UniCNS-UTF32-H',
            'UniCNS-UTF32-V',
            'UniCNS-UTF8-H',
            'UniCNS-UTF8-V',
            'UniGB-UCS2-H',
            'UniGB-UCS2-V',
            'UniGB-UTF16-H',
            'UniGB-UTF16-V',
            'UniGB-UTF32-H',
            'UniGB-UTF32-V',
            'UniGB-UTF8-H',
            'UniGB-UTF8-V',
            'UniJIS-UCS2-H',
            'UniJIS-UCS2-HW-H',
            'UniJIS-UCS2-HW-V',
            'UniJIS-UCS2-V',
            'UniJIS-UTF16-H',
            'UniJIS-UTF16-V',
            'UniJIS-UTF32-H',
            'UniJIS-UTF32-V',
            'UniJIS-UTF8-H',
            'UniJIS-UTF8-V',
            'UniJIS2004-UTF16-H',
            'UniJIS2004-UTF16-V',
            'UniJIS2004-UTF32-H',
            'UniJIS2004-UTF32-V',
            'UniJIS2004-UTF8-H',
            'UniJIS2004-UTF8-V',
            'UniJISPro-UCS2-HW-V',
            'UniJISPro-UCS2-V',
            'UniJISPro-UTF8-V',
            'UniJISX0213-UTF32-H',
            'UniJISX0213-UTF32-V',
            'UniJISX02132004-UTF32-H',
            'UniJISX02132004-UTF32-V',
            'UniKS-UCS2-H',
            'UniKS-UCS2-V',
            'UniKS-UTF16-H',
            'UniKS-UTF16-V',
            'UniKS-UTF32-H',
            'UniKS-UTF32-V',
            'UniKS-UTF8-H',
            'UniKS-UTF8-V',
            'V',
            'WP-Symbol'
        ];
        this.eof = 'EOF';
    }
    _PdfCharacterMapFactory.prototype._create = function (encoding, fetchBuiltInCharacterMap, _useCharacterMap) {
        var parsedCharacterMap; //eslint-disable-line
        if (encoding instanceof _PdfName) {
            return this._createBuiltInCharacterMap(encoding.name, fetchBuiltInCharacterMap);
        }
        else if (encoding instanceof _PdfFlateStream) {
            var stream = encoding.stream; //eslint-disable-line
            if (stream instanceof _PdfStream || stream instanceof _PdfDecryptStream) {
                parsedCharacterMap = this._parseCharacterMap(new _PdfCharacterMap(), new _PdfLexicalOperator(encoding), fetchBuiltInCharacterMap, _useCharacterMap);
            }
            return parsedCharacterMap;
        }
        else if (encoding instanceof _PdfStream) {
            parsedCharacterMap = this._parseCharacterMap(new _PdfCharacterMap(), new _PdfLexicalOperator(encoding), fetchBuiltInCharacterMap, _useCharacterMap);
            return parsedCharacterMap;
        }
    };
    _PdfCharacterMapFactory.prototype._createBuiltInCharacterMap = function (name, fetchBuiltInCharacterMap) {
        var _this = this;
        if (name === 'Identity-H') {
            return new _PdfIdentityCharacterMap(false, 2);
        }
        else if (name === 'Identity-V') {
            return new _PdfIdentityCharacterMap(true, 2);
        }
        if (!this._builtInCharacterMap.includes(name)) {
            throw new Error('Unknown CMap name: ' + name);
        }
        var characterMapData = this._fetchCharacterMap(name); //eslint-disable-line
        var cMap = new _PdfCharacterMap(true);
        if (characterMapData.isCompressed) {
            return new _PdfBinaryCharacterMapReader()._process(characterMapData.uint8Array, cMap, function (useCMap) {
                return _this._extendCMap(cMap, fetchBuiltInCharacterMap, useCMap);
            });
        }
        //throw new Error(`Invalid CMap 'compressionType' value: ${compressionType}`);
    };
    _PdfCharacterMapFactory.prototype._fetchCharacterMap = function (name) {
        var base64String = _getEncodingBase64String(name).replace(/^data:.+;base64,/, '');
        var uint8Array = this._base64ToUnSigned8Array(base64String);
        var isCompressed = true;
        var data = { uint8Array: uint8Array, isCompressed: isCompressed }; //eslint-disable-line
        return data;
    };
    _PdfCharacterMapFactory.prototype._base64ToUnSigned8Array = function (base64String) {
        var binaryString = atob(base64String);
        var uint8Array = new Uint8Array(binaryString.length);
        for (var i = 0; i < binaryString.length; i++) {
            uint8Array[Number.parseInt(i.toString(), 10)] = binaryString.charCodeAt(i);
        }
        return uint8Array;
    };
    _PdfCharacterMapFactory.prototype._parseCharacterMap = function (characterMap, lexer, fetchBuiltInCMap, _useCharacterMap) {
        var previous; //eslint-disable-line
        var embeddedUseCMap; //eslint-disable-line
        while (true) { //eslint-disable-line 
            try {
                var obj = lexer.getObject(); //eslint-disable-line
                if (obj === this.eof) {
                    break;
                }
                else if (obj instanceof _PdfName) {
                    if (obj.name === 'WMode') {
                        this._parseWritingMode(characterMap, lexer);
                    }
                    else if (obj.name === 'CMapName') {
                        this._parseCharacterMapName(characterMap, lexer);
                    }
                    previous = obj;
                }
                else if (obj instanceof _PdfCommand) {
                    switch (obj.command) {
                        case 'endcmap':
                            break;
                        case 'usecmap':
                            if (previous instanceof _PdfName) {
                                embeddedUseCMap = previous.name;
                            }
                            break;
                        case 'begincodespacerange':
                            this._parseCodeSpaceRange(characterMap, lexer);
                            break;
                        case 'beginbfchar':
                            this._parseBaseFontCharacter(characterMap, lexer);
                            break;
                        case 'begincidchar':
                            this._processCharacterMapping(characterMap, lexer);
                            break;
                        case 'beginbfrange':
                            this._mapBaseFontRange(characterMap, lexer);
                            break;
                        case 'begincidrange':
                            this._parseCharacterIdentifierRange(characterMap, lexer);
                            break;
                    }
                }
            }
            catch (ex) {
                continue;
            }
        }
        if (!_useCharacterMap && embeddedUseCMap) {
            _useCharacterMap = embeddedUseCMap;
        }
        if (_useCharacterMap) {
            return this._extendCMap(characterMap, fetchBuiltInCMap, _useCharacterMap);
        }
        return characterMap;
    };
    _PdfCharacterMapFactory.prototype._stringToInt = function (text) {
        var a = 0;
        for (var i = 0; i < text.length; i++) {
            a = (a << 8) | text.charCodeAt(i);
        }
        return a >>> 0;
    };
    _PdfCharacterMapFactory.prototype._validateString = function (object) {
        if (typeof object !== 'string') {
            throw new Error('Malformed CMap: expected string.');
        }
    };
    _PdfCharacterMapFactory.prototype._expectInt = function (object) {
        if (!Number.isInteger(object)) {
            throw new Error('Malformed CMap: expected int.');
        }
    };
    _PdfCharacterMapFactory.prototype._parseBaseFontCharacter = function (characterMap, lexer) {
        while (true) { // eslint-disable-line
            var obj = lexer.getObject(); //eslint-disable-line
            if (obj === this.eof) {
                break;
            }
            if (_isCommand(obj, 'endbfchar')) {
                return;
            }
            this._validateString(obj);
            var source = this._stringToInt(obj);
            obj = lexer.getObject();
            this._validateString(obj);
            var destination = obj; //eslint-disable-line
            characterMap._mapOne(source, destination);
        }
    };
    _PdfCharacterMapFactory.prototype._mapBaseFontRange = function (cMap, lexer) {
        while (true) { // eslint-disable-line
            var obj = lexer.getObject(); //eslint-disable-line
            if (obj === this.eof) {
                break;
            }
            if (_isCommand(obj, 'endbfrange')) {
                return;
            }
            this._validateString(obj);
            var low = this._stringToInt(obj);
            obj = lexer.getObject();
            this._validateString(obj);
            var high = this._stringToInt(obj);
            obj = lexer.getObject();
            if (Number.isInteger(obj) || typeof obj === 'string') {
                var dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj; //eslint-disable-line
                cMap._mapRangeToDestination(low, high, dstLow);
            }
            else if (_isCommand(obj, '[')) {
                obj = lexer.getObject();
                var array = []; //eslint-disable-line
                while (!_isCommand(obj, ']') && obj !== this.eof) {
                    array.push(obj);
                    obj = lexer.getObject();
                }
                cMap._mapRangeToArray(low, high, array);
            }
            else {
                break;
            }
        }
    };
    _PdfCharacterMapFactory.prototype._processCharacterMapping = function (characterMap, lexer) {
        while (true) { // eslint-disable-line
            var obj = lexer.getObject(); //eslint-disable-line
            if (obj === this.eof) {
                break;
            }
            if (_isCommand(obj, 'endcidchar')) {
                return;
            }
            this._validateString(obj);
            var src = this._stringToInt(obj);
            obj = lexer.getObject();
            this._expectInt(obj);
            var dst = obj; //eslint-disable-line
            characterMap._mapOne(src, dst);
        }
    };
    _PdfCharacterMapFactory.prototype._parseCharacterIdentifierRange = function (characterMap, lexer) {
        while (true) { // eslint-disable-line
            var obj = lexer.getObj(); //eslint-disable-line
            if (obj === this.eof) {
                break;
            }
            if (_isCommand(obj, 'endcidrange')) {
                return;
            }
            this._validateString(obj);
            var low = this._stringToInt(obj);
            obj = lexer.getObj();
            this._validateString(obj);
            var high = this._stringToInt(obj);
            obj = lexer.getObj();
            this._expectInt(obj);
            var dstLow = obj; // eslint-disable-line
            characterMap._mapCharacterIdentifierRange(low, high, dstLow);
        }
    };
    _PdfCharacterMapFactory.prototype._parseCodeSpaceRange = function (characterMap, lexer) {
        while (true) { // eslint-disable-line
            var obj = lexer.getObject(); //eslint-disable-line
            if (obj === this.eof) {
                break;
            }
            if (_isCommand(obj, 'endcodespacerange')) {
                return;
            }
            if (typeof obj !== 'string') {
                break;
            }
            var low = this._stringToInt(obj);
            obj = lexer.getObject();
            if (typeof obj !== 'string') {
                break;
            }
            var high = this._stringToInt(obj);
            characterMap._insertCodeSpaceRange(obj.length, low, high);
        }
    };
    _PdfCharacterMapFactory.prototype._parseWritingMode = function (cMap, lexer) {
        var obj = lexer.getObject(); //eslint-disable-line
        if (Number.isInteger(obj)) {
            cMap.vertical = obj;
        }
    };
    _PdfCharacterMapFactory.prototype._parseCharacterMapName = function (characterMap, lexer) {
        var obj = lexer.getObject(); //eslint-disable-line
        if (obj instanceof _PdfName) {
            characterMap.name = obj.name;
        }
    };
    _PdfCharacterMapFactory.prototype._extendCMap = function (characterMap, fetchBuiltInCMap, _useCharacterMap) {
        characterMap.useCMap = this._createBuiltInCharacterMap(_useCharacterMap, fetchBuiltInCMap);
        if (characterMap.numCodespaceRanges === 0) {
            var useCodespaceRanges = characterMap.useCMap.codespaceRanges; // eslint-disable-line
            for (var i = 0; i < useCodespaceRanges.length; i++) {
                characterMap.codespaceRanges[Number.parseInt(i.toString(), 10)] = useCodespaceRanges[Number.parseInt(i.toString(), 10)].
                    slice();
            }
            characterMap.numCodespaceRanges = characterMap.useCMap.numCodespaceRanges;
        }
        characterMap.useCMap.forEach(function (key, value) {
            if (!characterMap._contains(key)) {
                characterMap._mapOne(key, characterMap.useCMap.lookup(key));
            }
        });
        return characterMap;
    };
    return _PdfCharacterMapFactory;
}());
export { _PdfCharacterMapFactory };
var _PdfIdentityCharacterMap = /** @class */ (function (_super) {
    __extends(_PdfIdentityCharacterMap, _super);
    function _PdfIdentityCharacterMap(vertical, count) {
        var _this = _super.call(this) || this;
        _this._vertical = vertical;
        _this._insertCodeSpaceRange(count, 0, 0xffff);
        return _this;
    }
    _PdfIdentityCharacterMap.prototype._insertCodeSpaceRange = function (count, low, high) {
        this._codeSpaceRanges[count - 1].push(low, high);
        this._numberOfCodeSpaceRanges++;
    };
    _PdfIdentityCharacterMap.prototype._lookup = function (code) {
        return Number.isInteger(code) && code <= 0xffff ? code : undefined;
    };
    _PdfIdentityCharacterMap.prototype._contains = function (code) {
        return Number.isInteger(code) && code <= 0xffff;
    };
    _PdfIdentityCharacterMap.prototype._charCodeOf = function (value) {
        return Number.isInteger(value) && value <= 0xffff ? value : -1;
    };
    _PdfIdentityCharacterMap.prototype._forEach = function (callback) {
        for (var i = 0; i <= 0xffff; i++) {
            callback(i, i);
        }
    };
    return _PdfIdentityCharacterMap;
}(_PdfCharacterMap));
export { _PdfIdentityCharacterMap };
