"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var error_1 = require("../../../api/converter/error");
var NumberConverter = /** @class */ (function () {
    function NumberConverter(options) {
        this.options = options;
    }
    /**
     * @deprecated in favor of {@link NumberConverter.uint8()}
     * @param lsb
     */
    NumberConverter.uint8Instance = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return NumberConverter.uint8(lsb);
    };
    /**
     * Number as unsigned 8 bits converter
     * @param lsb true for least significant bit first
     */
    NumberConverter.uint8 = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return new NumberConverter({
            signed: false,
            sizeOf: 8,
            leastSignificantBitFirst: lsb
        });
    };
    /**
     * @deprecated in favor of {@link NumberConverter.uint16()}
     * @param lsb  true for least significant bit first
     */
    NumberConverter.uint16Instance = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return NumberConverter.uint16(lsb);
    };
    /**
     * Number as unsigned 16 bits converter
     * @param lsb true for least significant bit first
     */
    NumberConverter.uint16 = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return new NumberConverter({
            signed: false,
            sizeOf: 16,
            leastSignificantBitFirst: lsb
        });
    };
    /**
     * @deprecated in favor of {@link NumberConverter.uint32()}
     * @param lsb  true for least significant bit first
     */
    NumberConverter.uint32Instance = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return NumberConverter.uint32(lsb);
    };
    /**
     * Number as unsigned 32 bits converter
     * @param lsb true for least significant bit first
     */
    NumberConverter.uint32 = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return new NumberConverter({
            signed: false,
            sizeOf: 32,
            leastSignificantBitFirst: lsb
        });
    };
    /**
     * @deprecated in favor of {@link NumberConverter.int8()}
     * @param lsb  true for least significant bit first
     */
    NumberConverter.int8Instance = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return NumberConverter.int8(lsb);
    };
    /**
     * Number as signed 8 bits converter
     * @param lsb  true for least significant bit first
     */
    NumberConverter.int8 = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return new NumberConverter({
            signed: true,
            sizeOf: 8,
            leastSignificantBitFirst: lsb
        });
    };
    /**
     * @deprecated in favor of {@link NumberConverter.int16()}
     * @param lsb  true for least significant bit first
     */
    NumberConverter.int16Instance = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return NumberConverter.int16(lsb);
    };
    /**
     * Number as signed 16 bits converter
     * @param lsb  true for least significant bit first
     */
    NumberConverter.int16 = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return new NumberConverter({
            signed: true,
            sizeOf: 16,
            leastSignificantBitFirst: lsb
        });
    };
    /**
     * @deprecated in favor of {@link NumberConverter.int32()}
     * @param lsb  true for least significant bit first
     */
    NumberConverter.int32Instance = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return NumberConverter.int32(lsb);
    };
    /**
     * Number as signed 32 bits converter
     * @param lsb  true for least significant bit first
     */
    NumberConverter.int32 = function (lsb) {
        if (lsb === void 0) { lsb = false; }
        return new NumberConverter({
            signed: true,
            sizeOf: 32,
            leastSignificantBitFirst: lsb
        });
    };
    NumberConverter.prototype.decode = function (body) {
        if ((body.length * 8) < this.options.sizeOf) {
            throw error_1.ConverterError.unexpectedBufferSize(this.options.sizeOf / 8, body);
        }
        return NumberConverter.fromBytes(body, this.options.sizeOf / 8, this.options.signed, this.options.leastSignificantBitFirst);
    };
    NumberConverter.prototype.encode = function (value) {
        var result = new Uint8Array(this.options.sizeOf >> 3);
        for (var i = 0; i < result.length; i++) {
            var decalage = ((result.length - i - 1) * 8);
            result[i] = (value >> decalage) & 0xFF;
        }
        if (this.options.leastSignificantBitFirst) {
            result.reverse();
        }
        return result;
    };
    NumberConverter.toOpaqueMsb = function (input, sizeOf) {
        if (sizeOf == 8) {
            return new Uint8Array([input & 0xFF]);
        }
        else if (sizeOf == 16) {
            return new Uint8Array([
                (input >> 8) & 0xFF,
                input & 0xFF
            ]);
        }
        else if (sizeOf == 32) {
            return new Uint8Array([
                (input >> 24) & 0xFF,
                (input >> 16) & 0xFF,
                (input >> 8) & 0xFF,
                input & 0xFF
            ]);
        }
        else {
            throw new Error("Invalid size " + sizeOf + ". Must be 8, 16 or 32");
        }
    };
    NumberConverter.fromOpaqueMsb = function (data, sizeOf) {
        if (!sizeOf) {
            sizeOf = data.length * 8;
        }
        if (sizeOf == 8) {
            return data[0] & 0xFF;
        }
        if (sizeOf == 16) {
            return (data[1] & 0xFF) + ((data[0] & 0xFF) << 8);
        }
        if (sizeOf == 32) {
            return (data[3] & 0xFF) +
                ((data[2] & 0xFF) << 8) +
                ((data[1] & 0xFF) << 16) +
                ((data[0] & 0xFF) << 24);
        }
        throw new Error("Invalid size " + sizeOf + ". Must be 8, 16 or 32");
    };
    /**
     * @param size size in bytes
     */
    NumberConverter.fromBytes = function (data, size, signed, lsb) {
        if (lsb) {
            data = data.reverse();
        }
        var result = 0;
        var last = 0;
        var decalage;
        for (var i = 0; i < size; i++) {
            decalage = ((size - i - 1) * 8);
            result += ((data[i] & 0xFF) << decalage) >>> 0;
            if (last > result && !signed) {
                throw new Error("Overflow. Last value: " + last + " but new is " + result);
            }
            last = result;
        }
        if (signed && (data[0] & 0x80) == 0x80) {
            result = -(Math.pow(2, (8 * size)) - result);
        }
        return result;
    };
    return NumberConverter;
}());
exports.NumberConverter = NumberConverter;
