/******************************************************************************
 *                                                                            *
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include "ixheaacd_type_def.h"
#include "ixheaacd_constants.h"
#include "ixheaacd_basic_ops32.h"
#include "ixheaacd_basic_ops40.h"
#include "ixheaacd_acelp_com.h"

extern const WORD32 ixheaacd_factorial_7[8];
extern const WORD32 ixheaacd_iso_code_index_table[LEN_ABS_LEADER];
extern const UWORD8 ixheaacd_iso_code_data_table[LEN_SIGN_LEADER];
extern const UWORD32 ixheaacd_signed_leader_is[LEN_SIGN_LEADER];
extern const WORD32 ixheaacd_iso_code_num_table[],
    ixheaacd_pos_abs_leaders_a3[], ixheaacd_pos_abs_leaders_a4[];
extern const UWORD8 ixheaacd_absolute_leader_tab_da[][8];
extern const UWORD32 ixheaacd_cardinality_offset_table_i3[],
    ixheaacd_cardinality_offset_tab_i4[];

static VOID ixheaacd_nearest_neighbor_2d(WORD32 x[], WORD32 y[], WORD32 count,
                                         WORD32 *rem) {
  WORD32 i, j, sum;
  WORD32 s, e[8], em;
  WORD32 rem_temp[8];

  memcpy(rem_temp, rem, 8 * sizeof(WORD32));

  sum = 0;
  for (i = 0; i < 8; i++) {
    if (x[i] < 0) {
      y[i] = ixheaacd_negate32_sat(
          ixheaacd_shl32_sat((ixheaacd_sub32_sat(1, x[i]) >> 1), 1));
    } else {
      y[i] = ixheaacd_shl32_sat((ixheaacd_add32_sat(1, x[i]) >> 1), 1);
    }
    sum = ixheaacd_add32_sat(sum, y[i]);

    if (x[i] % 2 != 0) {
      if (x[i] < 0) {
        rem_temp[i] = ixheaacd_negate32_sat(
            ixheaacd_sub32_sat(rem_temp[i], (1 << count)));
      } else {
        rem_temp[i] = ixheaacd_sub32_sat(rem_temp[i], (1 << count));
      }
    }
  }

  if (sum % 4) {
    em = 0;
    j = 0;
    for (i = 0; i < 8; i++) {
      e[i] = rem_temp[i];
    }
    for (i = 0; i < 8; i++) {
      if (e[i] < 0) {
        s = -e[i];
      } else {
        s = e[i];
      }

      if (em < s) {
        em = s;
        j = i;
      }
    }

    if (e[j] < 0) {
      y[j] -= 2;
      rem_temp[j] = ixheaacd_add32_sat(rem_temp[j], (2 << count));
    } else {
      y[j] = ixheaacd_add32_sat(y[j], 2);
      rem_temp[j] = ixheaacd_sub32_sat(rem_temp[j], (2 << count));
    }
  }

  memcpy(rem, rem_temp, 8 * sizeof(WORD32));
  return;
}

VOID ixheaacd_voronoi_search(WORD32 x[], WORD32 y[], WORD32 count, WORD32 *rem1,
                             WORD32 *rem2) {
  WORD32 i, y0[8], y1[8];
  WORD32 x1[8], tmp;
  WORD32 e0, e1;

  ixheaacd_nearest_neighbor_2d(x, y0, count, rem1);
  for (i = 0; i < 8; i++) {
    if (x[i] == 0) {
      if (rem2[i] == 0) {
        x1[i] = x[i] - 1;
      } else {
        x1[i] = 0;
        rem2[i] = ixheaacd_sub32_sat(rem2[i], (1 << count));
      }
    } else {
      x1[i] = ixheaacd_sub32_sat(x[i], 1);
    }
  }

  ixheaacd_nearest_neighbor_2d(x1, y1, count, rem2);

  for (i = 0; i < 8; i++) {
    y1[i] = ixheaacd_add32_sat(y1[i], 1);
  }

  e0 = e1 = 0;
  for (i = 0; i < 8; i++) {
    tmp = rem1[i];
    e0 = ixheaacd_add32_sat(ixheaacd_sat64_32((WORD64)tmp * (WORD64)tmp), e0);
    tmp = rem2[i];
    e1 = ixheaacd_add32_sat(ixheaacd_sat64_32((WORD64)tmp * (WORD64)tmp), e1);
  }

  if (e0 < e1) {
    for (i = 0; i < 8; i++) {
      y[i] = y0[i];
    }
  } else {
    for (i = 0; i < 8; i++) {
      y[i] = y1[i];
    }
  }
  return;
}

VOID ixheaacd_voronoi_idx_dec(WORD32 *kv, WORD32 m, WORD32 *y, WORD32 count) {
  WORD32 i, v[8], tmp, sum, *ptr1, *ptr2;
  WORD32 z[8];
  WORD32 rem1[8], rem2[8];

  for (i = 0; i < 8; i++) y[i] = kv[7];

  z[7] = y[7] >> count;
  rem1[7] = y[7] & (m - 1);
  sum = 0;
  for (i = 6; i >= 1; i--) {
    tmp = ixheaacd_shl32_sat(kv[i], 1);
    sum = ixheaacd_add32_sat(sum, tmp);
    y[i] = ixheaacd_add32_sat(y[i], tmp);
    z[i] = y[i] >> count;
    rem1[i] = y[i] & (m - 1);
  }
  y[0] = ixheaacd_add32_sat(
      y[0],
      ixheaacd_add32_sat(ixheaacd_sat64_32((WORD64)4 * (WORD64)kv[0]), sum));
  z[0] = (ixheaacd_sub32_sat(y[0], 2)) >> count;
  if (m != 0)
    rem1[0] = (ixheaacd_sub32_sat(y[0], 2)) % m;
  else
    rem1[0] = ixheaacd_sub32_sat(y[0], 2);

  memcpy(rem2, rem1, 8 * sizeof(WORD32));

  ixheaacd_voronoi_search(z, v, count, rem1, rem2);

  ptr1 = y;
  ptr2 = v;
  for (i = 0; i < 8; i++) {
    *ptr1 = ixheaacd_sub32_sat(*ptr1,
                               ixheaacd_sat64_32((WORD64)m * (WORD64)*ptr2++));
    ptr1++;
  }
}

static VOID ixheaacd_gosset_rank_of_permutation(WORD32 rank, WORD32 *xs) {
  WORD32 i, j, a[8], w[8], base, fac, fac_b, target;

  j = 0;
  w[j] = 1;
  a[j] = xs[0];
  base = 1;
  for (i = 1; i < 8; i++) {
    if (xs[i] != xs[i - 1]) {
      j++;
      w[j] = 1;
      a[j] = xs[i];
    } else {
      w[j]++;
      base *= w[j];
    }
  }

  if (w[0] == 8) {
    for (i = 0; i < 8; i++) xs[i] = a[0];
  } else {
    target = rank * base;
    fac_b = 1;

    for (i = 0; i < 8; i++) {
      fac = fac_b * ixheaacd_factorial_7[i];
      j = -1;
      do {
        target -= w[++j] * fac;
      } while (target >= 0);
      xs[i] = a[j];

      target += w[j] * fac;
      fac_b *= w[j];
      w[j]--;
    }
  }

  return;
}

static WORD32 ixheaacd_get_abs_leader_tbl(const UWORD32 *table,
                                          UWORD32 code_book_ind, WORD32 size) {
  WORD32 i;

  for (i = 4; i < size; i += 4) {
    if (code_book_ind < table[i]) break;
  }
  if (i > size) i = size;

  if (code_book_ind < table[i - 2]) i -= 2;
  if (code_book_ind < table[i - 1]) i--;
  i--;

  return (i);
}

static VOID ixheaacd_gosset_decode_base_index(WORD32 n, UWORD32 code_book_ind,
                                              WORD32 *ya) {
  WORD32 i, im, t, sign_code, idx = 0, ks, rank;

  if (n < 2) {
    for (i = 0; i < 8; i++) ya[i] = 0;
  } else {
    switch (n) {
      case 2:
      case 3:
        i = ixheaacd_get_abs_leader_tbl(ixheaacd_cardinality_offset_table_i3,
                                        code_book_ind, LEN_I3);
        idx = ixheaacd_pos_abs_leaders_a3[i];
        break;
      case 4:
        i = ixheaacd_get_abs_leader_tbl(ixheaacd_cardinality_offset_tab_i4,
                                        code_book_ind, LEN_I4);
        idx = ixheaacd_pos_abs_leaders_a4[i];
        break;
    }

    for (i = 0; i < 8; i++) ya[i] = ixheaacd_absolute_leader_tab_da[idx][i];

    t = ixheaacd_iso_code_index_table[idx];
    im = ixheaacd_iso_code_num_table[idx];
    ks = ixheaacd_get_abs_leader_tbl(ixheaacd_signed_leader_is + t,
                                     code_book_ind, im);

    sign_code = 2 * ixheaacd_iso_code_data_table[t + ks];
    for (i = 7; i >= 0; i--) {
      ya[i] *= (1 - (sign_code & 2));
      sign_code >>= 1;
    }

    rank = code_book_ind - ixheaacd_signed_leader_is[t + ks];

    ixheaacd_gosset_rank_of_permutation(rank, ya);
  }
  return;
}

VOID ixheaacd_rotated_gosset_mtx_dec(WORD32 qn, WORD32 code_book_idx,
                                     WORD32 *kv, WORD32 *b) {
  if (qn <= 4) {
    ixheaacd_gosset_decode_base_index(qn, code_book_idx, b);
  } else {
    WORD32 i, m, c[8];
    WORD32 count = 0;
    while (qn > 4) {
      count++;
      qn -= 2;
    }

    if (count >= 31)
      m = MAX_32;
    else
      m = 1 << count;

    ixheaacd_gosset_decode_base_index(qn, code_book_idx, b);

    ixheaacd_voronoi_idx_dec(kv, m, c, count);

    for (i = 0; i < 8; i++) {
      b[i] =
          ixheaacd_add32_sat(ixheaacd_sat64_32((WORD64)m * (WORD64)b[i]), c[i]);
    }
  }
  return;
}