#!/usr/bin/env rune
# Copyright 2004-2006 Kevin Reid, under the terms of the MIT X license
# found at http://www.opensource.org/licenses/mit-license.html ................
# This is a test application for an EIO  implementation. It's a trivial 'telnet' client - receive text, send text.
pragma.enable("easy-return")
pragma.disable("explicit-result-guard")
pragma.enable("accumulator")
pragma.enable("unary-star")
pragma.enable("dot-props")
def ScrollPaneConstants      := 
def makeBorderLayout         := 
def makeJFrame               := 
def makeJTextArea            := 
def makeKeyEvent             := 
def makeScrollPane           := 
def dimension                := 
def font                     := 
def network                  := (privilegedScope)
#def makeInCharDecoder        := 
#def makeOutCharEncoder       := 
# Using dot-props heavily as an experiment.
def [hostStr, portStr, charsetStr] := switch (interp::args) {
  match [a,b,c] { [a,b,c] }
  match [`@a:@b`, c] { [a,b,c] }
  match [a,b] { [a,b,"UTF-8"] }
  match [`@a:@b`] { [a,b,"UTF-8"] }
}
# --- Making UI ---
def send
# Derived from Den's ui.makeTerminal
def outputScrollPane := makeScrollPane()
  outputScrollPane::preferredSize := dimension(320,320)
  outputScrollPane::verticalScrollBarPolicy := ScrollPaneConstants::VERTICAL_SCROLLBAR_ALWAYS
    
  outputScrollPane::viewport."add(Component)"(
    def outputC := makeJTextArea()
    outputC::lineWrap := true
    outputC::font := font("Courier", 0, 10)
    outputC::editable := false
    outputC
  )
def inputC := ()
  inputC.addKeyListener(def enterKeyListener{
    to keyPressed(theEvent) :void {
      try {
        if (theEvent::keyCode == makeKeyEvent::VK_ENTER) {
          send(inputC::text)
          inputC.selectAll()
        }
      } catch p {
        throw <- (p)
      }
    }
    match _ {}
  })
def win := makeJFrame(`$hostStr:$portStr`)
win::contentPane := JPanel`
  $outputScrollPane.X.Y
  $inputC.X
`
# ---  ---
def ins
def outs
bind send(text) {
  stderr.println(`send($text)`)
  outs.whenAvailable(text.size() + 1, fn{
    stderr.println(`send whenAvailable thunk`)
    outs.write(text + "\n")
    outs.flush()
  })
}
win.addWindowListener(def mainWindowListener {
  to windowClosing(event) :void {
    try {
      ins.close()
    } catch p {
      throw <- (p)
    }
    try {
      outs.close()
    } catch p {
      throw <- (p)
    }
    interp.continueAtTop()
  }
  match _ {}
})
def doc := outputC::document
def handler() {
  if (ins.isTerminated()) {
    win::contentPane := JPanel`$outputScrollPane`
    # I couldn't get it to relayout and redraw properly any other way:
    def s := win::size
    win.setSize(s::width.floor(), s::height.floor() + 1)
    win.setSize(s::width.floor(), s::height.floor())
    #win.invalidate()
    #win::contentPane.invalidate()
    #win::contentPane.repaint()
  } else {
    doc.insertString(doc::length, __makeTwine.fromChars(ins.read(0, 2**16), null), null)
    ins <- whenAvailable(1, handler)
  }
}
ins <- whenAvailable(1, handler)
# --- Making connection ---
def remotePort := network.getRemoteTCPEndpoint(hostStr, __makeInt(portStr, 10))
def [bind ins, bind outs] := remotePort.connect(["textStreams" => charsetStr])
#def [rawIns, rawOuts] := remotePort.connect()
#stderr.println(`% makeInCharDecoder`)
#bind ins := makeInCharDecoder(rawIns, "ISO-8859-15", => stderr)
#stderr.println(`% makeOutCharEncoder`)
#bind outs := makeOutCharEncoder(rawOuts, "ISO-8859-15", => stderr)
stderr.println(`% showing window`)
win.show()
interp.blockAtTop()