#include <string.h>
#include "../mcu/serial.h"
#include "../mcu/delay.h"
#include "../util/myprintf.h"
#include "../util/sockutil.h"
#include "../util/util.h"
#include "../iinchip/socket.h"
#include "../evb/config.h"
#include "../evb/lcd.h"
#include "../evb/led.h"
#include "../evb/evb.h"
#include "../app/ping_app.h"

#include "manage.h"

u_char manage_network(void);
u_char manage_channel(void);
void select_ch_app(CHCONF* pChConf, u_char ch);

/*
Description  : Check to enter administrator mode
Argument     : 
Return Value : 
Note         : 
*/
void check_manage(void)
{
	int i,j;
	char key;

	if(get_reset_flag()== SYSTEM_AUTO_RESET)
	{
		set_reset_flag(SYSTEM_MANUAL_RESET);
		return;
	}
	
	printf("\r\nPress 'M' to enter the manager mode");

	lcd_clrscr();
	lcd_gotoxy(0,0);
	lcd_puts("< MANAGE  MODE >");
	lcd_gotoxy(0,1);
	led_on(0);
	led_off(1);
	for (i = 0; i < 16; i++)
	{
		for ( j = 0 ; j < 40 ; j++)
		{
			if(uart_keyhit(0))
			{
				key = uart0_getchar();
				if(key == 'M' || key == 'm')
				{
					manage_config();
					return;
				}
				else if(key == 0x1B) return;					
			}
			wait_1ms(10);
		}
		printf("\a.");	
		lcd_putch(0xFF);
		led_toggle(0);
		led_toggle(1);
	}
	printf("\r\n");
	led_on(0);
	led_on(1);
	
}

void manage_config(void)
{
	u_char sel = 0;
	u_char bmodify=0;
	
	get_chconf(&ChConf);
	while(sel != 'e' && sel != 'E')
	{
		printf("\r\n===================\r\n");
		printf("EVB B/D MANAGE MODE\r\n");
		printf("===================\r\n");
		printf("1 : Network Config\r\n");
		printf("2 : Channel Config\r\n");
		printf("3 : Ping App Test\r\n");
		printf("F : Factory Reset\r\n");
		printf("E : Exit\r\n");
		printf("===================\r\n");
	
		printf("Select ? ");
		
		evb_set_lcd_text(1,"  Select Menu?  ");
		
		sel = uart0_getchar();
		uart0_putchar(sel);
		uart_puts(0, "\r\n");
		switch(sel)
		{
		case '1' : evb_set_lcd_text(1," Network Config ");
			bmodify |= manage_network();
			break;
		case '2' : evb_set_lcd_text(1," Channel Config ");
			bmodify |= manage_channel();
			break;

		case '3' : evb_set_lcd_text(1,"  Ping Request  ");
			net_init();
			ping_request();
			bmodify = 1;
			break;

		case 'F' :
		case 'f' : printf("Factory Reset\r\n");
			load_factory_netconf();
			load_factory_chconf();
			bmodify = 1;
			break;
		case 'E' : 
		case 'e' : printf("Exit Network Config\r\n");
			break;
		default : printf("\aInvalid Selectiton\r\n");
			break;
		}
	}
	if(bmodify) evb_soft_reset();
}


