#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

"""
Useful transforms for dom objects.
"""
from __future__ import absolute_import

from . import dom
try:
    from io import StringIO
except ImportError:
    from cStringIO import StringIO

class Visitor:

  def descend(self, node):
    for child in node.children:
      child.dispatch(self)

  def node(self, node):
    self.descend(node)

  def leaf(self, leaf):
    pass

class Identity:

  def descend(self, node):
    result = []
    for child in node.children:
      result.append(child.dispatch(self))
    return result

  def default(self, tag):
    result = dom.Tag(tag.name, *tag.attrs)
    result.extend(self.descend(tag))
    return result

  def tree(self, tree):
    result = dom.Tree()
    result.extend(self.descend(tree))
    return result

  def tag(self, tag):
    return self.default(tag)

  def leaf(self, leaf):
    return leaf.__class__(leaf.data)

class Sexp(Identity):

  def __init__(self):
    self.stack = []
    self.level = 0
    self.out = ""

  def open(self, s):
    self.out += "(%s" % s
    self.level += len(s) + 1
    self.stack.append(s)

  def line(self, s = ""):
    self.out = self.out.rstrip()
    self.out += "\n" + " "*self.level + s

  def close(self):
    s = self.stack.pop()
    self.level -= len(s) + 1
    self.out = self.out.rstrip()
    self.out += ")"

  def tree(self, tree):
    self.open("+ ")
    for child in tree.children:
      self.line(); child.dispatch(self)
    self.close()

  def tag(self, tag):
    self.open("Node(%s) " % tag.name)
    for child in tag.children:
      self.line(); child.dispatch(self)
    self.close()

  def leaf(self, leaf):
    self.line("%s(%s)" % (leaf.__class__.__name__, leaf.data))

class Output:

  def descend(self, node):
    out = StringIO()
    for child in node.children:
      out.write(child.dispatch(self))
    return out.getvalue()

  def default(self, tag):
    out = StringIO()
    out.write("<%s" % tag.name)
    for k, v in tag.attrs:
      out.write(' %s="%s"' % (k, v))
    out.write(">")
    out.write(self.descend(tag))
    if not tag.singleton:
      out.write("</%s>" % tag.name)
    return out.getvalue()

  def tree(self, tree):
    return self.descend(tree)

  def tag(self, tag):
    return self.default(tag)

  def data(self, leaf):
    return leaf.data

  def entity(self, leaf):
    return "&%s;" % leaf.data

  def character(self, leaf):
    raise Exception("TODO")

  def comment(self, leaf):
    return "<!-- %s -->" % leaf.data

class Empty(Output):

  def tag(self, tag):
    return self.descend(tag)

  def data(self, leaf):
    return ""

  def entity(self, leaf):
    return ""

  def character(self, leaf):
    return ""

  def comment(self, leaf):
    return ""

class Text(Empty):

  def data(self, leaf):
    return leaf.data

  def entity(self, leaf):
    return "&%s;" % leaf.data

  def character(self, leaf):
    # XXX: is this right?
    return "&#%s;" % leaf.data
