module ActiveWarehouse
  module View
    # Abstract version of a view that displays data generated by a
    # ActiveWarehouse::Report::AbstractReport.  Takes care of basic
    # set up, but expects the classes that it is mixed into to implement
    # the code that turns the report results into HTML.
    module AbstractView
      # The ActiveWarehouse::Report::AbstractReport that is
      # controlling this View
      attr_reader :report
      
      # The ActiveWarehouse::Report::Dimension that this report pivots
      # on as a column.  (It would be better to accept more than two
      # dimensions.)
      # TODO: Could this be delegated to report?
      attr_reader :column_dimension

      # The ActiveWarehouse::Report::Dimension that this report pivots
      # on as a row.  (It would be better to accept more than two
      # dimensions.)
      # TODO: Could this be delegated to report?
      attr_reader :row_dimension

      # The params that should be passed down to any links generated 
      # for this view.  Allows you to store where you are in a hierarchy,
      # and modify that staging for drill-down links.
      attr_reader :current_params      
      
      # Create a new View that displays data generated by the
      # +report+.  The +params+ are used to figure out the
      # row_dimension and column_dimension (TODO: these could probably
      # be delegated to the report).  The +options+ are unused, but may
      # be useful for concrete implementations of AbstractView for
      # configuring how the report should be displayed, for example
      # directives for showing totals, or sortable columns.
      def initialize(report, params, options = {})
        @report = report
        @current_params = HashWithIndifferentAccess.new.merge(report.html_params)

        @column_dimension = ActiveWarehouse::Report::Dimension.column(@report, parse(params,:cstage, report.column_param_prefix))
        @row_dimension = ActiveWarehouse::Report::Dimension.row(@report, parse(params,:rstage, report.row_param_prefix))
      end

      # Helper for constructing part of the data needed to create a
      # ActiveWarehouse::Report::Dimension.  Extracts the stage and
      # ancestors of the hierarchy into a hash.  This could probably
      # be moved into ActiveWarehouse::Report::AbstractReport, and
      # further cleaned up so it was less dependent on the request
      # params.
      def parse(html_params, stage_key, param_prefix)
        params = HashWithIndifferentAccess.new
        if html_params[stage_key]
          params[:stage] = html_params[stage_key]
          @current_params[stage_key] = html_params[stage_key]
        end
        ancestors = HashWithIndifferentAccess.new
        html_params.each do |key, value|
          if key =~ /^#{param_prefix}_(.*)/
            ancestors[$1] = value
            @current_params[key] = value
          end
        end
        params[:ancestors] = ancestors
        params
      end
    end
  end
end