#
# 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
import mllib.dom
try:
  from cStringIO import StringIO
except ImportError:
  from io 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 = mllib.dom.Tag(tag.name, *tag.attrs)
    result.extend(self.descend(tag))
    return result

  def tree(self, tree):
    result = mllib.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
