module Piggly
  module Reporter

    class Base
      include HtmlDsl

      def initialize(config)
        @config = config
      end

      # Copy each file to @config.report_root
      def install(*files)
        files.each do |name|
          src = File.join(File.dirname(__FILE__), name)
          dst = report_path(name)

          File.open(dst, "w"){|io| io.write(File.read(src)) }
        end
      end

      def report_path(file=nil, ext=nil)
        unless file.nil?
          # Remove the original extension from +file+ and add given extension
          @config.mkpath(@config.report_root, ext ?
            File.basename(file, ".*") + ext :
            File.basename(file))
        else
          @config.mkpath(@config.report_root)
        end
      end

    private

      def aggregate(label, summary)
        tag :p, label, :class => "summary"
        tag :table, :class => "summary sortable" do
          tag :tr do
            tag :th, "Blocks"
            tag :th, "Loops"
            tag :th, "Branches"
            tag :th, "Block Coverage"
            tag :th, "Loop Coverage"
            tag :th, "Branch Coverage"
          end

          tag :tr, :class => "even" do
            unless summary.include?(:block) or summary.include?(:loop) or summary.include?(:branch)
              # Parser couldn't parse this file
              tag(:td, :class => "count") { tag :span, -1, :style => "display:none" }
              tag(:td, :class => "count") { tag :span, -1, :style => "display:none" }
              tag(:td, :class => "count") { tag :span, -1, :style => "display:none" }
              tag(:td, :class => "pct")   { tag :span, -1, :style => "display:none" }
              tag(:td, :class => "pct")   { tag :span, -1, :style => "display:none" }
              tag(:td, :class => "pct")   { tag :span, -1, :style => "display:none" }
            else
              tag(:td, (summary[:block][:count]  || 0), :class => "count")
              tag(:td, (summary[:loop][:count]   || 0), :class => "count")
              tag(:td, (summary[:branch][:count] || 0), :class => "count")
              tag(:td, :class => "pct") { percent(summary[:block][:percent])  }
              tag(:td, :class => "pct") { percent(summary[:loop][:percent])   }
              tag(:td, :class => "pct") { percent(summary[:branch][:percent]) }
            end
          end
        end
      end

      def percent(pct)
        if pct
          tag :table, :align => "center" do
            tag :tr do
              tag :td, "%0.2f%%&nbsp;" % pct, :class => "num"

              style =
                case pct.to_f
                when 0...50;  "low"
                when 0...100; "mid"
                else          "high"
                end

              tag :td, :class => "graph" do
                if pct
                  tag :table, :align => "right", :class => "graph #{style}" do
                    tag :tr do
                      tag :td, :class => "covered", :width => (pct/2.0).to_i
                      tag :td, :class => "uncovered", :width => ((100-pct)/2.0).to_i
                    end
                  end
                end
              end
            end
          end
        else
          tag :span, -1, :style => "display:none"
        end
      end

      def timestamp
        tag :div, "Generated by piggly #{Piggly::VERSION} at #{Time.now.strftime("%B %d, %Y %H:%M %Z")}", :class => "timestamp"
      end
    end

  end
end
