import { binarySearchFloat32Array } from './binarySearch';

class Lookup {
  tableSize: number = 0;
  tableValues: Float32Array | null = null;
  tableKeys: Float32Array | null = null;
  minKey: number = Infinity;
  maxKey: number = -Infinity;
  keyRange: number = 0;
  tableSizeOverKeyRange: number = 0;
  keysEvenlyDistributed: boolean = false;
  initialize(tableSize: number, keysEvenlyDistributed: boolean = false): void {
    this.tableSize = tableSize;
    this.tableKeys = new Float32Array(tableSize);
    this.tableValues = new Float32Array(tableSize);
    for (let i = 0; i < tableSize; i++) {
      const input = this.getNthPrecomputedInput(i);
      this.tableValues![i] = this.compute(input);
      this.tableKeys![i] = input;
      if (input > this.maxKey) this.maxKey = input;
      if (input < this.minKey) this.minKey = input;
    }
    this.keyRange = this.maxKey - this.minKey;
    this.tableSizeOverKeyRange = (this.tableSize - 1) / this.keyRange;
    this.keysEvenlyDistributed = keysEvenlyDistributed;
  }
  get(x: number): number {
    const index = this.keysEvenlyDistributed
      ? Math.max(
          0,
          Math.min(
            Math.floor((x - this.minKey) * this.tableSizeOverKeyRange),
            this.tableSize - 1
          )
        )
      : binarySearchFloat32Array(this.tableKeys!, this.tableSize, x);

    return this.tableValues![index];
  }

  compute(_x: number): number {
    return 0;
  }
  getNthPrecomputedInput(i: number): number {
    return i;
  }
}

export default Lookup;
