#!/usr/bin/ruby
# Grid example — sortable/filterable table viewer
#
# Usage:
#   cd example && ruby grid [file]
#
# Reads a comma-separated file and displays it as an interactive table.
#
# Keys:
#   s         Sort by a column (prompts for column number)
#   f         Filter by column value
#   F         Pick fields to display
#   R         Select/deselect rows
#   C         Select/deselect columns
#   r         Reset sort, filter, and selection
#   `         Evaluate a Ruby expression (debug)
#   arrows    Scroll the viewport
#   esc       Exit
#
# The header line shows current time, active sort, filters,
# and selected rows. The user line shows available commands.

require_relative '../lib/typr.rb'

class GridTest
  include Typr

  def initialize
    Typr.init
    input = $<.read.split("\n").map{|l| l.split(',') }
    header = input.shift
    @grid = Grid.new(
      input: input,
      top: 1, right: -1, bottom: -2,
      format: [ 4, :max, 1, :min, :min ],
      header: header,
      colors: { columns: [ :yellow, :blue, :red, :green, :magenta] } )
    @user = Line.new( top: -1, default:
      "(s)ort, (f)ilter, (r)eset, select (R)ows/(C)olumns/(F)ields, [esc] quit")
    @head = Line.new( interval: 1,
      default: proc{ draw " %s, sort:%s filter:%s selected:%s" %
        [ Time.now.strftime("%D %T"),
          (@grid.header[@grid.sorted_by] if @grid.sorted_by),
          @grid.filters.join, @grid.selected ] } )
  end

  def run
    Typr.clear
    loop do
      @grid.show
      @user.show
      @head.start
      key = Typr.read_key
      @head.stop
      case key
        when KEY_ESCAPE; exit
        when ?` then (line = Typr.read_line) and @user.show(eval(line))
        when ?s then @grid.sort_by( @user.ask "sort column": [@grid, :column] )
        when ?F then @user.ask("pick fields": [@grid, :fields])
        when ?R then @user.ask("pick rows": [@grid, :rows])
        when ?C then @user.ask("pick columns": [@grid, :columns])
        when ?f then @grid.add_filter( *@user.ask("filter column":
          [@grid, :column], with: :line))
        when ?r then @grid.reset; @user.reset
        else @grid.send key; @user.reset
      end
    end
  end
end

begin
  GridTest.new.run
ensure
  Typr.exit
end
