/*
 * MPVQ.cpp
 *
 * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
 * www.ehima.com
 *
 * 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.
 */

#include "MPVQ.hpp"

#include <cstdbool>

#include "SnsQuantizationTables.hpp"

namespace Lc3Dec {

// declare local helper functions
void mind2vec_tab(short dim_in,                   /* i: dimension */
                  short k_max_local,              /* i: nb unit pulses */
                  short leading_sign,             /* i: leading sign */
                  unsigned int ind,               /* i: MPVQ-index */
                  short* vec_out,                 /* o: pulse train */
                  unsigned int MPVQ_offsets[][11] /* i: offset matrix */
);

void mind2vec_one(short k_val_in,     /* i: nb unit pulses */
                  short leading_sign, /* i: leading sign -1, 1 */
                  short* vec_out      /* o: updated pulse train */
);

short setval_update_sign(short k_delta,        /* i */
                         short k_max_local_in, /* i */
                         short* leading_sign,  /* i/o */
                         unsigned int* ind_in, /* i/o */
                         short* vec_out        /* i/o */
);

short get_lead_sign(unsigned int* ind_in);

//
// Implementation
//

void MPVQdeenum(uint8_t dim_in,   /* i : dimension of vec_out */
                uint8_t k_val_in, /* i : number of unit pulses */
                int16_t LS_ind,   /* i : leading sign index */
                int32_t MPVQ_ind, /* i : MPVQ shape index */
                int16_t* vec_out  /* o : PVQ integer pulse train */
) {
  for (uint8_t i = 0; i < dim_in; i++) {
    vec_out[i] = 0;
  }
  short leading_sign = 1;
  if (LS_ind != 0) {
    leading_sign = -1;
  }
  mind2vec_tab(dim_in, k_val_in, leading_sign, MPVQ_ind, vec_out, MPVQ_offsets);
}

void mind2vec_tab(short dim_in,                   /* i: dimension */
                  short k_max_local,              /* i: nb unit pulses */
                  short leading_sign,             /* i: leading sign */
                  unsigned int ind,               /* i: MPVQ-index */
                  short* vec_out,                 /* o: pulse train */
                  unsigned int MPVQ_offsets[][11] /* i: offset matrix */
) {
  /* init */
  unsigned int* h_row_ptr = &(MPVQ_offsets[(dim_in - 1)][0]);
  short k_acc = k_max_local;
  /* loop over positions */
  for (uint8_t pos = 0; pos < dim_in; pos++) {
    short k_delta;
    if (ind != 0) {
      k_acc = k_max_local;
      ;
      unsigned int UL_tmp_offset = h_row_ptr[k_acc];
      bool wrap_flag = (ind < UL_tmp_offset);
      unsigned int UL_diff = 0;
      if (!wrap_flag) {
        // Note: due to android build using a integer-overflow sanitizer, we
        // have to avoid
        //       computing the following difference when ind < UL_tmp_offset
        UL_diff = ind - UL_tmp_offset;
      }
      while (wrap_flag) {
        k_acc--;
        wrap_flag = (ind < h_row_ptr[k_acc]);
        if (!wrap_flag) {
          // Note: due to android build using a integer-overflow sanitizer, we
          // have to avoid
          //       computing the following difference when ind < UL_tmp_offset
          UL_diff = ind - h_row_ptr[k_acc];
        }
      }
      ind = UL_diff;
      k_delta = k_max_local - k_acc;
    } else {
      mind2vec_one(k_max_local, leading_sign, &vec_out[pos]);
      break;
    }
    k_max_local = setval_update_sign(k_delta, k_max_local, &leading_sign, &ind,
                                     &vec_out[pos]);
    h_row_ptr -= 11; /* reduce dimension in MPVQ_offsets table */
  }
}

void mind2vec_one(short k_val_in,     /* i: nb unit pulses */
                  short leading_sign, /* i: leading sign -1, 1 */
                  short* vec_out      /* o: updated pulse train */
) {
  short amp = k_val_in;
  if (leading_sign < 0) {
    amp = -k_val_in;
  }
  *vec_out = amp;
}

short setval_update_sign(
    short k_delta,        /* i */
    short k_max_local_in, /* i */
    short* leading_sign,  /* i/o */
    unsigned int* ind_in, /* i/o; needed to change type compared to spec */
    short* vec_out        /* i/o */
) {
  short k_max_local_out = k_max_local_in;
  if (k_delta != 0) {
    mind2vec_one(k_delta, *leading_sign, vec_out);
    *leading_sign = get_lead_sign(ind_in);
    k_max_local_out -= k_delta;
  }
  return k_max_local_out;
}

short get_lead_sign(
    unsigned int* ind)  // renamed "ind_in" from spec to just "ind" (as already
                        // found by yao.wang 28.06.2019)
{
  short leading_sign = +1;
  if (((*ind) & 0x1) != 0) {
    leading_sign = -1;
  }
  (*ind) = (*ind >> 1);
  return leading_sign;
}

}  // namespace Lc3Dec
