#!/usr/bin/env ruby

require "slang"
include Slang

Menu = [
  ["Color Test1", proc{color_test1}],
  ["Color Test2", proc{color_test2}],
  ["Alt charset test", proc{alt_char_test}],
  ["Alt charset with Kanji test", proc{alt_char_with_kanji_test}],
  ["Key Escape Sequence Report", proc{esc_seq_test}],
  ["Mouse test", proc{mouse_test}],
  ["Quit", proc{sl_reset; exit}]
]

def write_centered_string(s, row)
  return unless s
  
  len = s.size
  
  # Want 2 * col + len == SLtt_Screen_Rows
  if len >= sltt_screen_cols
    col = 0
  else 
    col = (sltt_screen_cols - len) / 2
  end

  slsmg_gotorc(row, col)
  slsmg_write_string(s)
end

def pre_test(title)
  slsig_block_signals
  slsmg_cls
  write_centered_string(title, 0)
end

def post_test
  write_centered_string("Press any key to return.", sltt_screen_rows - 1)
  slsmg_refresh
  slsig_unblock_signals
  slkp_getkey
end

def mouse_test
  pre_test("Mouse test");

  write_centered_string("Click mouse left button. Press 'q' to quit.", sltt_screen_rows - 1)
  slsmg_refresh

  color = rand(32767) % 16 + SL_BG_WHITE
  first = TRUE
  while TRUE
    case slkp_getkey
    when SL_KEY_ERR, ?q, ?Q
      break
    when SL_MOUSE_B0
      c, r = sl_get_mouse_rc
      if first
	slsmg_gotorc(r, c)
	x1 = c
	y1 = r
	first = FALSE
      else
	slsmg_gotorc(y1, x1)
	slsmg_write_char(0x20)	
	color += 1
	slsmg_set_color(color % 16 + 1)
	if c > x1
	  dx = c - x1 + 1
	else
	  dx = x1 - c + 1
	  x1 = c
	end
	if r > y1
	  dy = r - y1 + 1
	else
	  dy = y1 - r + 1
	  y1 = r
	end
	slsmg_draw_box(y1, x1, dy, dx)
	slsmg_gotorc(r, c)
	first = TRUE
      end
    else
      sltt_beep
    end
    slsmg_refresh
  end
  slsmg_set_color(0)
  slsmg_refresh
  slsig_unblock_signals
end

def color_test1
  pre_test("Color Test1");
  color_test_main(SL_BG_WHITE)
end

def color_test2
  pre_test("Color Test2");
  color_test_main(SL_BG_BLUE)
end

def color_test_main(start)
  row = 1
  color = start
  while row < sltt_screen_rows - 1
    slsmg_gotorc(row, 0)
    slsmg_set_color(color)
    slsmg_printf("color number = %d", color) 
    slsmg_erase_eol
    row += 1
    color += 1
  end   
  slsmg_set_color(0)
  post_test
end

def alt_char_with_kanji_test
  pre_test("Alternate Charset with Kanji Test")
  
  row = sltt_screen_rows / 2 - 2
  col = 0
  slsmg_gotorc(row, col)
  slsmg_write_string(" 漢字だよ ")

  row += 1
  slsmg_gotorc(row, col)
  slsmg_set_char_set(1)
  slsmg_write_char(?x)
  slsmg_set_char_set(0)
  slsmg_write_string("漢字だよ")
  slsmg_set_char_set(1)
  slsmg_write_char(?x)
  slsmg_set_char_set(0)
  
  row += 1
  slsmg_gotorc(row, col)
  slsmg_set_char_set(1)
  slsmg_write_char(?x)
  slsmg_write_string("漢字だよ")
  slsmg_write_char(?x)
  slsmg_set_char_set(0)
  
#  row += 1
#  altkanji = sprintf("\033)0\033(0x\033(Bx")
#  slsmg_gotorc(row, col)
#  slsmg_write_string(altkanji)
  post_test
end

def alt_char_test
  pre_test("Alternate Charset Test")
  
  row = sltt_screen_rows / 2 - 2
  col = 0
  for ch in 32..127
    slsmg_gotorc(row, col)
    slsmg_write_char(ch)
    slsmg_gotorc(row + 1, col)
    slsmg_set_char_set(1)
    slsmg_write_char(ch)
    slsmg_set_char_set(0)
    col += 1
    
    if col > 40
      col = 0
      row += 4
    end
  end
  
  post_test
end

def esc_seq_test
  pre_test("Escape Sequence Report")
  
  row = sltt_screen_rows / 2
  
  slsmg_gotorc(row, 0)
  slsmg_write_string("Press key: ")
  slsmg_refresh
  
  slsmg_gotorc(row, 0)
  slsmg_write_string("Key returned \"")
  
  b = []
  while TRUE
    ch = getkey
    if ch < 0x20 # space
      b.push(?^)
      b.push(ch + ?@)
    elsif ch >= 127
      sprintf("\\d%d", ch).each_byte{|c|
	b.push(c)
      }
    elsif (ch == ?") || (ch == ?\\)
      b.push(?\\)
    else
      b.push(ch)
    end
    break if sl_input_pending(3) <= 0
  end
  b.push(?")
  slsmg_write_string(b.pack("c*"))
  post_test
end

def print_menu
  slsig_block_signals

  slsmg_set_color(SL_BG_LGRAY+SL_BLACK)
  slsmg_cls

  row = 2
  Menu.each_index{|i|
    slsmg_gotorc(row, 3)
    slsmg_printf("%2d. %s", i, Menu[i][0])
    row += 1
    i += 1
  }
  
  row = 0
  slsmg_gotorc(row, 1)
  slsmg_write_string("Choose number:")
  
  slsmg_refresh
  slsig_unblock_signals
end

def select_menu_item(num)
  Menu.each_index{|i|
    if i == num
      Menu[i][1].call 
      return 0
    end
  }
  return -1
end


def menu_loop
  print_menu
  
  while TRUE
    ch = slkp_getkey - ?0
    
    if -1 == select_menu_item(ch)
      sltt_beep
      next
    end
    print_menu
  end
end

# ---- main
srand

mouse_on
exit unless init_terminal(1, 1)

sl_init_colors if sl_color_terminal?
slkp_define_keysym("\033[M\040", SL_MOUSE_B0)
slkp_define_keysym("\033[M\041", SL_MOUSE_B1) # not used
slkp_define_keysym("\033[M\042", SL_MOUSE_B2) # not used

menu_loop
