module Plasticine::Helpers
  def d3_include_tag
    javascript_include_tag("d3")
  end

  def column_visual(id, options={})
    PlasticineTagHelper.new(self, id, options[:from], options[:to], options[:step]).column(options)
  end

  def line_visual(id, options={})
    PlasticineTagHelper.new(self, id, options[:from], options[:to], options[:step]).line(options)
  end


  class PlasticineTagHelper
    attr_reader :rails_helpers

    delegate :content_tag,    to: :rails_helpers
    delegate :link_to,        to: :rails_helpers
    delegate :plasticine_url, to: :rails_helpers

    def initialize(rails_helpers, id, from, to, step)
      @rails_helpers = rails_helpers
      @id = id
      @from = from
      @to = to
      @step = step || 'month'
    end

    def column(options={})
      options.reverse_merge! columns_left_padding: 20, columns_right_padding: 20, columns_margin: 0.2, y_spacing_ratio: 1.10

      options[:data] = {
        columns_left_padding: options.delete(:columns_left_padding),
        columns_right_padding: options.delete(:columns_right_padding),
        columns_margin: options.delete(:columns_margin),
        y_spacing_ratio: options.delete(:y_spacing_ratio)
      }

      visual 'column', options
    end

    def line(options={})
      options.reverse_merge! lines_left_padding: 20, lines_right_padding: 20, lines_margin: 1, y_spacing_ratio: 1.10

      options[:data] = {
        lines_left_padding: options.delete(:lines_left_padding),
        lines_right_padding: options.delete(:lines_right_padding),
        lines_margin: options.delete(:lines_margin),
        y_spacing_ratio: options.delete(:y_spacing_ratio)
      }

      visual 'line', options
    end


  private

    def build_url(nature, options={})
      params = { from: @from, format: 'json', id: @id, nature: nature, nonce: SecureRandom.hex(20), step: @step, timestamp: Time.now.utc.iso8601, to: @to, version: 'v1' }

      options.each { |k,v| params[k] = v if not ['class', 'data', 'tools'].include? k.to_s }

      params[:token] = build_url_token(params)

      @url = plasticine_url(params)
    end

    def build_url_token(params)
      base_url = plasticine_url(id: params[:id])
      authentificator = Plasticine::Authentication.new(base_url, params)
      authentificator.tokenize
    end

    def t(path)
      Plasticine.translate(path)
    end

    def visual(nature, options={})
      options.reverse_merge! class: "", data: {}

      options[:class] += " plasticine plasticine-#{nature}"

      build_url nature, options

      options[:data][:visual] = nature
      options[:data][:url] = @url
      options[:data][:update_delay] = options[:update_every].to_i if options[:update_every]

      content = content_tag(:div, '', id: @id, class: options[:class], data: options[:data])
      content << link_to(@url, @url)

      content
    end
  end

  ::ActionView::Base.send :include, self
end