u_char manage_network(void)
{
	u_char sel = 0;
	u_char ret = 0;
	char addrstr[30];
	char * tok;
	u_int i, tnum;
	u_char tmac[6];
	
	get_netconf(&NetConf);

	while(sel != 'e' && sel != 'E')
	{
		printf("------------------\r\n");
		printf("NETWORK CONFIG\r\n");
		printf("------------------\r\n");
		printf("D : Display config\r\n");
		printf("1 : Source IP\r\n");
		printf("2 : Gateway IP\r\n");
		printf("3 : Subnet Mask\r\n");
		printf("4 : DNS Server IP\r\n");
		printf("M : MAC address\r\n");
		printf("A : Memory Allocation\r\n");
		printf("F : Factory reset\r\n");
		printf("E : Exit\r\n");
		printf("------------------\r\n");
		printf("Select ? ");	

		sel = uart0_getchar();
		uart0_putchar(sel);
		uart_puts(0, "\r\n");

		switch(sel)
		{
		case 'd' :
		case 'D' : display_netconf(&NetConf);
			break;
		case '1' : printf("Source IP ? ");
			uart_gets(0, addrstr,0,30);
			if(!VerifyIPAddress(addrstr))
			{
				printf("\aInvalid.\r\n");
				continue;
			}
			NetConf.sip = htonl(inet_addr(addrstr));
			ret = 1;
			break;
		case '2' : printf("Gateway IP ? ");
			uart_gets(0, addrstr,0,30);
			if(!VerifyIPAddress(addrstr))
			{
				printf("\aInvalid.\r\n");
				continue;
			}
			NetConf.gwip = htonl(inet_addr(addrstr));
			ret = 1;		
			break;
		case '3' : printf("Subnet Mask ? ");
			uart_gets(0, addrstr,0,30);
			if(!VerifyIPAddress(addrstr))
			{
				printf("\aInvalid.\r\n");
				continue;
			}
			NetConf.sn = htonl(inet_addr(addrstr));
			ret = 1;
			break;
		case '4' :printf("DNS Server IP ? ");
			uart_gets(0, addrstr,0,30);
			if(!VerifyIPAddress(addrstr))
			{
				printf("\aInvalid.\r\n");
				continue;
			}
			NetConf.dns = htonl(inet_addr(addrstr));
			ret = 1;
			break;
		case 'M' :
		case 'm' : printf("MAC Address ? ");
			uart_gets(0, addrstr,0,30);
			tok = addrstr;
			for(i = 0; i < 6; i++)
			{
				tok = strtok(tok,".");
				if (tok == 0 && i != 5) break;
				if(!ValidATOI(tok,0x10,&tnum)) break;
				if(tnum < 0 || tnum > 255) break;
				tmac[i] = tnum & 0xFF;
				printf("%.2x", tmac[i]);
				tok = NULL;
			}		
			if( i != 6)
			{
				printf("\aInvalid.\r\n");
				//continue;
			}
			else
			{
				memcpy(NetConf.mac,tmac,6);
				ret = 1;
			}
			break;
		case 'A' :
		case 'a' : printf("Memory Alloc ? ");
			uart_gets(0, addrstr,0,3);
			NetConf.Mem_alloc = ATOI(addrstr,0x10);
			printf("%.2x\r\n", NetConf.Mem_alloc);
			break;
		case 'F' :
		case 'f' : printf("Factory Reset\r\n");
			load_factory_netconf();
			ret = 1;
			break;
		case 'E' : 
		case 'e' : set_netconf(&NetConf);
			printf("Exit Network Config\r\n");
			break;
		case 0x1B: printf("User canceled.\r\n");
			break;
		default : printf("\aInvalid Selectiton\r\n");
			break;
		}
	}
	return ret;
}


u_char manage_channel(void)
{
	u_char sel = 0;
	u_char ret = 0;
	u_char ii = 0;
	
	get_chconf(&ChConf);

	while(sel != 'e' && sel != 'E')
	{
		printf("------------------\r\n");
		printf("CHANNEL CONFIG\r\n");
		printf("------------------\r\n");
		printf("D : Display Config\r\n");
		for (ii = 0; ii < MAX_SOCK_NUM; ii++) printf("%d : %dth Channel\r\n", ii, ii);
		printf("F : Factory Reset\r\n");
		printf("E : Exit\r\n");
		printf("------------------\r\n");
		printf("Select ? ");	

		sel = uart0_getchar();
		uart0_putchar(sel);
		uart_puts(0, "\r\n");

		switch(sel)
		{
		case '0' : 
		case '1' : 
		case '2' : 
		case '3' :  select_ch_app(&ChConf,sel-'0');
			break;
		case 'D' :
		case 'd' : display_chconf(&ChConf);
			break;
		case 'F' :
		case 'f' : printf("Factory Reset\r\n");
			load_factory_chconf();
			ret = 1;
			break;
		case 'E' : 
		case 'e' : set_chconf(&ChConf);
			printf("Exit Channel Config\r\n");
			break;
		case 0x1B: printf("User canceled.\r\n");
			break;
		default : printf("\aInvalid Selectiton\r\n");
			break;
		}
	}
	return ret;
}


