#include "contiki.h"
#include "socket.h"
#include "ctk-draw.h"

#include <cbm.h>
#include <c64.h>
#include <string.h>

static struct {
  struct socket sout, sin;
  struct pt inpt, outpt;
  char outputbuf[200];
  char inputbuf[200];
  unsigned short len;
} s;

#define CURSOR_ON()  *(char *)0xcc = 0
#define CURSOR_OFF() *(char *)0xcc = 1
static void ctkmode(void);
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send(void))
{
  SOCKET_BEGIN(&s.sout);
  
  SOCKET_SEND(&s.sout, s.outputbuf, s.len);
  SOCKET_END(&s.sout);    
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_output(void))
{
  ctk_arch_key_t c;
  char *ptr;
  
  PT_BEGIN(&s.outpt);
  
  while(1) {
    PT_WAIT_UNTIL(&s.outpt, (ctk_mode_get() == CTK_MODE_EXTERNAL) &&
		  kbhit());


    ptr = s.outputbuf;
    s.len = 0;    
    while(kbhit() && s.len < sizeof(s.outputbuf)) {
      c = cgetc();
      *ptr = c;
      ++ptr;
      ++s.len;   
    }

    PT_WAIT_THREAD(&s.outpt, send());
  }
  PT_END(&s.outpt);      
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(void))
{
  unsigned short i;
  char *ptr;
  char next;
  
  next = 1; 
  PT_BEGIN(&s.inpt);
  
  while(1) {
    /* Wait until data arrives. */
    next = 0;
    PT_WAIT_UNTIL(&s.inpt, next && uip_newdata());

    CURSOR_OFF();
    /* Print it out on the screen. */
    ptr = (char *)uip_appdata;
    for(i = 0; i < uip_len; ++i) {
      cbm_k_bsout(*ptr);
      ++ptr;
    }
    CURSOR_ON();
  }  
  PT_END(&s.inpt);
}
/*---------------------------------------------------------------------------*/
static void
appcall(void *state)
{
  if(uip_closed() || uip_aborted() || uip_timedout()) {
    ctkmode();
  } else if(uip_connected()) {
  } else {
    handle_input();
    handle_output();   
  }
}
/*---------------------------------------------------------------------------*/
static struct uip_conn *
connect(u16_t *host, u16_t port)
{
  SOCKET_INIT(&s.sin, s.inputbuf, sizeof(s.inputbuf));
  SOCKET_INIT(&s.sout, s.inputbuf, sizeof(s.inputbuf));
  PT_INIT(&s.inpt);
  PT_INIT(&s.outpt);
  return tcp_connect(host, htons(port), NULL);
}
/*---------------------------------------------------------------------------*/
EK_POLLHANDLER(pollhandler);
EK_EVENTHANDLER(eventhandler, ev, data);
EK_PROCESS(p, "C/G terminal", EK_PRIO_NORMAL,
	   eventhandler, pollhandler, NULL);
static ek_id_t id = EK_ID_NONE;
static struct uip_conn *conn;
static u16_t serveraddr[2];
static u16_t serverport;
/*---------------------------------------------------------------------------*/
static struct ctk_window window;
static struct ctk_label hostlabel =
  {CTK_LABEL(0, 0, 4, 1, "Host")};
static char host[32];
static struct ctk_textentry hostentry =
  {CTK_TEXTENTRY(5, 0, 20, 1, host, sizeof(host) - 1)};
static struct ctk_label portlabel =
  {CTK_LABEL(27, 0, 4, 1, "Port")};
static char port[7];
static struct ctk_textentry portentry =
  {CTK_TEXTENTRY(32, 0, 4, 1, port, sizeof(port) - 1)};
static struct ctk_button connectbutton =
  {CTK_BUTTON(0, 2, 7, "Connect")};
static struct ctk_button switchbutton =
  {CTK_BUTTON(30, 2, 6, "Switch")};
static struct ctk_label helplabel =
  {CTK_LABEL(0, 4, 37, 1, "RUN/STOP to return from terminal view")};
