# $Id: resolve.rb,v 1.7 2004/04/22 14:47:49 eto Exp $
# Copyright (C) 2003-2004 Kouichirou Eto, All rights reserved.
# This is free software with ABSOLUTELY NO WARRANTY.
# You can redistribute it and/or modify it under the terms of the GNU GPL2.

require 'qwik/site'
require 'qwik/qxml'
require 'qwik/wikitext'
require 'qwik/extension'

module Qwik
  class Resolver
    def initialize(xml, site=nil)
      @xml = xml
      @site = site
      @g = Qxml.new
    end
    attr_reader :xml

    def resolve
      resolve_h
      resolve_plugin
      resolve_ref
      resolve_interwiki
      resolve_empty
      @xml
    end

    private

    def resolve_h
      @xml.tag('h2', 'h3', 'h4', 'h5', 'h6'){|e|
	e.get_text.delete_spaces
      }
      #resolve_suf
    end

    def resolve_ref
      return unless @site
      @xml.tag('a'){|e|
	href = e.attributes['href']
	text = e.text
	next if href =~ /^http:\/\// # ignore external link
	next if href =~ /\?/ # ignore command link
	next unless href =~ /\.html$/ # ignore not html file

	pagename = href.sub(/\.html$/, '')
	if @site.pages.exist?(pagename)
	  if pagename == text
	    e.text = @site[pagename].get_title
	  end
	  next
	end

	title = pagename.unescape
	page = @site.pages.find_title(title)
	if page
	  e.add_attribute('href', page.key+".html")
	  next
	end

	newpagename = pagename.unescape.u8tosjis.escape # make it to sjis
	edithref = "_new.html?t=#{newpagename}"
	edithref += ";f=#{@site.plugin.pagename}" if @site.plugin
	e.previous_sibling = @g.span(:class=>'new'){text}
	e.text = "?"
	e.add_attribute('class', 'new')
	e.add_attribute('href', edithref)
      }
    end

    def resolve_interwiki
      return unless @site
      interwiki = InterWiki.new(@site)
      @xml.tag('interwiki'){|e|
	wiki = e.attributes['wiki']
	page = e.attributes['page']
	href = interwiki.href(wiki, page)
	e.delete_attribute('page')
	e.delete_attribute('wiki')
	e.add_attribute('class', 'interwiki')
	if href
	  e.name = 'a'
	  e.add_attribute('href', href)
	else
	  e.name = 'span' # ignore it
	end
      }
    end

    def resolve_plugin
      return unless @site
      return unless @site.plugin
      @xml.tag('plugin'){|e|
	method = e.attributes['method']
	param  = e.attributes['param']
	data   = e.text
	res = @site.plugin.call_plugin_method(method, param, data)
	res.each {|r|
	  next if r.nil?
	  if r.is_a? REXML::Element
	    e.parent.insert_after(e, r)
	  elsif r.is_a? String
	    e.parent.insert_after(e, REXML::Text.new(r))
	  else
	    p 'unknown!'
	  end
	}
	e.parent.delete(e)
      }
    end

    def resolve_empty
      @xml.delete_empty_tag('em', 'strong')
    end
  end

  class TDiaryResolver < Resolver
    def resolve
      super
      resolve_tdiary_theme
      @xml
    end

    private

    def resolve_tdiary_theme
      section = []
      title   = nil
      doc = REXML::Document.new
      doc << REXML::Element.new('body')
      @xml.root.elements.each {|e|
	if e.is_a?(REXML::Element) && e.name == 'h2'
	  if 0 < section.size
	    doc.root << tdiary_section(title, section)
	    section = []
	  end
	  title = e
	else
	  section << e
	end
      }
      doc.root << tdiary_section(title, section)
      @xml = doc
    end

    def tdiary_section(title, section)
      @g.div(:class=>'day'){
	[title,
	  @g.div(:class=>'body'){
	    @g.div(:class=>'section'){
	      section
	    }
	  }]
      }
    end
  end
end
