Shoes.app(title: , height: 700, width: 700) do
  C = Math::cos(Math::PI/3)
  S = Math::sin(Math::PI/3)
  Radius = 60.0
  letters = [
   %w[L A R N D 1 2], 
   %w[G U I Y T 3 4], 
   %w[P C F E B 5 6], 
   %w[V S O M K 7 8],
   %w[Q X J Z H 9 0],
  ]

  def highlight(hexagon)
    hexagon.style(fill: magenta)
  end

  def unhighlight(hexagon)
    hexagon.style(fill: yellow)
  end

  def choose(hexagon)
    hexagon.choose
    highlight hexagon
    chosen = @hexagons.find_all {|h| h.chosen?}.map {|h| h.letter}
    if chosen.size == @hexagons.size
      @chosen.text = 'Every hexagon has been chosen.'
    else
      @chosen.text =  +
                      
    end
  end

  width = 20 + (Radius*(7*letters[0].size - 3)/4.0).ceil
  height = 60 + (Radius*(1 + 2*S*letters.size)).ceil
  @hexagons = []
  letter_to_hex = {}

  
  stack(height: height, width: width) do
    @chosen = para()

    
    letters.each_index do |row|
      letters[0].each_index do |column|
        x = 60 + column * Radius * 0.75 + (1-S) * Radius
        y = 80 + row * S * Radius + (column.odd?? S * Radius * 0.5: 0)
        h = shape(x-Radius, y-S*Radius) do
          strokewidth 3
          move_to(x-C*Radius, y-S*Radius)
          line_to(x+C*Radius, y-S*Radius)
          line_to(x+Radius,   y)
          line_to(x+C*Radius, y+S*Radius)
          line_to(x-C*Radius, y+S*Radius)
          line_to(x-Radius,   y)
          line_to(x-C*Radius, y-S*Radius)
        end

        
        class << h
          attr_accessor:x,:y,:state,:letter
          def chosen?
            not @state.nil?
          end
          def choose
            @state =:chosen
          end
          def contains?(px, py)
            if @x-Radius < px and px <= @x-C*Radius
              ratio = (px - @x + Radius)/(Radius*(1-C))
              @y - ratio*S*Radius < py and py <= @y + ratio*S*Radius
            elsif @x-C*Radius < px and px <= @x+C*Radius
              @y - S*Radius < py and py < @y + S*Radius
            elsif @x+C*Radius < px and px <= @x+Radius
              ratio = (@x + Radius - px)/(Radius*(1-C))
              @y - ratio*S*Radius < py and py <= @y + ratio*S*Radius
            else
              false
            end
          end
          def inspect
           %q(<%s,,%s,%d@%d>) % [self.class, letter, chosen?, x, y]
          end
        end

        h.x = x + x - Radius
        h.y = y + y - S*Radius
        h.letter = letters[row][column]
        unhighlight h

        @hexagons << h
        letter_to_hex[h.letter.downcase] = h
        letter_to_hex[h.letter.upcase] = h

        
        para(h.letter).style(size:56, stroke:red) \
                      .move(h.x - C*Radius, h.y - S*Radius)
      end
    end

    
    hex_over = nil
    motion do |x, y|
      hex = @hexagons.find {|h| h.contains?(x,y)}
      unless hex.nil? or hex.chosen?
        highlight hex 
      end
      unless hex_over == hex or hex_over.nil? or hex_over.chosen?
        unhighlight hex_over 
      end
      hex_over = hex
    end

    
    click do |button, x, y|
      info()
      hexagon = @hexagons.find {|h| h.contains?(x,y)}
      if hexagon
        info()
        choose hexagon
      end
    end

    
    keypress do |key| 
      if key ==   
        exit
      elsif key == 
        info @hexagons.collect {|h| h.inspect}.join()
      elsif letter_to_hex.has_key?(key)
        info()
        choose letter_to_hex[key]
      end
    end
  end
end