# -*- coding: utf-8 -*-
#------------------------------------------------------------
#
#  Function definitions
#
#  $Id: functions.py,v 1.38 2005/09/21 20:18:31 pj Exp $
#------------------------------------------------------------
import exceptions
import glob, os, sys, getopt, traceback
import string,struct
import re
import dircache
import urllib
try:
    import xml.sax.saxutils
except:
    # we cannot parse xml, but still create galleries
    pass

props = None
pictypes = None

# constants
status_working = 0
status_finished = 1
status_error = 2
status_info = 3
status_finished_ok = 4

removeDotSlash = re.compile("^\.[\\/]")
    
def init(xprops):
    """provide functions a reference to the props dictionary.Must be given immediately after program start"""
    global pictypes
    props = xprops
    pictypes = props["pictypes"].split(";")


def trim(text):
    "Remove redundant whitespace from a string"
    return string.join(string.split(text), ' ')


def globFiles(dir):
    """Find all files of filetype defined in props["pictypes"] in 'dir'. Return sorted list with filenames or None"""
    global pictypes
    pictures = None

    for pictype in pictypes:
        regex = ".*%s" % pictype
        checkextension = re.compile(regex, re.IGNORECASE)
        for file in dircache.listdir(dir):
            if checkextension.search(file) and os.path.isfile(os.path.join(dir, file)):
                if not pictures:
                    pictures = []
                pictures.append(os.path.join(dir, removeDotSlash.sub("", file)))
    return pictures



def getDirs(dir):
    """Return sorted list of subdirectories in supplied dir.
    Supplied dir must be fully qualified"""
    result = None
    for file in dircache.listdir(dir):
        if os.path.isdir(os.path.join(dir,file)):
            if not result:
                result = []
            result.append(file)
    return result



def hasPic(dummy, dirname, filenames):
    """Callback for walk() which throws NE_FoundPic if a
       file of filetype props["pictypes"] is found.

       The exception is thrown to make walk() quit it's
       operation"""
    global pictypes

    for pictype in pictypes:
        regex = ".*%s" % pictype
        checkextension = re.compile(regex, re.IGNORECASE)
        for file in filenames:
            if checkextension.search(file):
                raise exceptions.NE_FoundPic("Found %s" % file)
    

def getSubdirsWithPics(dir):
    """Return list of dirs which has pics or subdirs with pics
       Resultlist is appended in callback method"""

    subdirs = getDirs(dir)
    resultlist = None
    if subdirs:
        for subdir in subdirs:
            try:
                os.path.walk(os.path.join(dir,subdir), hasPic, None)
            except exceptions.NE_FoundPic:
                    if resultlist is None:
                        resultlist = []
                    resultlist.append(subdir)
    return resultlist
    


def findYoungest(filelist):
    "Return max unix timestamp from list of files"
    result = 0
    try:
        for file in filelist:
            mtime = os.path.getmtime(file)
            if mtime > result:
                result = mtime
    except:
        pass
    return result


def copyFullSize(directory, file):
    "Copy fullsize pictures to directory"
    try:
        if os.path.exists(directory) == 0:
            os.mkdir(directory)
        outfile = os.path.join(directory, file)
        shutil.copyfile(file, outfile)
    except:
        printTraceback()
        sys.exit()


def createStylesheet(props):
    "Construct stylesheet unconditionally"
    try:
        directory =    props["galleryDirectory"]
        stylesheet =   props["stylesheet"]
        fgColor =      props["fgColor"]
        bgColor =      props["bgColor"]
        lnColor =      props["lnColor"]
        lnVisitColor = props["lnVisitColor"]
        hoverColor =   props["hoverColor"]
        
        html = []

        
        #html.append("\nH1 { color: " + fgColor + "}")
        html.append("""
        
BODY { background-color: """ + bgColor + """;
 color: """ + fgColor + """;
 font-family: verdana, helvetica, univers, sans-serif;  
}

H1 { font-size: x-large;
 font-weight: bold;
 text-align: center;
 margin: 2px 2px 2px 2px;
 padding: 0px 0px;
}

P { color: """ + fgColor + """;
 font-size: 10pt;
 font-weight: normal;
 text-align: left;
}
        
P.footer { color: """ + fgColor + """;
 font-size: 8pt ;
 font-style: italic;
 text-align: left;
 margin: 0px 10px 2px 5px;
 padding: 0px 5px 5px 5px;
}

IMG { border-style: solid;
      border-color: #D4D6D2;
      border-width: 2px;
}

td#sidelinks a:link {
 text-decoration: none;
 color: """ + lnColor + """;
 padding: 5px 1px 5px 20px;
 font-size: 12pt; font-weight: normal;                 
}

td#sidelinks a:hover {
 text-decoration: none;
 color: """ + hoverColor + """;
 padding: 5px 1px 5px 20 px;
 font-size: 12pt; font-weight: normal;
 background-color: """ + bgColor + """;
}

td#sidelinks a:visited:hover {
 text-decoration: none;
 color: """ + hoverColor + """;
 padding: 5px 1px 5px 20 px;
 font-size: 12pt; font-weight: normal;
 background-color: """ + bgColor + """;
}


A {text-decoration : none;
 color: """ + lnColor + """;
 margin: 0px 10px 0px 0 px;
 border: 0px;
 background-color: """ + bgColor + """;
}

A:link {
 color: """ + lnColor + """;
}

A:visited {
   color: """ + lnVisitColor + """;
}

A:hover {
 color: """ + hoverColor + """;
 background-color: """ + bgColor + """;
 font-weight: bold;
}

A:visited:hover {
 color: """ + hoverColor + """;
 background-color: """ + bgColor + """;
 font-weight: bold;
}


A IMG {
  border-width: 1px;
}

HR { color: #EAEAEA;
 height: 1;    
}

HR.headlineupper {
  margin: 5px 0px 0px 0px;
  padding: 0px 0px;
}

HR.headlinelower {
  margin: 0px 0px 1em 0px;
  padding: 0px 0px;
}

HR.abovegallerylink { margin: 0px 0px 0px 0px;
}
""")

        stylesheet = open(os.path.join(directory, stylesheet), "w")
        stylesheet.write(string.joinfields(html))
        stylesheet.close()
    except:
        printTraceback()
        sys.exit()
        


