/* render-me
 * Written in 2012 by
 *   Andrew Poelstra <apoelstra@wpsoftware.net>
 *
 * To the extent possible under law, the author(s) have dedicated all
 * copyright and related and neighboring rights to this software to
 * the public domain worldwide. This software is distributed without
 * any warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication
 * along with this software.
 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

#include <stdlib.h>

static unsigned index (unsigned x, unsigned y, unsigned z, unsigned side)
{
  return (x * side * side) + (y * side) + z;
}

/* Turn NxNxN grid into a (2N)x(2N)x(2N) one */
double *smear_data (double *list, unsigned side_len)
{
  unsigned i, j, k;
  unsigned new_slen = side_len * 2 - 1;
  double *rv = malloc (new_slen * new_slen * new_slen * sizeof *rv);

  if (rv == NULL)
    return NULL;

  /* Copy data into new array */
  for (i = 0; i < side_len; ++i)
    for (j = 0; j < side_len; ++j)
      for (k = 0; k < side_len; ++k)
        {
          rv[index (2*i, 2*j, 2*k, new_slen)] = list[index (i, j, k, side_len)];
          /* fuck c */
          if (j < side_len - 1)
            {
              rv[index (2*i, 2*j, 2*k + 1, new_slen)] = 0;
              if (j < side_len - 1)
                {
                  rv[index (2*i, 2*j + 1, 2*k, new_slen)] = 0;
                  if (k < side_len - 1)
                    rv[index (2*i, 2*j + 1, 2*k + 1, new_slen)] = 0;
                }
            }
          if (i < side_len - 1)
            {
              rv[index (2*i + 1, 2*j, 2*k, new_slen)] = 0;
              rv[index (2*i + 1, 2*j, 2*k + 1, new_slen)] = 0;
              if (j < side_len - 1)
                {
                  rv[index (2*i + 1, 2*j + 1, 2*k, new_slen)] = 0;
                  if (k < side_len - 1)
                    rv[index (2*i + 1, 2*j + 1, 2*k + 1, new_slen)] = 0;
                }
            }
        }

  /* Smear horizontally */
  for (i = 0; i < side_len - 1; ++i)
    for (j = 0; j < side_len; ++j)
      for (k = 0; k < side_len; ++k)
        rv[index (2*i + 1, 2*j, 2*k, new_slen)] =
          (rv[index (2*i + 0, 2*j, 2*k, new_slen)] +
           rv[index (2*i + 2, 2*j, 2*k, new_slen)]) / 2;

  /* Smear vertically */
  for (i = 0; i < new_slen; ++i)
    for (j = 0; j < side_len - 1; ++j)
      for (k = 0; k < side_len; ++k)
        rv[index (i, 2*j + 1, 2*k, new_slen)] =
          (rv[index (i, 2*j + 0, 2*k, new_slen)] +
           rv[index (i, 2*j + 2, 2*k, new_slen)]) / 2;

  /* Smear depthically */
  for (i = 0; i < new_slen; ++i)
    for (j = 0; j < new_slen; ++j)
      for (k = 0; k < side_len - 1; ++k)
        rv[index (i, j, 2*k + 1, new_slen)] =
          (rv[index (i, j, 2*k + 0, new_slen)] +
           rv[index (i, j, 2*k + 2, new_slen)]) / 2;

  return rv;
}