#include "globals.h"

#include <SDL_net.h>
#include <string.h>
#include "mcufstream.h"
#include "drawprimitives.h"
#include "globals.h"

// global
MCUF_Frame currentMCUFFrame;
Uint32 currentMCUFFrameNum;

// more or less local
UDPsocket MCUFsd;
IPaddress MCUFsrvadd;
UDPpacket *MCUFp;
Uint32 MCUFLastTick;

void initMCUFFrames() {
	// Reset frame number
	currentMCUFFrameNum = 0;
	
	
	// Open UDP Port
	//   Get the socket
    if (!(MCUFsd = SDLNet_UDP_Open(MCUFSTREAM_TARGETPORT))) {
        fprintf(stderr, "SDLNet_UDP_Open: %s\n", SDLNet_GetError());
        exit(EXIT_FAILURE);
    }
	
    //   Resolve server name
    if (SDLNet_ResolveHost(&MCUFsrvadd, MCUFSTREAM_TARGETHOST, MCUFSTREAM_TARGETPORT)) {
        fprintf(stderr, "SDLNet_ResolveHost(%s %d): %s\n", MCUFSTREAM_TARGETHOST, MCUFSTREAM_TARGETPORT, SDLNet_GetError());
        exit(EXIT_FAILURE);
    }
	
	/* Allocate memory for the packet */
    if (!(MCUFp = SDLNet_AllocPacket(sizeof(currentMCUFFrame)))) {
        fprintf(stderr, "SDLNet_AllocPacket: %s\n", SDLNet_GetError());
        exit(EXIT_FAILURE);
    }
	
	MCUFLastTick = SDL_GetTicks() + 10;
	
}

void deInitMCUFFrames() {
	SDLNet_FreePacket(MCUFp);
	SDLNet_UDP_Close(MCUFsd);
}

void recieveMCUFFrame(bool matrixMode) {
	while(!SDLNet_UDP_Recv(MCUFsd, MCUFp)) {

		SDL_Event event;
		while (SDL_PollEvent(&event)) 
		{
			switch (event.type) 
			{
				case SDL_KEYUP:
					exit(0);
					break;
			}
		}
		
		// Give up rest of allocated kernel timeslot to next program
		SDL_Delay(1);
	}

	memcpy(&currentMCUFFrame, MCUFp->data, sizeof(currentMCUFFrame));

	// check for magic
	if (currentMCUFFrame.magic[0] != 0x23 || currentMCUFFrame.magic[1] != 0x54 || currentMCUFFrame.magic[2] != 0x26 || currentMCUFFrame.magic[3] != 0x66) {
		return; //thats not an blinken-mcuf-udp-packet
	}

	// check for screen-size
	if (currentMCUFFrame.width[0] != 0x00|| currentMCUFFrame.width[1] != 0x12 || currentMCUFFrame.height[0] != 0x00 || currentMCUFFrame.height[1] != 0x08) {
		return; //thats not 18x8
	}
	
	// check for chan-count
	if (currentMCUFFrame.channels[0] != 0x00|| currentMCUFFrame.channels[1] != 0x03) {
		return; //thats not RGB
	}
	
	// Lock Surface if needed
	if (SDL_MUSTLOCK(gScreen))
		if (SDL_LockSurface(gScreen) < 0) 
			return;	
	
	for(Uint32 y = 0; y < 8; y++) {
		for(Uint32 x = 0; x < 18; x++) {
			char cval = currentMCUFFrame.pixels[0 + (x + y * 18) * 3];
			Uint32 colorR = (Uint32)cval;
			cval = currentMCUFFrame.pixels[1 + (x + y * 18) * 3];
			Uint32 colorG = (Uint32)cval;
			cval = currentMCUFFrame.pixels[2 + (x + y * 18) * 3];
			Uint32 colorB = (Uint32)cval;						
			Uint32 colorRGB = (colorR & 0xff) * 65536 + (colorG & 0xff) * 256 + (colorB & 0xff);
			drawrect(x * 20, y * 20, 20, 20, colorRGB);
		}
	}
	
	if (SDL_MUSTLOCK(gScreen)) 
		SDL_UnlockSurface(gScreen);

	SDL_Flip(gScreen); /* Update whole screen */
}