/*---------------------------------------------------------------------------*/
LOADER_INIT_FUNC(cgterm_init, arg)
{
  arg_free(arg);
  if(id == EK_ID_NONE) {
    id = ek_start(&p);
  }
}
/*---------------------------------------------------------------------------*/
static void
ctkmode(void)
{
  ctk_mode_set(CTK_MODE_NORMAL);
  ctk_draw_init();
  ctk_desktop_redraw(NULL);
}
/*---------------------------------------------------------------------------*/
static void
textmode(void)
{
  ctk_mode_set(CTK_MODE_EXTERNAL);
  
  VIC.ctrl1 = 0x1b;  /* $D011 */
  VIC.addr  = 0x17;  /* $D018 */
  VIC.ctrl2 = 0xc8;  /* $D016 */
  CIA2.pra  = 0x03;  /* $DD00 */
  
  VIC.bordercolor = 0x00; /* $D020 */
  VIC.bgcolor0 = 0x00; /* $D021 */

  CURSOR_ON();
}     
/*---------------------------------------------------------------------------*/
EK_EVENTHANDLER(eventhandler, ev, data)
{
  u16_t *ipaddr;
  char *cptr;
    
  if(ev == tcpip_event) {
    appcall(data);
  } else if(ev == EK_EVENT_INIT) {
    ctk_window_new(&window, 38, 5, "C/G term");
    CTK_WIDGET_ADD(&window, &hostlabel);
    CTK_WIDGET_ADD(&window, &hostentry);
    CTK_WIDGET_ADD(&window, &portlabel);
    CTK_WIDGET_ADD(&window, &portentry);
    CTK_WIDGET_ADD(&window, &connectbutton);
    CTK_WIDGET_ADD(&window, &switchbutton);
    CTK_WIDGET_ADD(&window, &helplabel);
    ctk_window_open(&window);
  } else if(ev == ctk_signal_widget_activate) {

    if(data == (ek_data_t)&switchbutton) {
      textmode();
    } else if(data == (ek_data_t)&connectbutton) {
      serverport = 0;
      for(cptr = port; *cptr != ' ' && *cptr != 0; ++cptr) {
	if(*cptr < '0' || *cptr > '9') {
	  return;
	}
	serverport = 10 * serverport + *cptr - '0';
      }

      ipaddr = serveraddr;
      if(uiplib_ipaddrconv(host, (u8_t *)serveraddr) == 0) {
	ipaddr = resolv_lookup(host);
	if(ipaddr == NULL) {
	  resolv_query(host);
	} else {
	  uip_ipaddr_copy(serveraddr, ipaddr);
	}
      }
      if(ipaddr != NULL) {      
	conn = connect(serveraddr, serverport);
	if(conn != NULL) {
	  memset((char *)0x0400, 0x20, 40*25);
	  memset((char *)0xd800, 0x01, 40*25);
	  textmode();
	}
      }
    }
  } else if(ev == resolv_event_found) {
    ipaddr = resolv_lookup(host);
    if(ipaddr != NULL) {
      uip_ipaddr_copy(serveraddr, ipaddr);
      
      conn = connect(serveraddr, serverport);
      if(conn != NULL) {
	memset((char *)0x0400, 0x20, 40*25);
	memset((char *)0xd800, 0x01, 40*25);
	textmode();
      }
    }
  } else if(ev == EK_EVENT_REQUEST_EXIT ||
	    ev == ctk_signal_window_close) {
    ctk_window_close(&window);
    ek_exit();
    LOADER_UNLOAD();
  } 
}
/*---------------------------------------------------------------------------*/
EK_POLLHANDLER(pollhandler)
{
  if(ctk_mode_get() == CTK_MODE_EXTERNAL) {
    if(CIA1.prb == 0x7f) {
      ctkmode();
    } else if(kbhit() && conn != NULL) {
      tcpip_poll_tcp(conn);
    }
  }
}
/*---------------------------------------------------------------------------*/
