#include <nds.h>
#include <nds/arm9/console.h> //basic print funcionality
#include <stdio.h>
#include <stdlib.h>
#include "draw.h"
#include "widgets.h"
#include "config.h"
#include "wifi.h"
#include "token.h"

volatile int frame = 0;

void Vblank()
{
	frame++;
}

int main(void) 
{
	touchPosition touch;
	touchPosition old;
	struct Widget *touched = NULL;
	struct Widget *lastTouched = NULL;
	char buf[255];
	char addr[16];
	char *args[MAX_NUM_TOKENS];
	int buttons[12] = {KEY_X, KEY_Y, KEY_A, KEY_B, KEY_SELECT, KEY_START, KEY_RIGHT, KEY_LEFT, KEY_UP, KEY_DOWN, KEY_R, KEY_L};
	char *names[12] = {"x", "y", "a", "b", "select", "start", "right", "left", "up", "down", "r", "l"};
	int b;
	
	args[0] = NULL;
	old.px = 0;
	old.py = 0;
	
	// Initialise the interrupt system
	irqInit();
	// install our simple vblank handler
	irqSet(IRQ_VBLANK, Vblank);
	// enable the interrupt
	irqEnable(IRQ_VBLANK);
	
	powerON(POWER_ALL_2D);
	videoSetMode(MODE_FB0);
	vramSetBankA(VRAM_A_LCD);
	
	// Setup console screen to display information.
	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE );
	vramSetBankC(VRAM_C_SUB_BG);
	SUB_BG0_CR = BG_MAP_BASE(31);
	BG_PALETTE_SUB[255] = BGCOLOR;
	consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
	
	// Swap the screens so the draw screen is the bottom screen.
	lcdSwap();
	
	// print out the title of this program
	iprintf("\33[2J");
	iprintf("\x1b[2;2HKnobsAndSlidersDS");
	iprintf("\x1b[3;2H-----------------\n\n");
	
	head = NULL;
	
	init_wifi();
	init_udp_connection();
	sendpacket("KnobsAndSlidersDS started\n");
	my_ip(addr);
	sprintf(buf, "ip %s\n", addr);
	sendpacket(buf);
	init_udp_connection_out();
	
	while(1)
	{
		// vertical retrace interrupt at the bottom of the screen
		// while(VCOUNT < 100);
		
		//BG_PALETTE_SUB[0] = RGB15(0, 31, 0);
		swiWaitForVBlank();

		//BG_PALETTE_SUB[0] = RGB15(31, 31, 31);
		// clear the screen
		clear_screen(VRAM_A, BGCOLOR);
		
		//BG_PALETTE_SUB[0] = RGB15(31, 0, 0);
		DrawAllWidgets();
		
		//BG_PALETTE_SUB[0] = RGB15(0, 0, 31);
		// read the button states
		scanKeys();
		
		// read the touchscreen coordinates
		touch = touchReadXY();
		
		int pressed = keysDown();	// buttons pressed this loop
		int released = keysUp();        // buttons released this loop
		int held = keysHeld();		// buttons currently held
		
		//BG_PALETTE_SUB[0] = RGB15(31, 31, 0);
		receivepackets(args);
		
		//BG_PALETTE_SUB[0] = RGB15(31, 0, 31);
		// see what messages we've been sent
		if (args[0] != NULL)
		{
			if (!strncmp(args[0], "add", 10))
			{
				if (args[1] != NULL)
				{
					iprintf("adding %s %d\n", args[1], atoi(args[2]));
					if (!strncmp(args[1], "slider", 7))
					{
						AddWidget(MakeSlider(atoi(args[2]), atoi(args[3]), atoi(args[4]), atoi(args[5]), atoi(args[6]), atoi(args[7]), args[8][0]));
					}
					else if (!strncmp(args[1], "knob", 5))
					{
						AddWidget(MakeKnob(atoi(args[2]), atoi(args[3]), atoi(args[4]), atoi(args[5]), atoi(args[6]), atoi(args[7])));
					}
					else if (!strncmp(args[1], "toggle", 5))
					{
						AddWidget(MakeToggle(atoi(args[2]), atoi(args[3]), atoi(args[4]), atoi(args[5]), atoi(args[6]), atoi(args[7])));
					}
				}
			}
			else if (!strncmp(args[0], "del", 10))
			{
				if (args[1] != NULL)
				{
					iprintf("deleting %d\n", atoi(args[1]));
					DelWidget(atoi(args[1]));
				}
			}
			else if (args[1] != NULL)
			{
				SetValue(atoi(args[0]), atoi(args[1]));
			}
			
			// now reset our args so we don't get anything else
			ResetArgs(args);
		}
		
		//BG_PALETTE_SUB[0] = RGB15(0, 31, 31);
		if (pressed & KEY_TOUCH)
		{
			touched = FindTouched(head, touch.px, touch.py);
		}
		
		//BG_PALETTE_SUB[0] = RGB15(0, 0, 0);
		if (held & KEY_TOUCH)
		{
			if (old.px == 0 && old.py == 0)
			{
				old.px = touch.px;
				old.py = touch.py;
			}
			
			if (touched && touched->type == 's')
			{
				SetSlider(touched, touch.px - old.px, touch.py - old.py);
			}
			else if (touched && touched->type == 'k')
			{
				SetKnob(touched, touch.px - old.px, touch.py - old.py);
			}
			else if (touched && touched->type == 't' && touched != lastTouched)
			{
				SetToggle(touched);
			}
		}
		else
		{
			touched = NULL;
		}
		
		old.px = touch.px;
		old.py = touch.py;
		lastTouched = touched;
		
		for (b = 0; b < 12; b++)
		{
			if (pressed & buttons[b])
			{
				sprintf(buf, "key %s 1;\n", names[b]);
				sendpacket(buf);
			}
			if (released & buttons[b])
			{
				sprintf(buf, "key %s 0;\n", names[b]);
				sendpacket(buf);
			}
		}
	}
	
	return 0;
}

