
#include "libOLED/displayclass.H"

void
display_t::printString (font_t &font, char const *string, uint16_t length,
			colour_t colour)
{
  uint16_t const xSpacing = font.width () + 1;
  for (uint16_t yt = 0; yt < font.height (); yt++) // iterate down scan lines
    {
      uint16_t ys = m_cursor_y + yt;
      for (uint16_t xt = 0; xt < length; xt++)
	{
	  unsigned char c = string[xt];
	  uint16_t xs = xt * xSpacing + m_cursor_x;
	  for (uint16_t j = 0; j < font.spacing (); j++)
	    {
	      if (font.getPixel (c, j, yt) != 0)
		drawPixel (j + xs, ys, colour);
	    }
	}
    }
  // move the cursor.
  m_cursor_x += xSpacing * length;
}

// scale is multiplied by 256
void
display_t::printScaledString (font_t &font, char const *string,
				uint16_t length, uint16_t scale,
				colour_t colour)
{
  uint16_t xt, yt, jt, curr_x=0;
  uint16_t curr_y = m_cursor_y;
  if (scale < 1)
    return;
  for (yt = 0; yt < font.height () * 256; yt += scale) // iterate down scan lines
    {
      // iterate along the string
      // local x plotting coordinate
      curr_x = m_cursor_x;
      for (xt = 0; xt < length; xt++)
	{
	  for (jt = 0; jt < (font.spacing ()) * 256; jt += scale)
	    {
	      unsigned char c = (string[xt]);
	      if (font.getPixel (c, jt / 256, yt / 256))
		drawPixel (curr_x, curr_y, colour);
	      curr_x++;
	    }
	}
      curr_y++;
    }
  if (curr_x > width ())
    {
      curr_x = 0;
    }
  m_cursor_x = curr_x;
}

uint8_t
display_t::formatNum (char *buff, uint8_t siz, uint8_t digits, uint8_t dp_pos, int val)
{
  digits++;
  uint8_t pos = digits;
  uint8_t dp_loc = pos - dp_pos;
  uint8_t sign = 0;
  if (val < 0)
    {
      sign = 1;
      val = -val;
    }

  buff[pos] = 0;
  while (pos && pos < siz)
    {
      if (pos == dp_loc)
	{
	  buff[--pos] = '.';
	}
      else
	{
	  buff[--pos] = val % 10 + '0';
	  val /= 10;
	  if (val == 0 && pos < dp_loc)
	    break;
	}
    }
  if (sign)
    {
      buff[--pos] = '-';
    }
  return digits;
}

void
display_t::fontDigits (font_t &font, uint8_t digits, uint8_t dp_pos, int val)
{
  char buff[10] = "        ";
  uint8_t wid = formatNum (buff, sizeof(buff), digits, dp_pos, val);
  printString (font, buff, wid, WHITE );
}

void
display_t::fontSigDigits (font_t &font,uint8_t x, uint8_t y, bool right_justify, uint8_t dp_pos,
		 int val)
{
  char digits;
  char sign = 0;
  int uval;
  if (val < 0)
    {
      uval = -val;
      sign = 1; // mark as negative
    }
  else
    {
      uval = val;
    }
  if (uval < 10) // always one digit for a sign or space, one for a digit
    {
      digits = 1;
    }
  if (uval >= 10 && uval < 100)
    {
      digits = 2;
    }
  if (uval >= 100 && uval < 1000)
    {
      digits = 3;
    }
  if (uval >= 1000)
    {
      digits = 4;
    }
  // backup for the - sign if right justified
  if (right_justify)
    {
      if (dp_pos < 10)
	{
	  digits += 2;
	}
      else
	{
	  digits += 1;
	}
      x -= digits * font.spacing();
    }

  gotoxy (x, y);
  fontDigits (font, digits, dp_pos, val);
}


