class Terminal::Table

def == other

def == other
  if other.respond_to?(:headings) && other.respond_to?(:rows)
    headings == other.headings && rows == other.rows
  end
end

def add_row row

def add_row row
  rows << row
end

def align_column n, alignment

def align_column n, alignment
  column(n).each_with_index do |col, i|
    @rows[i][n] = {:value => col, :alignment => alignment} unless col.is_a? Hash
  end
end

def column n

def column n
  rows.map { |row| row[n] }.compact 
end

def column_with_headings n

def column_with_headings n
  headings_with_rows.map { |row| row[n] }.compact  
end

def columns

def columns 
  (0..number_of_columns-1).map { |n| column n } 
end

def has_headings?

def has_headings?
  !headings.empty?
end

def headings_with_rows

def headings_with_rows
  [headings] + rows
end

def initialize options = {}, &block

def initialize options = {}, &block
  @headings = options.fetch :headings, []
  @rows = options.fetch :rows, []
  yield_or_eval &block if block_given?
end

def largest_cell_in_column n

def largest_cell_in_column n
  column_with_headings(n).sort_by { |cell| Cell.new(0, cell).length }.last
end

def length_of_column n

def length_of_column n
  largest_cell = largest_cell_in_column(n)
  if largest_cell.is_a? Hash
    largest_cell[:value].length# - 2
  else
    largest_cell.to_s.length
  end
end

def number_of_columns

def number_of_columns
  return rows.first.length unless rows.empty?
  raise Error, 'your table needs some rows.'
end

def render

def render
  buffer = seperator << "\n" 
  if has_headings?
    buffer << Y + headings.map_with_index do |heading, i|
      width = 0
      if heading.is_a?(Hash) and !heading[:colspan].nil?
        i.upto(i + heading[:colspan] - 1) do |col|
          width += length_of_column(col)
        end
        width += (heading[:colspan] - 1) * (Y.length + 2)
      else
        width = length_of_column(i)
      end
      Heading.new( width, heading).render
    end.join(Y) + Y
    buffer << "\n#{seperator}\n"
  end
  buffer << rows.map do |row| 
    Y + row.map_with_index do |cell, i|
      width = 0
      if cell.is_a?(Hash) and !cell[:colspan].nil?
        i.upto(i + cell[:colspan] - 1) do |col|
          width += length_of_column(col)
        end
        width += (cell[:colspan] - 1) * (Y.length + 2)
      else
        width = length_of_column(i)
      end
      Cell.new(width, cell).render
    end.join(Y) + Y 
  end.join("\n")
  buffer << "\n#{seperator}\n"
end

def seperator

def seperator
  I + columns.collect_with_index do |col, i| 
    X * (length_of_column(i) + 2) 
  end.join(I) + I 
end