module Coffeetags
  class Formatter
    # Generates CTAGS header
    # @returns [String] ctags header
    def self.header
      return [
        "!_TAG_FILE_FORMAT	2	/extended format/",
        "!_TAG_FILE_SORTED	0	/0=unsorted, 1=sorted, 2=foldcase/",
        "!_TAG_PROGRAM_AUTHOR	#{::Coffeetags::AUTHOR}",
        "!_TAG_PROGRAM_NAME	#{::Coffeetags::NAME}	//",
        "!_TAG_PROGRAM_URL	#{::Coffeetags::URL}	/GitHub repository/",
        "!_TAG_PROGRAM_VERSION	#{::Coffeetags::VERSION}	//"
      ].map { |h| "#{h}\n"}.join ''
    end

    def self.kinds
      return {
        'f' => 'function',
        'c' => 'class',
        'o' => 'object',
        'v' => 'var',
        'p' => 'proto',
        'b' => 'block'
      }
    end

    # New Formatter class
    #
    # @param [String] file file name
    # @param [Array] tree parse tree for given file generated by Coffeetags::Parser
    def initialize  file, tree =[]
      @file = file
      @tree = tree

      @header = Formatter.header
    end


    # Helper function for formatting a source line into regex
    def regex_line line
      "/^#{line.gsub(/([\\^$])/, '\\\\\1')}$/;\""
    end

    def line_to_string entry
      namespace = (entry[:parent].blank?) ? entry[:name]: entry[:parent]
      namespace =  namespace == entry[:name] ? '' : "object:#{namespace}"

      output = [
        entry[:name],
        @file,
        regex_line(entry[:source]),
        entry[:kind],
        "line:#{entry[:line]}",
        "language:coffee"
      ].join("\t")
      unless namespace.empty? then output << "\t#{namespace}" end
      output
    end

    def parse_tree
      @lines = @tree.map do | content|
        line_to_string content  unless content[:line].nil? or content[:name].blank?
      end
      @lines.reject!{|l| l.nil? }
    end

    def tags
      @lines.map { |l| "#{l}\n"}.join ''
    end

    def lines
      @lines
    end

  end
end
