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

$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
require "qwik/act-monitor"

module Qwik
  class Action
    def act_new
      c_require_login

      title = @req.query["t"]

      if title.nil? || title.empty? # title specified?
	return newpage_page_simple
      end

      # Check if the title is already exist.
      page = @site.get_by_title(title)
      if page
	return newpage_already_exist(title, page.key)
      end

      if !@req.is_post? # Request is GET
	return newpage_confirm(title)
      end

      key = title
      if ! newpage_valid_as_pagekey?(title)
	key = @site.get_new_id
      end

      begin
	page = @site.create(key) # CREATE
      rescue PageExistError
	# FIXME: should retry?
	return newpage_already_exist(title, key)
      end

      c_make_log("create", key) # CREATE
      c_monitor("create" + key) # CREATE

      page.store("* #{title}\n")

      url = key+".edit"
      return c_notice(_("New page"), url, 201){ # 201, Created
	[:p, _("Created."), [:br],
	  [:a, {:href=>url}, _("Edit new page")]]
      }
    end

    def newpage_valid_as_pagekey?(t)
      /\A[_A-Za-z0-9]+\z/ =~ t
    end

    def newpage_page_simple
      ar = []
      form = newpage_form
      return newpage_tail(ar, form)
    end

    def newpage_confirm(title)
      ar = []
      ar << [:h2, _("Confirm")]
      form = newpage_form(title) {
	[:p, _("Push create.")]
      }
      return newpage_tail(ar, form)
    end

    def newpage_already_exist(title, key)
      ar = []
      ar << [:h2, _("Already exist")]
      form = newpage_form(title) {
	[:p, [:a, {:href=>key+".html"}, [:strong, title]],
	  _(" is already exist."), [:br],
	  _("Please specify another title.")]
      }
      return newpage_tail(ar, form)
    end

    def newpage_form(title=nil)
      form = [:form, {:action=>".new", :method=>"post"},
	[:dl, [:dt, _("Title")],
	  [:dd, [:input, {:name=>"t", :value=>title, :class=>"focus"}]]]]
      form << yield if block_given?
      form << [:p, [:input, {:type=>"submit", :value=>_("New page")}]]
    end

    def newpage_tail(ar, form)
      ar << [:div, {:class=>"form"}, form]
      ar << [:hr]
      ar << [:p, _("Go back"), " : ",
	[:a, {:href=>"FrontPage.html"}, "FrontPage.html"]]
      return c_notice(_("New page")){ar}
    end

  end
end

if $0 == __FILE__
  require "t/test"
  $debug = true
