#! ruby
# NetMaster's FTP Component example
# author: YOSHIDA Kazuhiro <moriq@moriq.com>

require 'phi'
include Phi
require 'fastnet/socket'
require 'fastnet/ftp'
require 'dialogs'
require 'rgui/ui'

form = RGUI::Form.new :form1
form.caption = 'NetMaster\'s FTP Component example'
form.height = RGUI.min form.height * 2, Phi::SCREEN.height - 64
form.width  = RGUI.min form.width  * 2, Phi::SCREEN.width  - 64

labels = [
  Label.new(form, :lbl_host, 'host'),
  Label.new(form, :lbl_user, 'user'),
  Label.new(form, :lbl_passwd, 'passwd'),
]
def label_fixed(lbl)
  lbl.layout = Phi::TL_BOTTOM
end
labels.each { |i| label_fixed i }

edits = [
  form.lbl_host, Edit.new(form, :edit_host, 'ftp.ring.gr.jp'),
  form.lbl_user, Edit.new(form, :edit_user, 'ftp'),
  form.lbl_passwd, Edit.new(form, :edit_passwd, 'moriq@moriq.com'),
]

rgrp_mode = RadioGroup.new form # Transfer Mode
rgrp_mode.height*=  60
rgrp_mode.height/= 100

buttons = [
  Button.new(form, :btn_connect, 'Connect'),
  Button.new(form, :btn_dirlist, 'Dir List'),
  Button.new(form, :btn_chdir, 'Chdir'),
  Button.new(form, :btn_download, 'Download'),
  Button.new(form, :btn_upload, 'Upload'),
  Button.new(form, :btn_upload_append, 'Upload Append'),
  Button.new(form, :btn_upload_unique, 'Upload Unique'),
  Button.new(form, :btn_upload_restore, 'Upload Restore'),
  Button.new(form, :btn_abort, 'Abort'),
]

memos = [
  Memo.new(form, :memo1), # Status Window
  Memo.new(form, :memo2), # Directory List display
]
def memo_fixed(memo)
  memo.scroll_bars = Phi::SS_VERTICAL
  memo.font.name = '‚l‚r ƒSƒVƒbƒN'
end
memos.each { |i| memo_fixed i }
form.memo1.height = 160

vbox1 = UI::Vbox.new [buttons], 8
vbox1.width = 160

vbox2 = UI::Vbox.new [edits, rgrp_mode]
vbox2.height = form.client_height - form.memo2.height

hbox2 = UI::Hbox.new [form.memo1, vbox2], 8, true
hbox2.height = 80

hbox3 = UI::Hbox.new [form.memo2], 8
hbox3.height = 60

vbox4 = UI::Vbox.new [hbox2, hbox3], 8
vbox4.width = form.client_width - vbox1.width

hbox1 = UI::Hbox.new [vbox4, vbox1]

form.add hbox1

StatusBar.new form, :status_bar # File Transfer progress
form.status_bar.simple_panel = true

rgrp_mode.caption = 'mode'
rgrp_mode.items.add 'ascii'
rgrp_mode.items.add 'image'
rgrp_mode.items.add 'binary'
rgrp_mode.item_index = 0

def rgrp_mode.ftp_mode
  case item_index
  when 0; ?a
  when 1; ?i
  when 2; ?b
  end
end

form.layout
form.show

ftp = NMFTP.new

form.btn_connect.on_click = proc do
  if ftp.connected
    ftp.disconnect
  else
    ftp.host = form.edit_host.text
    ftp.user = form.edit_user.text
    ftp.passwd = form.edit_passwd.text
    ftp.connect
  end
end

form.btn_dirlist.on_click = proc do
  form.memo2.clear
  ftp.dirlist
  info = ftp.dirinfo
  p info
  for i in 0...info.name.count
    form.memo2.lines.add [
      info.attr[i].ljust(10),
      info.name[i].ljust(24),
      info.size[i].rjust(10),
      info.date[i].rjust(12),
    ].join(' ')
  end if info
end

form.btn_chdir.on_click = proc do
  ok, the_dir = Phi.input_query 'Change directory', 'Directory name?', ''
  if ok
    ftp.chdir the_dir
  end
end

form.btn_download.on_click = proc do
  local = ''
  open_dlg = OpenDialog.new
  ok, remote = Phi.input_query 'Download a file', 'File to download: ', ''
  if ok
    open_dlg.title = 'Save file as'
    if open_dlg.execute
      local = open_dlg.file_name
      ftp.mode rgrp_mode.ftp_mode
      ftp.download remote, local
    end
  end
end

ftp.on_connect = proc do
  form.memo1.lines.add 'Connected'
  form.btn_connect.caption = 'Disconnect'
end

ftp.on_disconnect = proc do
  form.memo1.lines.add 'Disconnected'
  form.btn_connect.caption = 'Connect'
end

Powersock.on_packet_recv = proc do
  form.status_bar.simple_text =
    "%d bytes out of %d received" % [ftp.bytes_recv, ftp.bytes_total]
end

Powersock.on_packet_sent = proc do
  form.status_bar.simple_text =
    "%d bytes out of %d transfer" % [ftp.bytes_sent, ftp.bytes_total]
end

ftp.on_transaction_start = proc do
  form.memo1.lines.add 'Transaction Start'
end

ftp.on_transaction_stop = proc do
  form.memo1.lines.add 'Transaction Stop'
end

form.btn_upload.on_click = proc do
  local = ''
  open_dlg = OpenDialog.new
  open_dlg.title = 'Select file to upload'
  ok, remote = Phi.input_query 'Choose remote file name', 'Filename?', ''
  if ok
    if open_dlg.execute
      local = open_dlg.file_name
      ftp.mode rgrp_mode.ftp_mode
      ftp.upload local, remote
    end
  end
end

form.btn_upload_append.on_click = proc do
  local = ''
  open_dlg = OpenDialog.new
  open_dlg.title = 'Select file to upload'
  if open_dlg.execute
    ok, remote = Phi.input_query 'Choose remote file name', 'Filename?', ''
    if ok
      local = open_dlg.file_name
      ftp.mode rgrp_mode.ftp_mode
      ftp.upload_append local, remote
    end
  end
end

form.btn_upload_unique.on_click = proc do
  local = ''
  open_dlg = OpenDialog.new
  open_dlg.title = 'Select file to upload'
  if open_dlg.execute
    local = open_dlg.file_name
    ftp.upload_unique local
  end
end

ftp.on_failure = proc do |sender, cmd|
  form.memo1.lines.add cmd << ' failure'
end

ftp.on_success = proc do |sender, cmd|
  form.memo1.lines.add cmd << ' success'
end

form.btn_upload_restore.on_click = proc do
  local = ''
  open_dlg = OpenDialog.new
  open_dlg.title = 'Select file to upload'
  if open_dlg.execute
    ok, remote = Phi.input_query 'Choose remote file name', 'Filename?', ''
    if ok
      ok, pos = Phi.input_query 'Choose restoration point', 'Byte count:', ''
      if ok
        pos = pos.to_i
        local = open_dlg.file_name
        ftp.mode rgrp_mode.ftp_mode
        ftp.upload_restore local, remote, pos
      end
    end
  end
end

form.btn_abort.on_click = proc do
  ftp.abort
end

form.on_resize = proc { form.layout }

form.show
Phi.mainloop
