// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

// sunview grey scale

#include <defines.h>
#include <gf_sun.h>
#include <surface.h>

#include <ctype.h>
#include <iostream.h>
#include <stdlib.h>

grey_font_sunview::grey_font_sunview(const uint16 width, const uint16 height) :
  grey_font(width, height)
{ bias = 0;
  heap_check(pr = new Pixrect* [w * h + 1]);
  _generate_squares();
}

// private -- generate memory versions of all the squares
void grey_font_sunview::_generate_squares(void)
{ for (int n_black = 0; n_black <= w * h; n_black++)
	 pr[n_black] = _generate_square(n_black);
}

// private -- generate a memory map of a single square
void* grey_font_sunview::_generate_square(const uint16 n_black)
{ Pixrect *ptr;

  const int square_size = w * h,
            breakpoint = square_size / 2;

  int  n_marked = 0, put_value, n_to_do, default_value = 1;

// create the empty square and a pointer to it
  ptr = mem_create(w, h, 1);    // CAREFUL! THIS USES MALLOC

  if (n_black > breakpoint) then
  { for (int i = 0; i < w; i++)
      for (int j = 0; j < h; j++)
        pr_put(ptr, i, j, default_value);
    put_value = 0;
    n_to_do = square_size - n_black;
  }
  else
  { put_value = default_value;
    n_to_do = n_black;
  }
  if (n_to_do)
  { for (int j = 1; n_marked < n_to_do; j++)
    { for (int i = 0; (i < square_size) && (n_marked < n_to_do); i++)
      { if ((pr_get(ptr, i % w, i / w) != put_value) && 
            ((random()  / 2147483648.0) < (1.0 / (10.0 * w)))) 
        { pr_put(ptr, i % w, i / w, put_value);
          n_marked++;
        }
      }
    }
  }
  return ptr;
}

uint16 grey_font_sunview::_rebuild(const uint16 width, const uint16 height)
{ if (pr) then
  { for (int n = 0; n <= w * h; n++)
    { if (pr[n]) then
        delete [] (pr[n]);
    }
    delete [] pr;
  }

  w = width;
  h = height;
  bias = (w * h < 50 ? 65 : 0);

  heap_check(pr = new Pixrect* [w * h + 1]);

  font_number = ++fonts_created;

  _generate_squares();
  index = 0;

  return (width * height);
};

