# Copyright (C) 2003-2005 Kouichirou Eto, All rights reserved.

module Qwik
  class Action
    def plg_show_presen
      return "" if !defined?(@req.base) || @req.base.nil?
      [:span, {:class=>"attribute"},
	[:a, {:href=>@req.base+".presen"}, _("Presentation mode")]]
    end

    def ext_presen
      c_require_pagename
      c_require_page_exist
      c_require_no_path_args
      c_require_no_ext_args

      gen = PresenPageGenerator.new(@config, self)
      @res.body = gen.generate_html(@site, @req.base)
      c_set_html
      c_set_no_cache
    end
  end

  class PresenPageGenerator
    def initialize(config, action)
      @config = config
      @action = action
      @page = nil
    end

    def generate_html(site, pagename)
      page = site[pagename]
      title = page.get_title

      wabisabi = @action.c_get(pagename)
      wabisabi = resolve_h(wabisabi)
      wabisabi = resolve_slide(wabisabi)

      theme = "i18n"
      #theme = "qwikblack"
      #theme = "qwikborder"
      html_page(title, theme, wabisabi)
    end

    REPLACE_H = {:h2=>:h1, :h3=>:h2, :h4=>:h3, :h5=>:h4, :h6=>:h5}
    def resolve_h(wabisabi)
      wabisabi.each_tag(:h2, :h3, :h4, :h5, :h6){|w|
	w[0] = REPLACE_H[w[0]]
	w
      }
    end

    def is_title?(e)
      e.is_a?(Array) && e[0] == :h1
    end

    def resolve_slide(wabisabi)
      presentation = []
      slide = []
      presentation << slide
      wabisabi.each {|e|
	if is_title?(e) && 0 < slide.size
	  slide = []
	  presentation << slide
	end
	slide << e
      }

      return presentation.map {|slide|
	div_slide(slide)
      }
    end

    def div_slide(slide)
      [:div, {:class=>"slide"}, slide]
    end

    private

    def html_css(href, media, id)
      [:link, {:rel=>"stylesheet", :href=>href,
	  :type=>"text/css", :media=>media, :id=>id}]
    end

    def html_style(style)
      [:style, {:type=>"text/css", :media=>"all"}, style]
    end

    def html_script(src)
      [:script, {:src=>src, :type=>"text/javascript"}, ""]
    end

    def html_head(title, theme)
      [:head,
	[:title, title],
	[:meta, {:name=>"defaultView", :content=>"slideshow"}],
	[:meta, {:name=>"controlVis", :content=>"hidden"}],
	html_css(".theme/s5/#{theme}/slides.css", "projection", "slideProj"),
	html_css(".theme/s5/default/outline.css", "screen", "outlineStyle"),
	html_css(".theme/s5/default/print.css", "print", "slidePrint"),
	html_css(".theme/s5/default/opera.css", "projection", "operaFix"),
	html_style(""),
	html_script(".theme/s5/default/slides.js"),
      ]
    end

    def div_layout(title)
      [:div, {:class=>"layout"},
	[:div, {:id=>"controls"}, ""],
	[:div, {:id=>"currentSlide"}, ""],
	[:div, {:id=>"header"}, ""],
	[:div, {:id=>"footer"},
	  [:h1, title]]]
    end

    def div_presentation(w)
      [:div, {:class=>"presentation"}, w]
    end

    def html_page(title, theme, wabisabi)
      [
	[:"!DOCTYPE", "html", "PUBLIC",
	  "-//W3C//DTD HTML 4.01 Transitional//EN",
	  "http://www.w3.org/TR/html4/loose.dtd"],
	[:html,
	  {:"xmlns"=>"http://www.w3.org/1999/xhtml",
	    :"xmlns:v"=>"urn:schemas-microsoft-com:vml"},
	  html_head(title, theme),
	  [:body,
	    div_layout(title),
	    div_presentation(wabisabi)]]
      ]
    end

  end
end

if $0 == __FILE__
  $LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
  require "t/test"
  $debug = true
end