def constructUniqueFilename(fileNameDictionary, file):
    "When adding pictures, nameclashes may arise. If so, construct unique name here"
    counter = 1
    slice = ""
    underscorePos = file.rfind("_")
    if underscorePos > -1:
        slice = file[:underscorePos]
    else:
        slice = file[:-4]
    while 1:
        try:
            fileNameDictionary[slice + "_" + str(counter) + ".jpg"]
            counter = counter + 1
        except:
            break
    newFileName = slice + "_" + str(counter) + ".jpg"
    return newFileName


def printTraceback():
    print >> sys.stderr, '-'*60
    print >> sys.stderr, "Error in application"
    traceback.print_exc(file=sys.stderr)
    print >> sys.stderr, '-'*60


def getYesNo(boolean):
    if boolean:
        return "Yes"
    else:
        return "No"
    


def xmlString(str):
    if not str:
        return ""
    else:
        return xml.sax.saxutils.escape(str.strip())
    

def quoteIt(string):
    "Quote xml for &, >, <, \, /, [, ]"
    string = string.replace("&", "&amp;")
    string = string.replace("<", "&lt;")
    string = string.replace(">", "&gt;")
    string = string.replace("\"", "&quot;")
    string = string.replace("\/", "&#047;")
    string = string.replace("\\", "&#092;")
    string = string.replace("]", "&#091;")
    string = string.replace("[", "&#093;")

    return string


def quoteUrl(string):
    """Quote so that links with those
    chars works on IE, it does on FireFox anyway"""
    urllib.quote_plus(string)

    return string



def createDirectories(pictureDirectory, fullsize):
    """Create destination dir and necessary subdirs"""

    # Create subdirectories as necessary. 
    (Directory,FileName)=os.path.split(pictureDirectory + "/dummy")
    try:
        os.makedirs(Directory) # make directories as needed
    except:
        # os.makedirs raises an exception if the directory exists.
        # We ignore the exception.
        pass 
    
    if os.path.exists(os.path.join(pictureDirectory, "thumbnails")) == 0:
        os.mkdir(os.path.join(pictureDirectory, "thumbnails"))

    if os.path.exists(os.path.join(pictureDirectory, "resized")) == 0:
        os.mkdir(os.path.join(pictureDirectory, "resized"))

    if fullsize:
        if os.path.exists(os.path.join(pictureDirectory, "fullsize")) == 0:
            os.mkdir(os.path.join(pictureDirectory, "fullsize"))



def getTitle(srcdirectory, props=None):
    """Return title, if default filename 'title.txt' is present in a 
    directory the content is used, else the dirname is used.
    If recursion is not on and a supplied title parameter is specified it is returned"""
    title=None

    filename = os.path.join(srcdirectory, 'title.txt')

    if os.path.isfile(filename):
        file = open(filename)
        title = file.read()
        file.close()

    if title is None:
        title = os.path.split(srcdirectory)[1]

    if props["recurse"] == 0:
        try:
            if props["title"] is not None:
                title = props["title"]
        except:
            pass
    return title


def wrapItemsInTag(list, tag):
    """Wrap listitems in <tag>listitem</tag>
       returns a string
    """
    if not list:
        return list

    starttag = "<" + tag + ">"
    endtag   = "</" + tag + ">"
    result = ["""%s%s%s\n""" % (starttag, item, endtag) for item in list]
    return "".join(result)
    
