##
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
import os
from xml.dom.minidom import getDOMImplementation

class ExportXML:
    """
        Exports the disk into XML file. Although the DTD is not necessary nor for creating nor for XSL transformation, I add it here:
        for the flat export:
        <!ELEMENT root folder* >
        <!ELEMENT folder file* >
        <!ELEMENT file EMPTY >
        <!ATTLIST root  name CDATA #REQUIRED
                        type CDATA #REQUIRED
                        comment CDATA #REQUIRED
                        id  ID #IMPLIED   >
        <!ATTLIST folder  path CDATA #REQUIRED
                        id  ID #IMPLIED   >
        <!ATTLIST file  path CDATA #REQUIRED
                        id  ID #IMPLIED   >
        for the tree export:
        <!ELEMENT root folder >
        <!ELEMENT folder (folder | file) * >
        <!ELEMENT file EMPTY >
        <!ATTLIST root  name CDATA #REQUIRED
                        type CDATA #REQUIRED
                        comment CDATA #REQUIRED
                        id  ID #IMPLIED   >
        <!ATTLIST folder  path CDATA #REQUIRED
                        id  ID #IMPLIED   >
        <!ATTLIST file  path CDATA #REQUIRED
                        id  ID #IMPLIED   >
    """
    def __init__(self):
        self.id = 0
        self.formats = {'flat': 'Flat',  'tree': 'Tree'}

    def getUniqueId(self):
        self.id += 1
        return str(self.id)

    def getDomByPath(self, dom, newdoc, path):
        if path == '/':
            dirNames = ["/"]
        else:
            dirNames = ["/"]  + path[1:].split("/")
        current = dom
        for dir in dirNames:
            children =current.getElementsByTagName('folder')
            found = False
            for child in children:
                if child.getAttribute('path') == dir:
                    current = child
                    found = True
                    break
            if not found:
                newDir = newdoc.createElement('folder')
                newDir.setAttribute('id', self.getUniqueId())
                newDir.setAttribute('path', dir)
                current = current.appendChild(newDir)

        return current

    def procesDir(self, newdoc, dir, directory):
        for ff in directory[1]:
            fileobject = newdoc.createElement('file')
            fileobject.setAttribute("path", ff[0])
            fileobject.setAttribute("size", str(ff[1]))
            fileobject.setAttribute('id', self.getUniqueId())
            dir.appendChild(fileobject)

    def printXML(self, disk, filename, format):
        impl = getDOMImplementation()
        newdoc = impl.createDocument(None, "root", None)
        #This is  ugly hack, don't try it at home. From some reason Firefox on windows wants file:// while Opera generally hates it
        #It seems that with double processing instruction it work in IE, Firefox and Opera (both on Windows and Linux)
        comment = newdoc.createComment(" This is  ugly hack, don't try it at home. ")
        pi = newdoc.createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="%s"' % os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resource', 'print.xsl')))
        pi2 = newdoc.createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="file://%s"' % os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resource', 'print.xsl')))
        newdoc.insertBefore(comment, newdoc.documentElement)
        newdoc.insertBefore(pi, newdoc.documentElement)
        newdoc.insertBefore(pi2, newdoc.documentElement)
        top_element = newdoc.documentElement
        top_element.setAttribute('name', disk.name)
        top_element.setAttribute('type', disk.type)
        top_element.setAttribute('comment', disk.remark)
        top_element.setAttribute('id', self.getUniqueId())

        if  format == 'flat':
            for directory in disk.content:
                dir = newdoc.createElement('folder')
                dir.setAttribute('path', directory[0])
                dir.setAttribute('id', self.getUniqueId())
                self.procesDir(newdoc, dir, directory)
                top_element.appendChild(dir)
        elif  format == 'tree':
            flatdirs = disk.content[:]  #make copy
            flatdirs.sort() #now the shorter paths are always before the longer paths
            for directory in flatdirs:
                dir = self.getDomByPath(top_element, newdoc, directory[0])
                head, tail = os.path.split(directory[0])
                self.procesDir(newdoc, dir, directory)

        fh = file(filename, 'w')
        fh.write(newdoc.toprettyxml())
        fh.close()
