"use strict";
exports.__esModule = true;
// tslint:disable no-conditional-assignment
require("../../typed-array");
var NUMBER_OF_ROUNDS = 81;
var HASH_LENGTH = 243;
var STATE_LENGTH = 3 * HASH_LENGTH;
var TRUTH_TABLE = [1, 0, -1, 2, 1, -1, 0, 2, -1, 1, 0];
/**
 * @class Curl
 * @ignore
 */
var Curl = /** @class */ (function () {
    /**
     * @constructor
     *
     * @ignore
     *
     * @param rounds
     */
    function Curl(rounds) {
        if (rounds === void 0) { rounds = NUMBER_OF_ROUNDS; }
        this.rounds = rounds;
        if (rounds !== 27 && rounds !== 81) {
            throw new Error('Illegal number of rounds. Only `27` and `81` rounds are supported.');
        }
        this.state = new Int8Array(STATE_LENGTH);
    }
    /**
     * Initializes the state with `STATE_LENGTH` trits
     *
     * @method initialize
     *
     * @ignore
     *
     * @param {Int8Array} [state]
     */
    Curl.prototype.initialize = function (state) {
        if (state === void 0) { state = new Int8Array(STATE_LENGTH); }
        if (state.length !== STATE_LENGTH) {
            throw new Error('Illegal state length. ');
        }
        this.state = state.slice();
        for (var i = 0; i < STATE_LENGTH; i++) {
            this.state[i] = 0;
        }
    };
    /**
     * Resets the state
     *
     * @ignore
     *
     * @method reset
     */
    Curl.prototype.reset = function () {
        this.initialize();
    };
    /**
     * Absorbs trits given an offset and length
     *
     * @method absorb
     *
     * @ignore
     *
     * @param {Int8Array} trits
     * @param {number} offset
     * @param {number} length
     **/
    Curl.prototype.absorb = function (trits, offset, length) {
        do {
            var i = 0;
            var limit = length < HASH_LENGTH ? length : HASH_LENGTH;
            while (i < limit) {
                this.state[i++] = trits[offset++];
            }
            this.transform();
        } while ((length -= HASH_LENGTH) > 0);
    };
    /**
     * Squeezes trits given an offset and length
     *
     * @method squeeze
     *
     * @ignore
     *
     * @param {Int8Array} trits
     * @param {number} offset
     * @param {number} length
     **/
    Curl.prototype.squeeze = function (trits, offset, length) {
        do {
            var i = 0;
            var limit = length < HASH_LENGTH ? length : HASH_LENGTH;
            while (i < limit) {
                trits[offset++] = this.state[i++];
            }
            this.transform();
        } while ((length -= HASH_LENGTH) > 0);
    };
    /**
     * Sponge transform function
     *
     * @method transform
     *
     * @ignore
     *
     * @private
     */
    Curl.prototype.transform = function () {
        var stateCopy = new Int8Array(STATE_LENGTH);
        var index = 0;
        for (var round = 0; round < this.rounds; round++) {
            stateCopy = this.state.slice();
            for (var i = 0; i < STATE_LENGTH; i++) {
                this.state[i] =
                    TRUTH_TABLE[stateCopy[index] + (stateCopy[(index += index < 365 ? 364 : -365)] << 2) + 5];
            }
        }
    };
    Curl.HASH_LENGTH = HASH_LENGTH;
    return Curl;
}());
exports["default"] = Curl;
//# sourceMappingURL=index.js.map