if $debug
  class TC_ActPresen < Test::Unit::TestCase
    include TestSession

    def test_all
      # test_plg_presen
      assert_wiki([:span, {:class=>"attribute"}, [:a, {:href=>"1.presen"},
		      "Presentation mode"]], "{{show_presen}}")

      # test_act_presen
      t_add_user

      session("/test/FrontPage.presen")
      assert_text("FrontPage", "title")
      assert_text("FrontPage", "h1")

      page = @site.create_new
      page.store("* ‚ ")
      session("/test/#{page.key}.presen")
      assert_text("‚ ", "title")
    end
  end

  class TC_PresenPageGenerator < Test::Unit::TestCase
    include TestSession

    def assert(expected, wabisabi)
      gen = Qwik::PresenPageGenerator.new(@config, @action)
      w = gen.resolve_h(wabisabi)
      assert_equal(expected, w)
    end

    def assert_slide(expected, wabisabi)
      gen = Qwik::PresenPageGenerator.new(@config, @action)
      w = gen.resolve_slide(wabisabi)
      assert_equal(expected, w)
    end

    def test_all
      # test_resolve_h
      session
      assert([[:h1, "h"]], [[:h2, "h"]])
      assert([[:h1, "h", "h2"]], [[:h2, "h", "h2"]])
      assert([[:h1, "h", [:b, "b"], "c"]], [[:h2, "h", [:b, "b"], "c"]])
      assert([[:h2, "h"]], [[:h3, "h"]])

      # test_resolve_slide
      gen = Qwik::PresenPageGenerator.new(@config, @action)
      assert_equal(true, gen.is_title?([:h1, "h"]))
      assert_equal(false, gen.is_title?([:h2, "h"]))
      assert_equal([:div, {:class=>"slide"}, [:h1, "h"]],
		   gen.div_slide([:h1, "h"]))
      assert_slide([[:div, {:class=>"slide"}, [[:h1, "h"]]]],
		   [[:h1, "h"]])
      assert_slide([[:div, {:class=>"slide"}, [[:h1, "h"], [:p, "p"]]]],
		   [[:h1, "h"], [:p, "p"]])
      assert_slide([[:div, {:class=>"slide"}, [[:h1, "h"], [:p, "p"]]],
		     [:div, {:class=>"slide"}, [[:h1, "h"], [:p, "p"]]]],
		   [[:h1, "h"], [:p, "p"], [:h1, "h"], [:p, "p"]])

      # test_get_html
      gen = Qwik::PresenPageGenerator.new(@config, @action)
      page = @site.create_new
      page.store("* h\np\n* h2\np2\n")
      w = gen.generate_html(@site, page.key)
      page = 
	[[:"!DOCTYPE",
	  "html", "PUBLIC", "-//W3C//DTD HTML 4.01 Transitional//EN",
	  "http://www.w3.org/TR/html4/loose.dtd"],
	[:html,
	  {:"xmlns:v"=>"urn:schemas-microsoft-com:vml",
	    :xmlns=>"http://www.w3.org/1999/xhtml"},
	  [:head,
	    [:title, "h"],
	    [:meta, {:content=>"slideshow", :name=>"defaultView"}],
	    [:meta, {:content=>"hidden", :name=>"controlVis"}],
	    [:link,
	      {:id=>"slideProj",
		:media=>"projection",
		:href=>".theme/s5/i18n/slides.css",
		:rel=>"stylesheet",
		:type=>"text/css"}],
	    [:link,
	      {:id=>"outlineStyle",
		:media=>"screen",
		:href=>".theme/s5/default/outline.css",
		:rel=>"stylesheet",
		:type=>"text/css"}],
	    [:link,
	      {:id=>"slidePrint",
		:media=>"print",
		:href=>".theme/s5/default/print.css",
		:rel=>"stylesheet",
		:type=>"text/css"}],
	    [:link,
	      {:id=>"operaFix",
		:media=>"projection",
		:href=>".theme/s5/default/opera.css",
		:rel=>"stylesheet",
		:type=>"text/css"}],
	    [:style, {:media=>"all", :type=>"text/css"}, ""],
	    [:script,
	      {:type=>"text/javascript", :src=>".theme/s5/default/slides.js"},
	      ""]],
	  [:body,
	    [:div,
	      {:class=>"layout"},
	      [:div, {:id=>"controls"}, ""],
	      [:div, {:id=>"currentSlide"}, ""],
	      [:div, {:id=>"header"}, ""],
	      [:div, {:id=>"footer"}, [:h1, "h"]]],
	    [:div,
	      {:class=>"presentation"},
	      [[:div, {:class=>"slide"}, [:h1, [:h1, "h"]], [[:p, "p"]]],
		[:div, {:class=>"slide"}, [:h1, [:h1, "h2"]], [[:p, "p2"]]]]]]]]

      #    assert_equal(page, w)
    end
  end
end
