// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

// class for grey scale for surface

#include <defines.h>
#include <gf_vga.h>
#include <surface.h>

#include <ctype.h>
#include <dos.h>
#include <graphics.h>
#include <iostream.h>
#include <stdlib.h>

grey_font_vga::grey_font_vga(const uint16 width, const uint16 height) :
  grey_font(width, height)
{ bias = 0;
  heap_check(pr = new char* [w * h + 1]);
  _generate_squares();
}

// destructor
grey_font_vga::~grey_font_vga(void)
{ if (pr) then
  { for (int n = 0; n <= w * h; n++)
    { if (pr[n]) then
        delete [] pr[n];
    }
    delete [] pr;
  }
}

uint16 grey_font_vga::_rebuild(const uint16 width, const uint16 height)
{ // g++ doesn't permit explicit call to destructor code
  if (pr) then
  { for (int n = 0; n <= w * h; n++)
    { if (pr[n]) then
        delete [] pr[n];
    }
    delete [] pr;
  }

  w = width;
  h = height;

  heap_check(pr = new char* [w * h + 1]);

  font_number = ++fonts_created;

  _generate_squares();
  index = 0;

  return (width * height);
};

// private -- generate a memory map of a single square
void* grey_font_vga::_generate_square(const uint16 n_black)
{ char *ptr = 0;
  if (!w || !h) then
    return ptr;

  const int square_size = w * h,
            breakpoint = square_size / 2;

  int  n_marked = 0, put_value, n_to_do, default_value = 15;

  const int size = imagesize(0, 0, w - 1, h - 1);
  heap_check(ptr = new char [size]);
 
  setfillstyle(0, 0);
  bar(0, 0, w - 1, h - 1);
  setpalette(default_value, EGA_BLACK);

  if (n_black > breakpoint) then
  { for (int i = 0; i < w; i++)
      for (int j = 0; j < h; j++)
        putpixel(i, j, default_value);
    put_value = 0;
    n_to_do = square_size - n_black;
  }
  else
  { put_value = default_value;
    n_to_do = n_black;
  }
  for (int j = 1; n_marked < n_to_do; j++)
  { for (int i = 0; (i < square_size) && (n_marked < n_to_do); i++)
    { if ((getpixel(i % w, i / w) != put_value) && 
          ((rand()  / (1.0 * RAND_MAX)) < (1.0 / (10.0 * w)))) 
      { putpixel(i % w, i / w, put_value);
        n_marked++;
      }
    }
  }
  getimage(0, 0, w - 1, h - 1, ptr);
  bar(0, 0, w - 1, h - 1);
  setpalette(default_value, EGA_WHITE);

  return ptr;
}

// private -- generate memory versions of all the squares
void grey_font_vga::_generate_squares(void)
{ for (int n_black = 0; n_black <= w * h; n_black++)
    pr[n_black] = (char*)_generate_square(n_black);
}
