require 'drb/drb'
require 'div'
require 'singleton'
require 'cgi'

class RWikiDiv < Div::Div
  include Singleton

  RWIKI_URI = 'druby://localhost:8470'

  def initialize
    @session = nil
    @div_class = type.to_s
    @div_id = self.id.to_s
    @action = nil
    @rwiki = DRbObject.new(nil, RWIKI_URI)
    @cache = {}
    @ref_proc = Proc.new {|cmd, name| escape(name)}
  end

  def to_html(context)
    name = path2name(context) || :top
    fetch(name)
  end

  def modified(context)
    name = path2name(context) || :top
    page = update(name)
    page[:modified]
  end

  def escape(name)
    CGI.escape(name).gsub(/\%/, "@") + '.html'
  end

  def unescape(enc)
    CGI.unescape(enc.sub(/\.html$/, '').gsub(/\@/, "%"))
  end

  def path2name(context)
    path = context.req_path_info
    if /\/(.+)$/ =~ path #/
      unescape($1)
    else
      nil
    end
  end

  def today(n = 1)
    body = ""
    now = Time.now
    n.times do |i|
      name = (now-(i * 24 * 60 * 60)).strftime("%Y-%m-%d")
      today_body = fetch(name)
      if today_body.size > 0
	body << today_body
	body << "<p align='right'><small>(#{name})</small></p>"
      end
    end
    return "<p>No News is Good News.</p>" if body.to_s == ""
    body
  end

  def update(name)
    modified = nil
    v = @cache[name] 
    return v if v && v[:expires] > Time.now
    case name
    when String
      begin
	page = @rwiki.page(name)
	body = page.body_html({'ref_name'=>@ref_proc}) 
	modified = page.modified
	expires = Time.now + 300
      rescue
	body = "RWiki-div: " + h($!)
	expires = Time.now + 300
      end
    when :top
      body = fetch('Top') + "\n" + today(7)
      expires = Time.now + 600
    end
    @cache[name] = {:body => body, :expires => expires, :modified => modified}
  end
  
  def fetch(name)
    page = update(name)
    page[:body]
  end
end
