#include <windows.h>
#include <math.h>
#include "ZGo.h"



//---- ZGO STRUCTURES --------------------------------------------------------//

//---- ZGoDATA

ZGoDATA::ZGoDATA()
{
  input_of = NULL;
  output_of = NULL;
}

ZGoDATA::ZGoDATA(ZGo *zgo)
{
  this->zgo = zgo;
  input_of = NULL;
  output_of = NULL;
  frame = 0;
}
  
ZGoDATA *ZGoDATA::setInput(ZGoFn *fn)
{
  input_of = fn;
  return this;
}

ZGoDATA *ZGoDATA::setOutput(ZGoFn *fn)
{
  output_of = fn;
  return this;
}
  
void ZGoDATA::process()
{
  if(frame == zgo->frame) return;

  frame = zgo->frame;
  if(output_of != NULL) output_of->process();
}



//---- ZGoFn

ZGoFn::ZGoFn()
{
  this->fnType = new ZGoNAME(zgo, "(ZGoFn)");
}

ZGoFn::ZGoFn(ZGo *zgo, ZGoPARAMS *input, ZGoPARAMS *output)
{
  this->zgo = zgo;
  this->input = input->setInput(this);
  this->output = output->setOutput(this);
  this->fnType = new ZGoNAME(zgo, "ZGoFn");
}

void ZGoFn::process()
{
}

ZGoNAME *ZGoFn::getType()
{
  return fnType;
}


//---- ZGO SYSTEM CLASS ------------------------------------------------------//

//---- ZGo

ZGo::ZGo(int w, int h)
{
  //- Internal variables
   
  frame = 0;
  for(int i=0; i<256; i++) keypress[i] = false;

  //- Set up ZGo tree

  time = new ZGoREAL(this);
  result = new ZGoIMAGE(this, w, h);

  main = new ZGoMain(this,
    (new ZGoPARAMS(this))->add("time", time),
    (new ZGoPARAMS(this))->add("result", result)
  );
}



//---- render

void ZGo::render(double t)
{
  frame ++;
  time->value = t;
  result->process();
}



//---- display

void ZGo::display(HDC dc)
{
  BITMAPINFO bmi;

  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  bmi.bmiHeader.biWidth = result->w;
  bmi.bmiHeader.biHeight = -(signed)result->h;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = 32;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biSizeImage = 0;
  bmi.bmiHeader.biXPelsPerMeter = 1000;
  bmi.bmiHeader.biYPelsPerMeter = 1000;
  bmi.bmiHeader.biClrUsed = 0;
  bmi.bmiHeader.biClrImportant = 0;

  StretchDIBits(
    dc,
    0, 0, result->w, result->h,
    0, 0, result->w, result->h,
    (LPVOID)result->buf,
    (LPBITMAPINFO)&bmi,
    DIB_RGB_COLORS, SRCCOPY
  );

}



//---- keyDown

void ZGo::keyDown(int key)
{
  if(key >= 0 && key < 256) keypress[key] = true;
}



//---- keyUp

void ZGo::keyUp(int key)
{
  if(key >= 0 && key < 256) keypress[key] = false;
}



//---- keyPressed

bool ZGo::keyPressed(int key)
{
  if(key >= 0 && key < 256) return keypress[key];
  return false;
}



//---- end of file -----------------------------------------------------------//


