#!/usr/bin/env python
#
# Time-stamp: <01/03/18 11:33:10 dhellmann>
#
# COPYRIGHT
#
#   Permission to use, copy, modify, and distribute this software and
#   its documentation for any purpose and without fee is hereby
#   granted, provided that the above copyright notice appear in all
#   copies and that both that copyright notice and this permission
#   notice appear in supporting documentation, and that the name of Doug
#   Hellmann not be used in advertising or publicity pertaining to
#   distribution of the software without specific, written prior
#   permission.
# 
# DISCLAIMER
#
#   DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
#   INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
#   NO EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
#   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
#   OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
#   NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
#   CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# 


"""A base class for file-based formatters for HappyDoc.

"""

__rcs_info__ = {
    #
    #  Creation Information
    #
    'module_name':'$RCSfile: hdformatter_file.py,v $',
    'creator':'Doug Hellmann <doughellmann@bigfoot.com>',
    'project':'HappyDoc',
    'created':'Sat, 03-Jun-2000 17:56:22 EDT',
    #
    #  Current Information
    #
    'author':'$Author: doughellmann $',
    'version':'$Revision: 1.9 $',
    'date':'$Date: 2001/03/18 18:22:16 $',
    }

#
# Import system modules
#
import os
import string
import types

#
# Import Local modules
#
import happyformatter
import hdpath

#
# Module
#

    
class FileBasedFormatter(happyformatter.HappyFormatterBase):
    """A base class for file-based formatters for HappyDoc.
    """

    def __init__(self, docSet, filenamePrefix='', **extraNamedParameters):
        """Initialize a FileBasedFormatter.

        Parameters

          docSet -- The documentation set controlling the formatter.
          
          filenamePrefix -- A prefix to append to the base names of
          files and directories being created.  This is useful for
          situations where the names which would be automatically
          generated might cause a name clash or conflict.

          extraNamedParameters -- Parameters specified by name which
          were not supported by a subclass initialization.
          
        """
        #
        # Store parameters
        #
        self._filename_prefix = filenamePrefix
        #
        # Initialize the base class
        #
        apply(happyformatter.HappyFormatterBase.__init__,
              (self, docSet,),
              extraNamedParameters)
        return

    def openOutput(self, name, title1, title2=None):
        "Open the named output destination and give the title."
        hdpath.rmkdir(hdpath.dirname(name))
        f = open(name, 'wt')
        if not hasattr(self, 'open_root_file'):
            self.open_root_file = f
        return f

    def closeOutput(self, output):
        "Close the output handle."
        output.close()
        return

    def fixUpOutputFilename(self, filename, usePrefix=1):
        """Tweak the filename to remove relative references and add the safe prefix."""
        #
        # Remove preceding slashes to make name relative
        #
        filename = hdpath.removeRelativePrefix(filename)
        #
        # Apply the path prefix, if required
        #
        if usePrefix:
            filename = hdpath.applyPrefixToPath(filename, self._filename_prefix)
        return filename
    
    def getOutputNameForFile(self, filename, usePrefix=0):
        """
        Return the base name of the thing to which output should be
        written for a file.  This is usually a file name, but could be
        anything understood by the formatter as a name.  If infoObject
        is None, return the name for a root node for this formatter.
        """
        filename = self.fixUpOutputFilename(filename, usePrefix)
        #
        # Set the correct extension for the output file
        #
        extension = self.getFilenameExtension()
        #
        # Build the name
        #
        basename, ext = hdpath.splitext(filename)
        if ext == '.py':
            name = '%s.%s' % (filename, extension)
        else:
            name = '%s.%s' % (filename, extension)
        return name
    
    def getOutputNameForObject(self, infoObject):
        """
        Return the base name of the thing to which output should be written
        for an info source.  This is usually a file name, but could
        be anything understood by the formatter as a name.  If
        infoObject is None, return the name for a root node for this
        formatter.
        """
        #print 'ZZZ getOutputNameForObject(%s)' % infoObject
        if type(infoObject) == types.StringType:
            #print 'ZZZ string'
            name = infoObject
        elif type(infoObject) == types.FileType:
            #print 'ZZZ file'
            name = infoObject.name
        elif infoObject is not None:
            #print 'ZZZ infoObject'
            name = self.getOutputNameForFile(
                infoObject.getFullyQualifiedName(self._filename_prefix)
                )
            #print '\n\nFILE for %s \nis %s\n\n' % (infoObject.getName(),
            #                                       name)
        else:
            name = self.getRootNodeName()
        #print 'ZZZ =>%s' % name
        return name


    def getLocalOutputNameForObject(self, infoObject):
        """
        Return a local reference to base name of the thing to which
        output should be written for an info source.  This is usually
        a file name, but could be anything understood by the formatter
        as a name.  If infoObject is None, return the name for a root
        node for this formatter.
        """
        extension = self.getFilenameExtension()
        if infoObject is not None:
            name = '%s.%s' % ( infoObject.getQualifiedName(self._filename_prefix),
                               extension )
        else:
            name = self.getRootNodeName()
        return name


    def getFullOutputNameForObject(self, infoObject):
        "Get the full name, including path, to the object being output."
        obj_output_name = self.getOutputNameForObject(infoObject)
        if (not infoObject) and self._docset.getDocsetBaseDirectory():
            #
            # Root node for docset
            #
            name = hdpath.join( self._docset.getDocsetBaseDirectory(),
                                obj_output_name
                                )
            
        elif self._docset.getDocsetBaseDirectory():
            #
            # Subnode of docset
            #
            docset_base = self._docset.getDocsetBaseDirectory()
            output_base = self._docset.getOutputBaseDirectory()
            file_name = self.getOutputNameForObject(infoObject)
            name = hdpath.joinWithCommonMiddle( output_base, docset_base, file_name )
            
        else:
            #
            # How can we get here?
            #
            name = self.getOutputNameForObject(infoObject)

        return name

    def getFullOutputNameForFile(self, filename, usePrefix=0):
        "Get the full name, including path, to the filename to convert."
        if self._docset.getOutputBaseDirectory():
            name = hdpath.join( self._docset.getOutputBaseDirectory(),
                                self.getOutputNameForFile(filename, usePrefix)
                                )
        else:
            name = self.getOutputNameForFile(filename)
        return name

    def getRootNodeName(self):
        "Return the name of the root node for the documentation tree."
        self._requiredOfSubclass('getRootNodeName')
        return
