
#==============================================================================#
# $Id: scale_label.rb,v 1.3 2004/01/23 05:24:11 yuya Exp $
# $Source: /cvsroot/gruby/gruby/lib/grb/chart/xy_base/decorator/scale_label.rb,v $
#==============================================================================#

require 'grb/chart/base/decorator/no_child_base'
require 'grb/chart/base/utility/text'

#==============================================================================#

module GRb

  module Chart

    class ScaleLabelDecorator < NoChildDecoratorBase

      def initialize
        @scale  = nil
        @font   = nil
        @format = nil
      end

      attr_accessor :scale, :font, :format

      def draw(image, box)
        interval = @scale.interval
        delta    = @scale.delta
        raito    = @scale.raito(box.dy - 1)
        origin   = @scale.delta + @scale.minimum
        width    = self.dx

        if @scale.maximum > 0
          base   = [@scale.minimum, 0].max
          delta  = @scale.maximum - base
          number = (delta.to_f / interval.to_f).floor + 1

          (0...number).collect { |i|
            value = i * interval + base

            x = box.x + width
            y = box.y + (origin - value) * raito

            text = GRb::Chart::Text.new(@font, @format.call(value), GRb::Font::ALIGN_RIGHT, GRb::Font::VALIGN_MIDDLE)
            text.draw2(image, x, y)
          }
        end

        if @scale.minimum < 0
          base   = [@scale.maximum, 0].min
          delta  = (@scale.minimum - base).abs
          number = (delta.to_f / interval.to_f).floor

          (0..number).collect { |i|
            value = i * -interval + base

            x = box.x + width
            y = box.y + (origin - value) * raito

            text = GRb::Chart::Text.new(@font, @format.call(value), GRb::Font::ALIGN_RIGHT, GRb::Font::VALIGN_MIDDLE)
            text.draw2(image, x, y)
          }
        end
      end

      def dx
        texts = []

        if @scale.maximum > 0
          base   = [@scale.minimum, 0].max
          delta  = @scale.maximum - base
          number = (delta.to_f / @scale.interval.to_f).floor + 1

          (0...number).collect { |i|
            value = i * @scale.interval + base
            text  = @format.call(value)
            texts << GRb::Chart::Text.new(@font, text, GRb::Font::ALIGN_RIGHT, GRb::Font::VALIGN_MIDDLE)
          }
        end

        if @scale.minimum < 0
          base   = [@scale.maximum, 0].min
          delta  = (@scale.minimum - base).abs
          number = (delta.to_f / @scale.interval.to_f).floor

          (0..number).collect { |i|
            value = i * -@scale.interval + base
            text = @format.call(value)
            texts << GRb::Chart::Text.new(@font, text, GRb::Font::ALIGN_RIGHT, GRb::Font::VALIGN_MIDDLE)
          }
        end

        return texts.collect { |text| text.dx }.max
      end

    end # ScaleLabelDecorator

  end # Chart

end # GRb

#==============================================================================#

if $0 == __FILE__
  require 'grb/image'
  require 'grb/chart/scale'

  GRb::Image.create_and_write_png_file(200, 200, false, __FILE__.sub(/\.rb/, '.png')) { |image|
    GRb::Chart::Decorator::ScaleLabel.new.instance_eval {
      self.scale  = GRb::Chart::Scale.new(100, -20, 10)
      self.font   = GRb::Chart::Font.new(GRb::Font::Giant, GRb::Color.red(128))
      self.format = Proc.new { |value| '%02i' % value }
      self.draw(image, GRb::Chart::Box.new(10, 10, 180, 180))
    }
  }
end

#==============================================================================#
#==============================================================================#
