#include <stdint.h>
#include <string.h>
#include "System.h"
#include "RCC.h"
#include "VGA.h"
#include "Random.h"
#include "Utils.h"
#include "Graphics/Bitmap.h"
#include "Graphics/Drawing.h"
#include "Logo.h"

#define NumberOfStars 1000

void Demo();

int main() {
  InitializeSystem();
  SysTick_Config(HCLKFrequency() / 100);
  InitializeVGA();
  Demo();
}

void Demo() {
  uint8_t* framebuffer1 = (uint8_t*)0x20000000;
  uint8_t* framebuffer2 = (uint8_t*)0x20010000; 
  memset(framebuffer1, 0, 320 * 200);
  memset(framebuffer2, 0, 320 * 200);
  SetVGAScreenMode320x200(framebuffer1);

  static struct Star {
    int x, y, dx;
  } stars[NumberOfStars];

  for (int i = 0; i < NumberOfStars; i++) {
    stars[i].x = RandomInteger() % 320;
    stars[i].y = RandomInteger() % 200;
    stars[i].dx = RandomInteger() % 3 + 1;
  }

  Bitmap frame1, frame2;
  InitializeBitmap(&frame1, 320, 200, 320, framebuffer1);
  InitializeBitmap(&frame2, 320, 200, 320, framebuffer2);

  int frame = 0;
  for (;;) {
    WaitVBL();

    Bitmap* currframe;
    if (frame & 1) {
      currframe = &frame2;
      SetFrameBuffer(framebuffer1);
    }
    else {
      currframe = &frame1;
      SetFrameBuffer(framebuffer2);
    }

    ClearBitmap(currframe);

    for (int i = 0; i < NumberOfStars; i++) {
      DrawPixel(currframe, stars[i].x, stars[i].y, RawRGB(1, 1, 1));

      stars[i].x -= stars[i].dx;
      if (stars[i].x <= 0) {
        stars[i].x = 320;
        stars[i].y = RandomInteger() % 200;
      }
    }

    DrawRLEBitmap(currframe, &logo, 49, 50);
    frame++;
  }
}

volatile uint32_t SysTickCounter=0;

void Delay(uint32_t time)
{
    uint32_t end=SysTickCounter+time;
      while(SysTickCounter!=end);
}

void SysTick_Handler()
{
    SysTickCounter++;
}

