int socket, display, pane, rightpane, leftpane, enter_icon, host_icon, port_icon ;
int button_1, button_2, button_3, reverse_icon, prefix_icon, disconnect_icon ;
int lookup ;
string history[10] ;
int history_slot ;

string button_1_text, button_1_send ;
string button_2_text, button_2_send ;
string button_3_text, button_3_send ;

int fibo_counter ;

void change_history_slot(int inc)
{
  history[history_slot]=icon_contents(display, pane, enter_icon) ;
  history_slot=history_slot+inc ;
  history_slot=history_slot % 10 ;
  if (history_slot < 0) history_slot=10+history_slot ;
}

int pre_quit()
{
  text_to_display(display, 0, "Attempt to quit the application", "") ;
  return 0 ;
}

void enter_text(int display; int _pane; int icon; string text)
{
  if (_pane=pane)
  {
    if (icon=enter_icon)
    {
      change_history_slot(1) ;
      if (socket >= 0)
      {
        string send ;
        if (string_char(text, 0) != '.' && string_char(text, 0) != ''')
        {
          send=icon_contents(display, leftpane, prefix_icon) ;
        }
        string_cat(send, text) ;
        line_to_socket(socket, send) ;
      }
      else
      {
        text_to_display(display, 0, "\0300FF00You are not connected to a host", "") ;
      }
      set_icon_text(display, pane, enter_icon, "") ;
    }
    else
    {
      if (socket = -1)
      {
        if (lookup >= 0)
        {
          text_to_display(display, 0, "\0300FF00Aborting a lookup already in progress", "") ;
          abort_lookup(lookup) ;
        }
        string host ;
        host=icon_contents(display, pane, host_icon) ;
        text_to_display(display, 0, "Starting lookup", "") ;
        lookup=start_lookup(host, 0) ;
      }
      else
      {
        text_to_display(display, 0, "\0300FF00You are still connected", "") ;
      }
    }
  }
  else
  {
    if (_pane=leftpane)
    {
      caret_to_icon(display, pane, enter_icon, 0x7FFFFF) ;
    }
  }
}

int key_press(int display; int _pane; int icon; int code; int index)
{
  if (_pane=pane)
  {
    if (code=0x18E || code=0x18F)
    {
      if (icon=enter_icon)
      {
        if (code=0x18F)
        {
          change_history_slot(-1) ;
        }
        else
        {
          change_history_slot(1) ;
        }
        set_icon_text(display, pane, enter_icon, history[history_slot]) ;
      }
      else
      {
        if (icon=host_icon)
        {
          caret_to_icon(display, pane, port_icon, 0x7FFFFFFF) ;
        }
        else
        {
          if (icon=port_icon)
          {
            caret_to_icon(display, pane, host_icon, 0x7FFFFFFF) ;
          }
        }
      }
      return -1 ;
    }
  }
  return 0 ;
}

void shade_connection_icons()
{
  change_icon_colours(display, rightpane, disconnect_icon, 0x0000CC00, 0xCCCCCC00) ;

  change_icon_colours(display, pane, host_icon, 0x66666600, 0x88CCCC00) ;
  change_icon_colours(display, pane, port_icon, 0x66666600, 0x88CCCC00) ;
  change_icon_flags(display, pane, host_icon, 0, 0x40) ;
  change_icon_flags(display, pane, port_icon, 0, 0x40) ;
}

void revive_connection_icons()
{
  change_icon_colours(display, rightpane, disconnect_icon, 0x66666600, 0xCCCCCC00) ;

  change_icon_colours(display, pane, host_icon, 0, 0x00FFFF00) ;
  change_icon_colours(display, pane, port_icon, 0, 0x00FFFF00) ;
  change_icon_flags(display, pane, host_icon, 0x40, 0x40) ;
  change_icon_flags(display, pane, port_icon, 0x40, 0x40) ;
}

void socket_connection_attempted(int handle; int reason)
{
  if (reason > 0)
  {
    define_socket_to_text(socket, "\0a", 1, 0) ;
    shade_connection_icons() ;
    text_to_display(display, 0, read_time_string("Connected at %24:%mi on %dy.%mn.%ce%yr"), "") ;
  }
  else
  {
    text_to_display(display, 0, "\034400FFUnable to connect to host", "") ;
    socket=-1 ;
  }
}

void lookup_complete(int handle; int reason; int ip)
{
  if (reason=1)
  {
    int port ;
    string show ;

    port=string_to_int(icon_contents(display, pane, port_icon)) ;
    if (port=0) port=23 ;

    show="Connecting to " ;
    string_cat(show, int_to_dotted_ip(ip)) ;
    string_cat(show, " on port ") ;
    string_cat(show, int_to_string(port)) ;
    text_to_display(display, 0, show, "") ;
    socket=create_socket_nonblock(ip, port) ;
  }
  else
  {
    text_to_display(display, 0, "\0300FF00Lookup failed", "") ;
  }
  lookup=-1 ;
}

void reverse_lookup_complete(int handle; int reason; string name; int ip)
{
  if (reason=1)
  {
    text_to_display(display, 0, name, "") ;
  }
  else
  {
    text_to_display(display, 0, "\0300FF00Reverse lookup failed", "") ;
    text_to_display(display, 0, int_to_string(reason), "") ;
    text_to_display(display, 0, int_to_dotted_ip(ip), "") ;
  }
}

void line_from_socket(int handle; string got)
{
  int offset ;
  string send ;

  offset=find_string(got, "\1B[1m") ;
  while (offset >= 0)
  {
    replace_substring(got, offset, 4, "\02") ;
    offset=find_string(got, "\1B[1m") ;
  }
  offset=find_string(got, "\1B[0m") ;
  while (offset >= 0)
  {
    replace_substring(got, offset, 4, "\02") ;
    offset=find_string(got, "\1B[0m") ;
  }
  offset=find_string(got, "\02\02") ;
  while (offset >= 0)
  {
    replace_substring(got, offset, 2, "\02") ;
    offset=find_string(got, "\02\02") ;
  }
  text_to_display(display, 0, got, "") ;
}

void socket_closed(int handle)
{
  socket=-1 ;
  text_to_display(display, 0, "\0300FF00The remote end has closed the socket", "") ;
  revive_connection_icons() ;
}

void display_close_request(int display)
{
  if (socket >= 0)
  {
    text_to_display(display, 0, "You are still connected", "") ;
  }
  else
  {
    quit() ;
  }
}

int click(int display; int _pane; int _icon; int x; int y; int buttons)
{
  if ((buttons=1) || (buttons=4) || (buttons=256) || (buttons=4*256))
  {
    if (_pane=leftpane)
    {
      caret_to_icon(display, leftpane, prefix_icon, 0x7FFFFF) ;
    }
    else
    {
      if (_pane < 0 || _icon < 0)
      {
        caret_to_icon(display, pane, enter_icon, 0x7FFFFF) ;
      }
      else
      {
        if (_pane=rightpane && _icon >= 0)
        {
          if (_icon=reverse_icon)
          {
            string temp ;

            temp=icon_contents(display, pane, enter_icon) ;
            string_reverse(temp) ;
            set_icon_text(display, pane, enter_icon, temp) ;
          }
          if ( socket >= 0)
          {
            if (_icon=button_2)
            {
              line_to_socket(socket, button_2_send) ;
            }
            if (_icon=button_1)
            {
              string temp, line ;

              temp=icon_contents(display, pane, enter_icon) ;
              line=button_1_send ;
              string_cat(line, temp) ;
              line_to_socket(socket, line) ;
            }
            if (_icon=button_3)
            {
              line_to_socket(socket, button_3_send) ;
            }
            if (_icon=disconnect_icon)
            {
              if (buttons >= 256)
              {
                close_socket(socket) ;
                revive_connection_icons() ;
                socket=-1 ;
              }
              else
              {
                text_to_display(display, 0, "Double click to disconnect", "") ;
              }
            }
          }
          return -1 ;
        }
      }
    }
    return 0 ; /*although the click is used, don't mind Rabbit using it too*/
  }
  return 0 ;
}

void main()
{
  int version ;

  version=init("Oaktree Client", "Access the Oaktree House talker", "Sham Gardner", "0.00 (November 1997)", 0) ;
  socket=-1 ;
  lookup=-1 ;
  history_slot=0 ;

  display=open_display(80, 20, 200, "Oaktree") ;
  pane        =create_pane(display, 1072, 200, 1072, 200, 0, 16*13, 0, 0) ;
  rightpane   =create_pane(display, 250,  400, 250,  400, 3,     0, 0, 0) ;
  leftpane    =create_pane(display, 206,  200, 206,  200, 0,     0, 0, 0) ;

  disconnect_icon=create_icon(display, rightpane, 10,  10, 240,  60, 0x66666600, 0xCCCCCC00, 0xFFFFFFF, 2, 0x230,
                              "Disconnect", "") ;

  int file ;
  file=open_file("<Toth$Dir>.icons", 0) ;
  read_line(file, button_1_text) ;
  read_line(file, button_1_send) ;
  read_line(file, button_2_text) ;
  read_line(file, button_2_send) ;
  read_line(file, button_3_text) ;
  read_line(file, button_3_send) ;
  close_file(file) ;

  button_3    =create_icon(display, rightpane, 10, 160, 240, 210, 0, 0xCCCCCC00, 0xFFFFFFF, 2, 0x230, button_3_text, "") ;
  button_2    =create_icon(display, rightpane, 10, 220, 240, 270, 0, 0xCCCCCC00, 0xFFFFFFF, 2, 0x230, button_2_text, "") ;
  button_1    =create_icon(display, rightpane, 10, 280, 240, 330, 0, 0xCCCCCC00, 0xFFFFFFF, 2, 0x230, button_1_text, "") ;
  reverse_icon=create_icon(display, rightpane, 10, 340, 240, 390, 0, 0xCCCCCC00, 0xFFFFFFF, 2, 0x230, "Reverse",     "") ;

  prefix_icon =create_icon(display, leftpane,      0, 100, 206, 160, 0xCC00, 0xFFFFFF00, 36, 3,   0x64, "",       "") ;

  enter_icon  =create_icon(display, pane,   0, 100, 1072, 160, 0, 0xFFFFFF00, 4096, 3, 0x164, "",       "[\20-\\\7E]") ;
               create_icon(display, pane,  10,  10,  100,  70, 0, 0xDDDDDD00,   14, 0, 0x28,  "Host:",  "") ;
  host_icon   =create_icon(display, pane, 110,  10,  500,  70, 0, 0x00FFFF00,  128, 1, 0x64,  "toth.org.uk", "[a-z0-9\\.\\-]") ;
               create_icon(display, pane, 600,  10,  690,  70, 0, 0xDDDDDD00,   14, 0, 0x28,  "Port:",  "") ;
  port_icon   =create_icon(display, pane, 700,  10,  900,  70, 0, 0x00FFFF00,   10, 1, 0x64,  "23",  "[0-9]") ;
}
