#include "gfddrawingcontext.h"

#include "gfd_grifo_fonts.h"
#include "gc_color_theme.h"

#include <stdarg.h>

GfdDrawingContext GrifoDrawingContext::phyDeviceDisplay;
GfdDrawingContext GrifoDrawingContext::wholeDisplay;
GfdDrawingContext GrifoDrawingContext::movingArea;



static gfd_framebuffer_t rdrAreaFb;
static gfd_framebuffer_t movingAreaFb;

static struct {
	int rox;
	int roy;
	int ox;
	int oy;
	int rdrw;
	int rdrh;
	int mw;
	int mh;
}  subframe_params;

void GrifoDrawingContext::setup(gfd_framebuffer_t &fb, int rox, int roy, int rw, int rh, int ox, int oy, int mw, int mh)
{
  phyDeviceDisplay.cx.fb=&fb;

  wholeDisplay.cx.fb=&rdrAreaFb;
  movingArea.cx.fb=&movingAreaFb;

  subframe_params.rox=rox;
  subframe_params.roy=roy;
  subframe_params.ox=ox;
  subframe_params.oy=oy;
  subframe_params.mw=mw;
  subframe_params.mh=mh;

  subframe_params.rdrw=rh;
  subframe_params.rdrh=rw;

  setFramebufferMemory(phyDeviceDisplay.cx.fb->buffer);

  //gfd_fb_subframe(&rdrAreaFb, &fb, rox, roy, fb.dx-2*rox, fb.dy-2*rox);
  //gfd_fb_subframe(&movingAreaFb, &rdrAreaFb, ox, oy, mw, mh);
}


void GrifoDrawingContext::setFramebufferMemory(void* p)
{
	phyDeviceDisplay.cx.fb->buffer=reinterpret_cast<uint8_t*>(p);
	gfd_framebuffer_t& fb=*phyDeviceDisplay.cx.fb;


	gfd_fb_subframe(&rdrAreaFb, &fb, subframe_params.rox, subframe_params.roy, subframe_params.rdrw, subframe_params.rdrh);
	gfd_fb_subframe(&movingAreaFb, &rdrAreaFb, subframe_params.ox, subframe_params.oy, subframe_params.mw, subframe_params.mh);
}

void GrifoDrawingContext::setDebug()
{
  //setColor(64);
  //setFont(fontDebug());
}

/*
const gfd_font256_tag_t& GrifoDrawingContext::fontSmall() { return gfd_font256_F5_10x14;}
const gfd_font256_tag_t& GrifoDrawingContext::fontMicro() { return gfd_font256_F5_10x14;}
const gfd_font256_tag_t& GrifoDrawingContext::fontLarge() { return gfd_font256_F5_14x20;}
const gfd_font256_tag_t& GrifoDrawingContext::fontDebug() { return gfd_font256_PC_8x8;}
*/
const gfd_font256_tag_t& GrifoDrawingContext::fontSmall() { return gfd_font256_GEN_9x13;}
const gfd_font256_tag_t& GrifoDrawingContext::fontMicro() { return gfd_font256_GEN_9x13;}
const gfd_font256_tag_t& GrifoDrawingContext::fontLarge() { return gfd_font256_GEN_13x19;}
const gfd_font256_tag_t& GrifoDrawingContext::fontDebug() { return gfd_font256_GEN_7x7;}

void GfdDrawingContext::initialize()
{
	cx.main_color = 127;
	cx.occl_color =   1;
	cx.dbg_color  =  gc_color_theme::gc_color_dbg;
	cx.trsp_color =   0;
	cx.font     = &GrifoDrawingContext::fontSmall();
	cx.dbg_font = &gfd_font256_PC_8x8;
}


int GfdDrawingContext::printf(int x, int y, const char* fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  int n=GfdDrawingContext::vprintf(x, y, fmt, args);
  va_end(args);
  return n;
}

int GfdDrawingContext::vprintf(int x, int y, const char* fmt, va_list args)
{
  cx.crs_y=y;
  int n=gfd_fb_vprintf(cx.fb, cx.font, x, y, cx.main_color, fmt, args);
  cx.crs_x=x+n;
  return n;
}

int GfdDrawingContext::textWidth(const char* fmt, ...) const
{
  va_list args;
  va_start(args, fmt);
  int n=GfdDrawingContext::vtextWidth(fmt, args);
  va_end(args);
  return n;
}

int GfdDrawingContext::textLen(const char* text, int maxCnt)
{
  return gfd_textLen(text, maxCnt);
}

char* GfdDrawingContext::textCpy(char *dest, const char *source, int count)
{
  return gfd_textCpy(dest, source, count);
}

int GfdDrawingContext::vtextWidth(const char* fmt, va_list args) const
{
  int n=gfd_fb_text_vmeasure(cx.fb, cx.font, 0, 0, cx.main_color, fmt, args);
  return n;
}

int GfdDrawingContext::textHeight() const
{
  return cx.font->height;
}

int GfdDrawingContext::dbgPrintf(int x, int y, const char* fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  int n=GfdDrawingContext::dbgVprintf(x, y, fmt, args);
  va_end(args);
  return n;
}

int GfdDrawingContext::dbgPrintfColor(int x, int y, int color, const char* fmt, ...)
{
	  va_list args;
	  va_start(args, fmt);
	  int n=GfdDrawingContext::dbgVprintfColor(x, y, color, fmt, args);
	  va_end(args);
	  return n;
}

int GfdDrawingContext::dbgVprintfColor(int x, int y, int color, const char* fmt, va_list args)
{
  cx.crs_y=y;
  if (color<0)
	  color=cx.dbg_color;
  int n=gfd_fb_vprintf/*_cs*/(cx.fb, cx.dbg_font, x, y, color, fmt, args);
  cx.crs_x=x+n;
  return n;
}

int GfdDrawingContext::dbgVprintf(int x, int y, const char* fmt, va_list args)
{
  cx.crs_y=y;
  int n=gfd_fb_vprintf/*_cs*/(cx.fb, cx.dbg_font, x, y, cx.dbg_color, fmt, args);
  cx.crs_x=x+n;
  return n;
}

