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

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

static struct {
  struct psock 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))
{
  PSOCK_BEGIN(&s.sout);
  
  PSOCK_SEND(&s.sout, s.outputbuf, s.len);
  PSOCK_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)
{
  PSOCK_INIT(&s.sin, s.inputbuf, sizeof(s.inputbuf));
  PSOCK_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);
    }
  }
}
/*---------------------------------------------------------------------------*/
