# Web::Controller::PolyState
# Copyright(c) 2002 MoonWolf <moonwolf@moonwolf.com>
require "web/escape"
require "web/response"

module Web
  module Controller
    class PolyState
      def initialize
      end
      
      def setup(opt={})
      end
      
      def teardown
      end
      
      def run_mode(req)
        rm = req.get('rm') || 'start'
      end
      
      def run(req)
        begin
          rsp = Web::Response.new
          rm = 'do_' + run_mode(req)
          send(rm, req, rsp)
          rsp
        rescue StandardError,ScriptError
          error($!.message + "\n" + $!.backtrace.join("\n"))
        end
      end
      
      def error(msg)
        rsp = Web::Response.new
        
        msg = h(msg).gsub(/\n/,"<br>")
        rsp.content_type = "text/html"
        rsp.write <<EOS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>ERROR #{self.type}</title>
<link rel="INDEX"  href="./">
</head>
<body>
  <h1>ERROR #{self.type}</h1>
  <pre>#{msg}</pre>
</body>
</html>
EOS
        rsp
      end
      
      def h(str)
        Web::escapeHTML(str)
      end
      
      def u(str)
        Web::escape(str.to_s)
      end

      def qs(hash)
        url = '?'
        url << hash.collect {|key,value|
          u(key.to_s) << '=' << u(value.to_s)
        }.sort.join(';')
        h(url)
      end

      def get_param(req, name, type, must = true)
        raise ArgumentError if must && !req.has_key?(name)
        value = req[name]
        return nil if !value and !must
        value = value.read if value.respond_to?(:read)
        case type
        when :text
          value
        when :flag
          case value.trim.downcase
          when /\A(?:on|yes|y|true|1)\z/
            true
          when /\A(?:off|no|n|false|0)\z/
            false
          else
            raise ArgumentError
          end
        when :integer
          Integer(value)
        when Array
          raise ArgumentError unless type.include?(value)
          value
        when Hash
          type[value]
        when Regexp
          m = type.match(value)
          raise ArgumentError unless value
          m
        end
      end
      
    end # PolyState
  end # Controller
end # Web