void select_ch_app(CHCONF* pChConf, u_char ch)
{
	u_char sel,i,bloop;
	u_int port;
	char addrstr[16];
	u_long addr;
	bloop = 1;
	while(bloop)
	{
		printf("Select the followed APPs type for %d channel.\r\n",ch);
		printf("\t0 : No Use\r\n"); 
		if(!ch) printf("\t1 : DHCP Client\r\n");
		printf("\t2 : Loop-Back TCP Server\r\n");
		printf("\t3 : Loop-Back TCP Client\r\n");
		printf("\t4 : Loop-Back UDP\r\n");
		printf("\t5 : Web Server\r\n");
		printf("Select ? ");
		sel = uart0_getchar();
		uart0_putchar(sel);
		uart_puts(0, "\r\n");
		switch(sel)
		{
		case '0': pChConf->ch[ch].type = NOTUSE;
			bloop = 0;
			break;
		case '1': 
			if(!ch)
			{ 
				pChConf->ch[0].type = DHCP_CLIENT;
				bloop = 0;
			}
			else 
			{
				printf("\aInvalid.\r\n");
				bloop = 1;
			}
			break;
		case '2': 
			while(1)
			{
				printf("Listen Port Num (1~65535) ? ");
				uart_gets(0, addrstr,0,8);
				if(addrstr[0] == 0) 
				{
					port = DEFAULT_LISTEN_PORT;
					printf("Default Applied. %d\r\n",port);
					break;
				}
				if(addrstr[0] == '0' && addrstr[1] == 'x')
				{
					if(ValidATOI(addrstr+2,0x10,&port)) break;
				}
				else if(ValidATOI(addrstr,10,&port)) break;
				printf("\aInvalid Range.\r\n");
			}
			if(!port)
			{
				port = DEFAULT_LISTEN_PORT;
				printf("Default Applied. %d\r\n",port);
			}
			pChConf->ch[ch].type = LB_TCPS;
			pChConf->ch[ch].port = port;
			bloop = 0;
			break;
		case '3':
			while(1)
			{
				printf("Server IP Address ? ");
				uart_gets(0, addrstr,0,16);
				if(addrstr[0] == 0) 
				{
					addr = htonl(DEFAULT_CH_DESTIP);
					printf("Default Applied. %s\r\n",inet_ntoa(ntohl(addr)));
					break;
				}
				if(VerifyIPAddress(addrstr))
				{
					addr = htonl(inet_addr(addrstr));
					break;
				}
				printf("\aInvalid Range.\r\n");
			}
			pChConf->ch[ch].destip = addr;
			while(1)
			{
				printf("Server Port Num (1~65535) ? ");
				uart_gets(0, addrstr,0,8);
				if(addrstr[0] == 0) 
				{
					port = DEFAULT_CONNECT_PORT;
					printf("Default Applied. %d\r\n",port);
					break;
				}
				if(addrstr[0] == '0' && addrstr[1] == 'x')
				{
					if(ValidATOI(addrstr+2,0x10,&port)) break;
				}
				else if(ValidATOI(addrstr,10,&port)) break;
				printf("\aInvalid Range.\r\n");
			}
			if(!port)
			{
				port = DEFAULT_CONNECT_PORT;
				printf("Default Applied. %d\r\n",port);
			}
			pChConf->ch[ch].port = port;
			pChConf->ch[ch].type = LB_TCPC;
			bloop = 0;
			break;
		case '4':
			while(1)
			{
				while(1)
				{
					printf("Source Port Num (1~65535) ? ");
					uart_gets(0, addrstr,0,8);
					if(addrstr[0] == 0) 
					{
						port = DEFAULT_SOURCE_PORT;
						printf("Default Applied. %d\r\n",port);
						break;
					}
					if(addrstr[0] == '0' && addrstr[1] == 'x')
					{
						if(ValidATOI(addrstr+2,0x10,&port)) break;
					}
					else if(ValidATOI(addrstr,10,&port)) break;
					printf("\aInvalid Range.\r\n");
				}
				if(!port)
				{
					port = DEFAULT_SOURCE_PORT;
					printf("Default Applied. %d\r\n",port);
				}
				for(i=0; i < MAX_SOCK_NUM; i++)
				{
					if(ch!=i && pChConf->ch[i].type == LB_UDP && pChConf->ch[i].port == port)
					{
						i+=10;
						break;
					}
				}
				if(i==MAX_SOCK_NUM) break;
				printf("\aYou can't use the same port number in UDP. The %d channel is same.\r\n",i-10);
			}
			pChConf->ch[ch].port = port;
			pChConf->ch[ch].type = LB_UDP;
			bloop = 0;
			break;
		case '5':
			while(1)
			{
				printf("HTTP Port Num (1~65535) ? ");
				uart_gets(0, addrstr,0,8);
				if(addrstr[0] == 0) 
				{
					port = DEFAULT_HTTP_PORT;
					printf("Default Applied. %d\r\n",port);
					break;
				}
				if(addrstr[0] == '0' && addrstr[1] == 'x')
				{
					if(ValidATOI(addrstr+2,0x10,&port)) break;
				}
				else if(ValidATOI(addrstr,10,&port)) break;
				printf("\aInvalid Range.\r\n");
			}
			if(!port)
			{
				port = DEFAULT_HTTP_PORT;
				printf("Default Applied. %d\r\n",port);
			}
			pChConf->ch[ch].port = port;
			pChConf->ch[ch].type = WEB_SERVER;
			bloop = 0;
			break;
		case 0x1b: printf("User canceled.\r\n");
			break;
		default: printf("\aInvalid.\r\n");
			break;
		}
	}
}

