#pragma once

/**
 * @brief Utility function that draws a circle using Bresenham's algorithm.
 * @tparam Functor the type of binary Functor that should be used.
 * @param functor the binary Functor that will be called everytime a pixel should be drawn.
 * @param radius the radius of the circle to draw.
 * @param filled true if the circle should be filled, false if only the border should be drawn.
 */
template<class Functor>
Functor& BresenhamCircle(Functor& functor, int radius, bool filled)
{
  if(radius == 0)
  {
    functor(0, 0); // ?
    return functor;
  }

  int x = 0;
  int y = radius;
  int prevy = radius;
  int h = 1 - radius;

  if(filled)
  {
    for(int i=1; i<2*radius; ++i)
    {
      functor(-radius + i, 0);
    }
  }

  functor(0,  radius);
  functor(0, -radius);
  functor( radius, 0);
  functor(-radius, 0);

  while(y > x+1)
  {
    prevy = y;

    if(h < 0)
    {
      h += 2*x + 3;
    }
    else
    {
      h += 2*(x-y) + 5;
      --y;
    }

    ++x;

    if(filled)
    {
      if(prevy > y && x < y)
      {
        for(int i=1; i<2*x; ++i)
        {
          functor(-x + i,  y);
          functor(-x + i, -y);
        }
      }

      for(int i=1; i<2*y; ++i)
      {
        functor(-y + i,  x);
        functor(-y + i, -x);
      }
    }

    functor( x,  y);
    functor(-x,  y);
    functor( x, -y);
    functor(-x, -y);
    if(x != y)
    {
      functor( y,  x);
      functor(-y,  x);
      functor( y, -x);
      functor(-y, -x);
    }
  }
  return functor;
}