end

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

    def test_create_newpage
      t_add_user

      # See NewPage page
      session("/test/.new")
      assert_attr({"action"=>".new", "method"=>"post"}, "form")
      assert_attr({"name"=>"t"}, "input")
      assert_attr({"type"=>"submit", "value"=>"New page"}, "input[2]")

      # Create a new page.
      #session("POST /test/FirstPage.new")
      session("POST /test/.new?t=FirstPage")
      assert_text("New page", "title")
      assert_in(["Edit new page"], "//div[@class='section']//a")
      assert_rattr({"href"=>"FirstPage.edit"}, "//div[@class='section']//a")
    end

    def test_opensite_newpage
      t_add_user
      t_site_open # OPEN site

      session("/test/") {|req|
	req.cookies.clear
      }
      assert_text("FrontPage", "title") # you can see the page.
      assert_in(["Login"], "//div[@class='adminmenu']//a") # not logged in.

      # try to see the NewPage page
      session("/test/.new") {|req|
	req.cookies.clear
      }
      assert_text("Please login.", "title") # You can't see the form.
      assert_text("You need login to use this function.", "p")
    end

    def test_embeded_newpage
      t_add_user
      page = @site["FrontPage"]
      page.store("[[FirstPage]]")

      # See FrontPage
      session("/test/")
      assert_text("FrontPage", "title")
      assert_xml([[:span, {:class=>"new"}, "FirstPage"],
		   [:a, {:class=>"new", :href=>".new?t=FirstPage"},
		     [:img, {:src=>"/.theme/i/new.png",
			 :class=>"new", :alt=>"create"}]]],
		 "//div[@class='section']/p")
      assert_xpath([:span, {:class=>"new"}, "FirstPage"],
		   "//span[@class='new']")

      # To confirm
      session("/test/.new?t=FirstPage")
      assert_text("New page", "title")
      assert_text("New page", "h1")
      assert_text("Confirm", "h2")
      assert_attr({"action"=>".new", "method"=>"post"}, "form")
      assert_attr({"name"=>"t", "value"=>"FirstPage"}, "input")
      assert_attr({"type"=>"submit", "value"=>"New page"}, "input[2]")

      # Create a new page.
      session("POST /test/.new?t=FirstPage")
      assert_xml("Edit new page", "//div[@class='section']//a")
      assert_rattr({"href"=>"FirstPage.edit"}, "//div[@class='section']//a")

      # Check the new page
      assert_equal("* FirstPage\n", @site["FirstPage"].load)

      # Try to create with the same key.
      session("/test/.new?t=FirstPage")
      assert_in(["Already exist"], "//h2")
      assert_xpath([:a, {:href=>"FirstPage.html"}, [:strong, "FirstPage"]],
		   "//div[@class='section']/a")

      # Try to create with the same key.
      session("POST /test/.new?t=FirstPage")
      assert_in(["Already exist"], "//h2")
      assert_xpath([:a, {:href=>"FirstPage.html"}, [:strong, "FirstPage"]],
		   "//div[@class='section']/a")
    end

    def test_embeded_newpage_with_space
      t_add_user
      page = @site["FrontPage"]
      page.store("[[First Page]]")
      assert_equal("FrontPage", page.get_title)

      # see a page
      session("/test/")
      assert_in(["First Page"], "//span[@class='new']")
      #pw("//div[@class='section']")
      assert_xpath([:a, {:href=>".new?t=First+Page",
		       :class=>"new"}, [:img, {:src=>"/.theme/i/new.png",
			 :alt=>"create", :class=>"new"}]],
		   "//div[@class='section']/a")

      # Please input corresponding page key
      session("/test/.new?t=First+Page")
      assert_text("New page", "h1")
      assert_text("Confirm", "h2")
      assert_attr({"action"=>".new", "method"=>"post"}, "form")
      assert_attr({"name"=>"t", "value"=>"First Page"}, "input")
      assert_attr({"type"=>"submit", "value"=>"New page"}, "input[2]")

      # POST
      session("POST /test/.new?t=First Page")
      assert_text("New page", "h1")
      assert_xml("Edit new page", "//div[@class='section']//a")
      assert_rattr({"href"=>"1.edit"}, "//div[@class='section']//a")

      # check the new page
      assert_equal("* First Page\n", @site["1"].load)
      page = @site.get_by_title("First Page")
      assert_equal("1", page.key)

      # check title
      page = @site["1"]
      assert_equal("First Page", page.get_title)
      assert_equal("1", @site.get_by_title("First Page").key.to_s)
      assert_equal(false, @site.exist?("First Page"))
      assert_equal(true, @site.exist?("1"))

      # check the source page
      session("/test/")
      assert_xml("First Page", "//div[@class='section']//a")
      assert_rattr({"href"=>"1.html"}, "//div[@class='section']//a")
      assert_equal("[[First Page]]", @site["FrontPage"].load)

      # Try to create with the same key.
      session("/test/.new?t=First+Page")
      assert_in(["Already exist"], "//h2")
      assert_xpath([:a, {:href=>"1.html"}, [:strong, "First Page"]],
		   "//div[@class='section']/a")

      # Try to create with the same key.
      session("POST /test/.new?t=First+Page")
      assert_in(["Already exist"], "//h2")
      assert_xpath([:a, {:href=>"1.html"}, [:strong, "First Page"]],
		   "//div[@class='section']/a")

      # Let's create a page again.  At the first, embed the title.
      page = @site["FrontPage"]
      page.store("[[2nd Page]]")

      # See the page
      session("/test/")
      assert_xml("2nd Page", "//div[@class='section']//span")
      assert_rattr({"href"=>".new?t=2nd+Page", "class"=>"new"},
		   "//div[@class='section']//a")

      # please input a corresponding page key
      session("/test/.new?t=2nd+Page")
      assert_attr({"name"=>"t", "value"=>"2nd Page"}, "input")

      # try again
      session("POST /test/.new?t=2nd+Page")
      assert_xml("Edit new page", "//div[@class='section']//a")
      assert_rattr({"href"=>"2.edit"}, "//div[@class='section']//a")

      page = @site["2"]
      assert_equal("* 2nd Page\n", page.load)

      # check the source page again
      session("/test/")
      assert_xml("2nd Page", "//div[@class='section']//a")
      assert_rattr({"href"=>"2.html"}, "//div[@class='section']//a")
      assert_equal("[[2nd Page]]", @site["FrontPage"].load)
    end

  end
end
