require 'div/div'
require 'div/tofusession'
require 'amida'

class AmidaApp
  def initialize(width, height)
    resize(4)
    @img = AmidaMagick.new(width, height)
    @show = nil
    @result = {}
  end
  attr_reader :amida
  attr_reader :img
  
  def size; @amida.size; end

  def resize(size)
    @amida = Amida.new(size)
    @amida.setup_branch
    @show = nil
    @result = {}
  end

  def show(idx)
    @show = idx
    v = @amida.trace(idx) 
    @result[v] = idx
  end

  def add(x, y)
    return if @show
    pos = @img.add_branch(@amida, x, y)
    @result = {}
  end

  def to_image
    canvas = @img.canvas
    @img.draw_field(@amida).draw(canvas)
    @img.draw_entry(@amida, @show).draw(canvas) if @show
    canvas.to_blob { self.format = 'JPEG' }
  end

  def entry(idx)
    idx + 1
  end

  def goal(idx)
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[idx,1]
  end

  def result(idx)
    it = @result[idx]
    return '' unless it
    entry(it)
  end
end

class AmidaFieldDiv < Div::Div
  set_erb('amida_field.erb')

  def initialize(session, amida)
    super(session)
    @amida = amida
    @width = amida.img.width
    @height = amida.img.height
    @seq = 1
  end

  def to_pos(params)
    x ,= params['img.x']
    y ,= params['img.y']
    return nil if x.nil?
    return nil if y.nil?
    [x.to_i, y.to_i]
  end

  def do_add(conext, params)
    x, y = to_pos(params)
    return unless x
    @amida.add(x, y)
  end
  
  def do_show(context, params)
    idx ,= params['idx']
    return unless idx
    @amida.show(idx.to_i)
  end
  
  def image_path(context)
    @seq += 1
    context.req_script_name.to_s + '/image' + "?#{id}_#{@seq}"
  end
end

class AmidaDiv < Div::Div
  set_erb('amida.erb')
  
  def initialize(session)
    super(session)
    @amida = AmidaApp.new(512, 640)
    @field = AmidaFieldDiv.new(session, @amida)
  end
  attr_reader :amida, :field
  
  def to_image
    @amida.to_image
  end
  
  def do_size(context, params)
    size ,= params['size']
    return unless size
    size = size.to_i
    return if size < 2
    return if size > 8
    @amida.resize(size)
  end
end

class BaseDiv < Div::Div
  set_erb('base.erb')

  def initialize(session)
    super(session)
    @amida_div = AmidaDiv.new(session)
  end
  attr_reader :amida_div
end

class AmidaTofuSession < Div::TofuSession
  def initialize(bartender, hint=nil)
    super(bartender, hint)
    @base = BaseDiv.new(self)
  end

  def do_GET(context)
    update_div(context)
    case context.req_path_info
    when '/image'
      context.res_header('content-type', 'image/jpeg')
      context.res_body(@base.amida_div.to_image)
    else
      context.res_header('content-type', 'text/html; charset=euc-jp')
      context.res_body(@base.to_html(context))
    end
  end
end

if __FILE__ == $0
  require 'drb/drb'
  require 'tofu/proxy'
  
  tofu = Tofu::Bartender.new(DipTofuSession)
  DRb.start_service('druby://localhost:7642', tofu)
  DRb.thread.join
end
