/*
    GNU Octave level-set package.
    Copyright (C) 2013-2015  Daniel Kraft <d@domob.eu>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* Test program for fast marching.  */

#include "FastMarching.hpp"

#include <cmath>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>

using namespace fastMarching;

namespace fastMarching
{

/* Provide printf-based implementation of issueWarning.  */
void
issueWarning (const std::string&, const std::string& fmt, ...)
{
  va_list args;
  va_start (args, fmt);
  vprintf (fmt.c_str (), args);
  va_end (args);
}

} // namespace fastMarching

/**
 * Main routine.
 * @return Exit code 0.
 */
int
main ()
{
  static const unsigned N = 100;

  IndexTuple size(2);
  size[0] = N;
  size[1] = N;

  Grid grid(size);
  for (unsigned i = 0; i < N; ++i)
    for (unsigned j = 0; j < N; ++j)
      {
        size[0] = i;
        size[1] = j;

        if (i == N/2 && j == N/2)
          grid.setInitial (Entry::newAlive (size, 0.0, 0.0));
        else
          {
            realT f = 0.0;
            f += std::pow (static_cast<double> (i) - N/2, 2);
            f += std::pow (static_cast<double> (j) - N/2, 2);
            f = 1.0 - std::sqrt (f) / N * std::sqrt (1.8);
            f = 1.0 / f;
            grid.setInitial (Entry::newFarAway (size, f));
          }
      }

  grid.perform ();

  printf ("data = [ ...\n"); 
  for (unsigned i = 0; i < N; ++i)
    {
      for (unsigned j = 0; j < N; ++j)
        {
          size[0] = i;
          size[1] = j;
          const Grid& constGrid(grid);
          const Entry& cur = *constGrid.get (size);

          printf (" %f", cur.getDistance ());
          if (j + 1 < N)
            printf (",");
        }
      
      if (i + 1 < N)
        printf ("; ...\n");
      else
        printf (" ...\n");
    }
  printf ("];\n");

  return EXIT_SUCCESS;
}
