/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <assert.h>
#include <stdint.h>
#include <string.h>

#include "av1/common/blockd.h"
#include "av1/encoder/palette.h"
#include "av1/encoder/random.h"

#ifndef AV1_K_MEANS_DIM
#error "This template requires AV1_K_MEANS_DIM to be defined"
#endif

#define RENAME_(x, y) AV1_K_MEANS_RENAME(x, y)
#define RENAME(x) RENAME_(x, AV1_K_MEANS_DIM)

static int RENAME(calc_dist)(const int *p1, const int *p2) {
  int dist = 0;
  for (int i = 0; i < AV1_K_MEANS_DIM; ++i) {
    const int diff = p1[i] - p2[i];
    dist += diff * diff;
  }
  return dist;
}

void RENAME(av1_calc_indices)(const int *data, const int *centroids,
                              uint8_t *indices, int64_t *dist, int n, int k) {
  if (dist) {
    *dist = 0;
  }
  for (int i = 0; i < n; ++i) {
    int min_dist = RENAME(calc_dist)(data + i * AV1_K_MEANS_DIM, centroids);
    indices[i] = 0;
    for (int j = 1; j < k; ++j) {
      const int this_dist = RENAME(calc_dist)(data + i * AV1_K_MEANS_DIM,
                                              centroids + j * AV1_K_MEANS_DIM);
      if (this_dist < min_dist) {
        min_dist = this_dist;
        indices[i] = j;
      }
    }
    if (dist) {
      dist += min_dist;
    }
  }
}

static void RENAME(calc_centroids)(const int *data, int *centroids,
                                   const uint8_t *indices, int n, int k) {
  int i, j;
  int count[PALETTE_MAX_SIZE] = { 0 };
  unsigned int rand_state = (unsigned int)data[0];
  assert(n <= 32768);
  memset(centroids, 0, sizeof(centroids[0]) * k * AV1_K_MEANS_DIM);

  for (i = 0; i < n; ++i) {
    const int index = indices[i];
    assert(index < k);
    ++count[index];
    for (j = 0; j < AV1_K_MEANS_DIM; ++j) {
      centroids[index * AV1_K_MEANS_DIM + j] += data[i * AV1_K_MEANS_DIM + j];
    }
  }

  for (i = 0; i < k; ++i) {
    if (count[i] == 0) {
      memcpy(centroids + i * AV1_K_MEANS_DIM,
             data + (lcg_rand16(&rand_state) % n) * AV1_K_MEANS_DIM,
             sizeof(centroids[0]) * AV1_K_MEANS_DIM);
    } else {
      for (j = 0; j < AV1_K_MEANS_DIM; ++j) {
        centroids[i * AV1_K_MEANS_DIM + j] =
            DIVIDE_AND_ROUND(centroids[i * AV1_K_MEANS_DIM + j], count[i]);
      }
    }
  }
}

void RENAME(av1_k_means)(const int *data, int *centroids, uint8_t *indices,
                         int n, int k, int max_itr) {
  int centroids_tmp[AV1_K_MEANS_DIM * PALETTE_MAX_SIZE];
  uint8_t indices_tmp[MAX_PALETTE_BLOCK_WIDTH * MAX_PALETTE_BLOCK_HEIGHT];
  int *meta_centroids[2] = { centroids, centroids_tmp };
  uint8_t *meta_indices[2] = { indices, indices_tmp };
  int i, l = 0, prev_l, best_l = 0;
  int64_t this_dist;

  assert(n <= MAX_PALETTE_BLOCK_WIDTH * MAX_PALETTE_BLOCK_HEIGHT);

#if AV1_K_MEANS_DIM - 2
  av1_calc_indices_dim1(data, centroids, indices, &this_dist, n, k);
#else
  av1_calc_indices_dim2(data, centroids, indices, &this_dist, n, k);
#endif

  for (i = 0; i < max_itr; ++i) {
    const int64_t prev_dist = this_dist;
    prev_l = l;
    l = (l == 1) ? 0 : 1;

    RENAME(calc_centroids)(data, meta_centroids[l], meta_indices[prev_l], n, k);
#if AV1_K_MEANS_DIM - 2
    av1_calc_indices_dim1(data, meta_centroids[l], meta_indices[l], &this_dist,
                          n, k);
#else
    av1_calc_indices_dim2(data, meta_centroids[l], meta_indices[l], &this_dist,
                          n, k);
#endif

    if (this_dist > prev_dist) {
      best_l = prev_l;
      break;
    }
    if (!memcmp(meta_centroids[l], meta_centroids[prev_l],
                sizeof(centroids[0]) * k * AV1_K_MEANS_DIM))
      break;
  }
  if (i == max_itr) best_l = l;
  if (best_l != 0) {
    memcpy(centroids, meta_centroids[1],
           sizeof(centroids[0]) * k * AV1_K_MEANS_DIM);
    memcpy(indices, meta_indices[1], sizeof(indices[0]) * n);
  }
}
#undef RENAME_
#undef RENAME
