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 __());
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
import { _PdfQcmsRunner } from '../import/qcms-runner';
import { _PdfColorPalette } from './colorspace';
var _PdfDataType;
(function (_PdfDataType) {
    _PdfDataType[_PdfDataType["rgb8"] = 0] = "rgb8";
    _PdfDataType[_PdfDataType["rgba8"] = 1] = "rgba8";
    _PdfDataType[_PdfDataType["bgra8"] = 2] = "bgra8";
    _PdfDataType[_PdfDataType["gray8"] = 3] = "gray8";
    _PdfDataType[_PdfDataType["graya8"] = 4] = "graya8";
    _PdfDataType[_PdfDataType["cmyk"] = 5] = "cmyk";
})(_PdfDataType || (_PdfDataType = {}));
var _PdfIntent;
(function (_PdfIntent) {
    _PdfIntent[_PdfIntent["perceptual"] = 0] = "perceptual";
    _PdfIntent[_PdfIntent["relativeColorimetric"] = 1] = "relativeColorimetric";
    _PdfIntent[_PdfIntent["saturation"] = 2] = "saturation";
    _PdfIntent[_PdfIntent["absoluteColorimetric"] = 3] = "absoluteColorimetric";
})(_PdfIntent || (_PdfIntent = {}));
var _PdfBaseColorSpace = /** @class */ (function () {
    function _PdfBaseColorSpace(name, numComps) {
        this.name = name;
        this.numComps = numComps;
    }
    return _PdfBaseColorSpace;
}());
export { _PdfBaseColorSpace };
var nextReqId = 1;
function onceMessage(worker, predicate) {
    return new Promise(function (resolve) {
        var handler = function (e) {
            var d = e.data; // eslint-disable-line
            if (predicate(d)) {
                worker.removeEventListener('message', handler);
                resolve(d);
            }
        };
        worker.addEventListener('message', handler);
    });
}
var _PdfIccColorSpace = /** @class */ (function (_super) {
    __extends(_PdfIccColorSpace, _super);
    function _PdfIccColorSpace(name, numComps, bytes) {
        var _this = _super.call(this, name, numComps) || this;
        _this.transformerId = 0;
        _this._isUsable = false;
        _this.numComps = numComps;
        _this.bytes = bytes;
        switch (numComps) {
            case 1:
                _this.inType = _PdfDataType.gray8;
                break;
            case 3:
                _this.inType = _PdfDataType.rgb8;
                break;
            case 4:
                _this.inType = _PdfDataType.cmyk;
                break;
            default: throw new Error('Unsupported number of components for ICCBased: ' + numComps);
        }
        return _this;
    }
    _PdfIccColorSpace.prototype._resolveBaseUrl = function (platform) {
        var _a = document.location, protocol = _a.protocol, host = _a.host, pathname = _a.pathname;
        var trimmedPathname = pathname.replace(/\/+$/, '');
        var baseUrl = protocol + "//" + host + trimmedPathname;
        if (platform === 'angular') {
            baseUrl = baseUrl + '/assets/ej2-pdf-lib';
        }
        else if (platform === 'vue') {
            baseUrl = baseUrl + '/public/js/ej2-pdf-lib';
        }
        else {
            window.getRunningScript = function () {
                return function () {
                    var stackTrace = new Error().stack; // eslint-disable-line
                    var match = stackTrace && stackTrace.match(/(?:http[s]?:\/\/(?:[^\/\s]+\/))(.*\.js)/); // eslint-disable-line
                    return match ? match[0] : location.href;
                };
            };
            var scriptLinkURL = window.getRunningScript()(); // eslint-disable-line
            var splitURL = scriptLinkURL.split('/'); // eslint-disable-line
            var path = scriptLinkURL.replace('/' + splitURL[splitURL.length - 1], '');
            if (platform === 'javascript' ||
                platform === 'typescript' ||
                platform === 'react' ||
                platform === 'aspnetcore' ||
                platform === 'aspnetmvc') {
                baseUrl = path + '/ej2-pdf-lib';
            }
            else {
                baseUrl = path.replace('image-extraction', 'ej2-pdf-lib');
            }
        }
        return baseUrl;
    };
    _PdfIccColorSpace.prototype._initialize = function (platform) {
        return __awaiter(this, void 0, void 0, function () {
            var workerBob, workerBlobUrl, worker, baseUrl;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (this._worker) {
                            return [2 /*return*/];
                        }
                        workerBob = new Blob([_PdfQcmsRunner.toString().replace(/^[^{]*{([\s\S]*)}$/m, '$1')], { type: 'text/javascript' });
                        workerBlobUrl = URL.createObjectURL(workerBob);
                        worker = new Worker(workerBlobUrl);
                        this._worker = worker;
                        baseUrl = this._resolveBaseUrl(platform);
                        return [4 /*yield*/, new Promise(function (resolve, reject) {
                                var onMsg = function (event) {
                                    var msg = event.data; // eslint-disable-line
                                    if (msg.message === 'loaded') {
                                        _this._isUsable = true;
                                        worker.removeEventListener('message', onMsg);
                                        resolve();
                                    }
                                    else if (msg.message === 'initError') {
                                        worker.removeEventListener('message', onMsg);
                                        reject(new Error(msg.error));
                                    }
                                };
                                worker.addEventListener('message', onMsg);
                                worker.postMessage({ message: 'initialLoading', url: baseUrl });
                            })];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    _PdfIccColorSpace.prototype._create = function () {
        return __awaiter(this, void 0, void 0, function () {
            var obj, reqId, resp;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        obj = Object.create(_PdfIccColorSpace.prototype);
                        _PdfBaseColorSpace.call(obj, this.name, this.numComps);
                        obj.numComps = this.numComps; // eslint-disable-line
                        obj._worker = this._worker; // eslint-disable-line
                        switch (this.numComps) {
                            case 1:
                                obj.inType = _PdfDataType.gray8;
                                break; // eslint-disable-line
                            case 3:
                                obj.inType = _PdfDataType.rgb8;
                                break; // eslint-disable-line
                            case 4:
                                obj.inType = _PdfDataType.cmyk;
                                break; // eslint-disable-line
                            default: throw new Error('Unsupported number of components for ICCBased: ' + this.numComps);
                        }
                        reqId = nextReqId++;
                        this._worker.postMessage({
                            message: 'createTransformer',
                            payload: { profileBytes: this.bytes, inType: obj.inType, intent: _PdfIntent.perceptual },
                            reqId: reqId
                        });
                        return [4 /*yield*/, onceMessage(// eslint-disable-line
                            this._worker, function (d) { return d && (d.message === 'transformerCreated' || d.message === 'createTransformerError') && // eslint-disable-line
                                d.reqId === reqId; })];
                    case 1:
                        resp = _a.sent();
                        if (resp.message === 'createTransformerError') {
                            throw new Error(resp.error || 'Failed to create ICC transformer'); // eslint-disable-line
                        }
                        this.transformerId = resp.handle;
                        obj.transformerId = resp.handle; // eslint-disable-line
                        return [2 /*return*/, obj];
                }
            });
        });
    };
    _PdfIccColorSpace.prototype.dispose = function () {
        if (this.transformerId) {
            try {
                this._worker.postMessage({ message: 'dropTransformer', payload: { id: this.transformerId } });
            }
            catch ( /* ignore */_a) { /* ignore */ }
            this.transformerId = 0;
        }
    };
    _PdfIccColorSpace.prototype._getRgbItem = function (src, srcOffset, dest, // eslint-disable-line        
    destOffset, css) {
        if (css === void 0) { css = false; }
        return __awaiter(this, void 0, void 0, function () {
            var value, resp_1, out_1, r, g, b, resp_2, out_2, c, m, y, k, resp, out;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!this.transformerId) {
                            throw new Error('ICCBased transformer is not initialized');
                        }
                        if (!(this.inType === _PdfDataType.gray8)) return [3 /*break*/, 2];
                        value = src[srcOffset] * 255;
                        this._worker.postMessage({
                            message: 'convertOne',
                            payload: { id: this.transformerId, dest: dest, destOffset: destOffset, value: value, css: css }
                        });
                        return [4 /*yield*/, onceMessage(// eslint-disable-line 
                            this._worker, function (d) { return d && (d.message === 'convertOneResult' || d.message === 'convertOneError'); } // eslint-disable-line 
                            )];
                    case 1:
                        resp_1 = _a.sent();
                        if (resp_1.message === 'convertOneError') {
                            throw new Error(resp_1.error || 'convertOne failed');
                        }
                        out_1 = resp_1.data;
                        dest[destOffset] = out_1[0];
                        dest[destOffset + 1] = out_1[1];
                        dest[destOffset + 2] = out_1[2];
                        return [2 /*return*/];
                    case 2:
                        if (!(this.inType === _PdfDataType.rgb8)) return [3 /*break*/, 4];
                        r = src[srcOffset] * 255;
                        g = src[srcOffset + 1] * 255;
                        b = src[srcOffset + 2] * 255;
                        this._worker.postMessage({
                            message: 'convertThree',
                            payload: { id: this.transformerId, dest: dest, destOffset: destOffset, r: r, g: g, b: b, css: css }
                        });
                        return [4 /*yield*/, onceMessage(// eslint-disable-line 
                            this._worker, function (d) { return d && (d.message === 'convertThreeResult' || d.message === 'convertThreeError'); })];
                    case 3:
                        resp_2 = _a.sent();
                        if (resp_2.message === 'convertThreeError') {
                            throw new Error(resp_2.error || 'convertThree failed');
                        }
                        out_2 = resp_2.data;
                        dest[destOffset] = out_2[0];
                        dest[destOffset + 1] = out_2[1];
                        dest[destOffset + 2] = out_2[2];
                        return [2 /*return*/];
                    case 4:
                        c = src[srcOffset] * 255;
                        m = src[srcOffset + 1] * 255;
                        y = src[srcOffset + 2] * 255;
                        k = src[srcOffset + 3] * 255;
                        this._worker.postMessage({
                            message: 'convertFour',
                            payload: { id: this.transformerId, dest: dest, destOffset: destOffset, c: c, m: m, y: y, k: k, css: css }
                        });
                        return [4 /*yield*/, onceMessage(// eslint-disable-line 
                            this._worker, function (d) { return d && (d.message === 'convertFourResult' || d.message === 'convertFourError'); } // eslint-disable-line 
                            )];
                    case 5:
                        resp = _a.sent();
                        if (resp.message === 'convertFourError') {
                            throw new Error(resp.error || 'convertFour failed');
                        }
                        out = resp.data;
                        dest[destOffset] = out[0];
                        dest[destOffset + 1] = out[1];
                        dest[destOffset + 2] = out[2];
                        return [2 /*return*/];
                }
            });
        });
    };
    _PdfIccColorSpace.prototype._getRgbBuffer = function (src, srcOffset, count, dest, // eslint-disable-line 
    destOffset, bits, alpha01) {
        return __awaiter(this, void 0, void 0, function () {
            var scale, i, ii, resp, result;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!this.transformerId) {
                            throw new Error('ICCBased transformer is not initialized');
                        }
                        src = src.subarray(srcOffset, srcOffset + count * this.numComps);
                        if (bits !== 8) {
                            scale = 255 / ((1 << bits) - 1);
                            for (i = 0, ii = src.length; i < ii; i++) {
                                src[i] *= scale;
                            }
                        }
                        this._worker.postMessage({
                            message: 'convertWith',
                            payload: {
                                id: this.transformerId,
                                src: src,
                                dest: dest,
                                destOffset: destOffset,
                                alpha: !!alpha01
                            }
                        });
                        return [4 /*yield*/, onceMessage(// eslint-disable-line
                            this._worker, function (d) { return d && (d.message === 'convertWithResult' || d.message === 'convertWithError'); } // eslint-disable-line
                            )];
                    case 1:
                        resp = _a.sent();
                        if (resp.message === 'convertWithError') {
                            throw new Error(resp.error || 'convertWith failed');
                        }
                        result = resp.data;
                        dest.set(result);
                        return [2 /*return*/];
                }
            });
        });
    };
    _PdfIccColorSpace.prototype._getRgbHex = function (src, srcOffset, css) {
        if (css === void 0) { css = false; }
        return __awaiter(this, void 0, void 0, function () {
            var tmp;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        tmp = new Uint8Array(3);
                        return [4 /*yield*/, this._getRgbItem(src, srcOffset, tmp, 0, css)];
                    case 1:
                        _a.sent();
                        return [2 /*return*/, ((tmp[0] << 16) | (tmp[1] << 8) | tmp[2]) >>> 0];
                }
            });
        });
    };
    _PdfIccColorSpace.prototype._getOutputLength = function (inputLength, alpha01) {
        return ((inputLength / this.numComps) * (3 + alpha01)) | 0;
    };
    return _PdfIccColorSpace;
}(_PdfColorPalette));
export { _PdfIccColorSpace };
