class Table
  
  #state = :enabled (default) or :disabled
  #sets the table responsive or non-responsive to clicks
  attr_writer :state
  
  #selected - returns the number of the curently selected row
  attr_reader :selected
  
  #block - sets a new Proc object to be called when row is clicked
  attr_writer :block
 
  #Sets up the table
  #top, left - position of the top and left corner of the table
  #height - number of rows to show without the vertical scrolling bar
  #headers - array of arrays containing headers and widths of the collumns)
  #          in the form of ["title", width]
  #items - array of arrays containing data to be displayed
  #blk - optional Proc object with a block to be called when the row is clicked
  def initialize(top, left, height, headers, items, blk=nil)
    @block=blk
    @selected=nil
    @state=:enabled
    @top=top
    @left=left
    @height=height
    @items=items 
    @headers=headers
    @columns=@headers.size
    mult = @items.size > @height ? 1:0
    $app.nostroke
    @width=2
    @item=[]
    @headers.each { |x| @width+=(x[1]+1)  }
    @flot=$app.stack :width=>@width+mult*12+2, :height=>31*(@height+1)+4, :top=>@top, :left=>@left do
      $app.background $app.red
      @header=$app.flow do
        @lefty=0
        @headers.each_with_index do |h,l|
          temp=(l==@headers.size-1 ? h[1]+12*mult : h[1])
          $app.flow :width=>temp,  :left=>@lefty+2, :top=>2 do
            $app.rect(0,0,temp,29, :fill=>$app.lightgrey)
            @lefty+=h[1]+1
            $app.para $app.strong(h[0]), :align=>'center'
          end
        end
      end
      @flot1=$app.stack :width=>@width+mult*12+2, :height=>31*(@height), :scroll=>true, :top=>33, :left=>1 do
        @items.each_with_index do |it, i|
          $app.inscription " "

          @item[i]=$app.stack :width=>@width-1, :top=>31*i+1, :left=>1 do
            @lefty=0
            rr=[]
            @columns.times do |ei|
              $app.flow :width=>@headers[ei][1], :height=>29, :left=>@lefty, :top=>0 do
                rr[ei]=$app.rect(0,0,@headers[ei][1],29, :fill=>$app.white)
                @lefty+=@headers[ei][1]+1
                it[ei]=" " if not it[ei] or it[ei]==""
                $app.inscription $app.strong(it[ei]), :align=>'center'
              end
            end

            $app.hover do
              if @state==:enabled
                @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.dimgray)}
              end
            end
            $app.leave do
              if @state==:enabled
                if @selected
                  if @selected==i
                    @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.salmon)}
                  else
                    @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.white)}
                  end
                else
                  @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.white)}
                end
              end
            end
            $app.click do
              if @state==:enabled
                if @selected
                  if @selected==i
                    @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.white)}
                    @selected=nil
                  else
                    @item[@selected].contents.each{|x| x.contents[1].style(:fill=>$app.white)} 
                    @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.salmon)}
                    @selected=i
                  end
                else
                  @item[i].contents.each{|x| x.contents[1].style(:fill=>$app.salmon)}
                  @selected=i
                end
                @block.call @items[i] if @selected and @block
              end  
            end         
          end
        end
      end  
    end
  end
    
  #Not yet tested functions, which did not worked due to the bug.
  #they should work now with the latest update of Shoes
  #Hids the table  
  def hide
    @flot.hide
  end
  #Shows the table
  def show
    @flot.show
  end
  #-------------------------------
  
  #Allows for manual selection of the row
  def set_selected(item_no)
    if @selected
      @selected=item_no
      @item[@selected].contents.each{|x| x.contents[1].style(:fill=>$app.salmon)}
    end
  end
 
  #Updates the current list of items shown in the table
  # items - array of items to show
  # height - height of table in rows
  def update_items(items, height=items.size)
    @items=items
    @height=height if height<=items.size
    @flot.remove
    initialize(@top, @left, @height, @headers, @items, @block)
  end 
  
end

Shoes.app do
  $app=self
  
  @t=nil
  @z=Proc.new {|x| alert x}
  @y=Proc.new {|x| alert "Hej: #{x}"}
  def create
    @t=Table.new(10, 10, 5, [[:Title1, 80], [:Title2, 50], ["A Bit Loner Title", 200]],[[1,"","dssd"],["ererer",:mle,"ss"],[2,:ale,"sdsdsd"],[3,:ale,"ss"],[4,:mle,"ss"]], @z)

  end
  @ww=stack do
    create     
  end
  b1=button "hide" do
    @t.hide
  end
  b2=button "show" do
    @t.show
  end
  b3=button "disable" do
    @t.state=:disbled
  end
  b4=button "enable" do
    @t.state=:enabled
  end
  b5=button "update" do
    @t.update_items([[1,:esdfsdd,"dssd"],[4,:mal],[2,:fle,"sdsdsd"],[1,:mdfle,"dssd"],[4,:ale,"ss"],[2,:ale,"sdsdsd"]],4)
    @t.block=@y
  end
  b1.move(10,250)
  b2.move(70,250)
  b3.move(130,250)
  b4.move(220,250)
  b5.move(290,250)

end