class Temple::HTML::Fast

@api public

def attribute(name, value)

def attribute(name, value)
  [:multi,
   [:static, " #{name}=#{options[:attr_wrapper]}"],
   compile(value),
   [:static, options[:attr_wrapper]]]
end

def contains_static?(exp)

def contains_static?(exp)
  case exp[0]
  when :multi
    exp[1..-1].any? {|e| contains_static?(e) }
  when :escape
    contains_static?(exp[2])
  when :static
    true
  else
    false
  end
end

def html?

def html?
  options[:format] == :html5 || options[:format] == :html4
end

def initialize(opts = {})

def initialize(opts = {})
  super
  # html5 is now called html only
  options[:format] = :html5 if options[:format] == :html
  unless [:xhtml, :html4, :html5].include?(options[:format])
    raise "Invalid format #{options[:format].inspect}"
  end
end

def on_html_attr(name, value)

def on_html_attr(name, value)
  if empty_exp?(value)
    compile(value)
  elsif contains_static?(value)
    attribute(name, value)
  else
    tmp = unique_name
    [:multi,
     [:capture, tmp, compile(value)],
     [:if, "!#{tmp}.empty?",
      attribute(name, [:dynamic, tmp])]]
  end
end

def on_html_attrs(*attrs)

def on_html_attrs(*attrs)
  result = {}
  attrs.each do |attr|
    raise(InvalidExpression, 'Attribute is not a html attr') if attr[0] != :html || attr[1] != :attr
    name, value = attr[2].to_s, attr[3]
    next if empty_exp?(value)
    if result[name]
      delimiter = options[:attr_delimiter][name]
      raise "Multiple #{name} attributes specified" unless delimiter
      if contains_static?(value)
        result[name] = [:html, :attr, name,
                        [:multi,
                         result[name][3],
                         [:static, delimiter],
                         value]]
      else
        tmp = unique_name
        result[name] = [:html, :attr, name,
                        [:multi,
                         result[name][3],
                         [:capture, tmp, value],
                         [:if, "!#{tmp}.empty?",
                          [:multi,
                           [:static, delimiter],
                           [:dynamic, tmp]]]]]
      end
    else
      result[name] = attr
    end
  end
  [:multi, *result.sort.map {|name,attr| compile(attr) }]
end

def on_html_comment(content)

def on_html_comment(content)
  [:multi,
    [:static, '<!--'],
    compile(content),
    [:static, '-->']]
end

def on_html_doctype(type)

def on_html_doctype(type)
  type = type.to_s
  trailing_newlines = type[/(\A|[^\r])(\n+)\Z/, 2].to_s
  text = type.downcase.strip
  if text =~ /^xml/
    raise 'Invalid xml directive in html mode' if html?
    wrapper = options[:attr_wrapper]
    str = "<?xml version=#{wrapper}1.0#{wrapper} encoding=#{wrapper}#{text.split(' ')[1] || "utf-8"}#{wrapper} ?>"
  else
    case options[:format]
    when :html5
      str = '<!DOCTYPE html>'
    when :html4
      str = HTML4_DOCTYPES[text] || HTML4_DOCTYPES['transitional']
    when :xhtml
      str = XHTML_DOCTYPES[text] || XHTML_DOCTYPES['transitional']
    end
  end
  str << trailing_newlines
  [:static, str]
end

def on_html_tag(name, attrs, content = nil)

def on_html_tag(name, attrs, content = nil)
  name = name.to_s
  closed = !content || (empty_exp?(content) && options[:autoclose].include?(name))
  result = [:multi, [:static, "<#{name}"], compile(attrs)]
  result << [:static, (closed && xhtml? ? ' /' : '') + '>']
  result << compile(content) if content
  result << [:static, "</#{name}>"] if !closed
  result
end

def xhtml?

def xhtml?
  options[:format] == :xhtml
end