#! /usr/bin/env python

#
# This script will generate a static web site
#

import os, sys, string, shutil
from mkcommons import *

global TARGET
#TARGET = "../public_html"

HEADER  = "inc/head.html"
FOOTER  = "inc/foot.html"
CSS     = "tapoueh.css"
LOGO    = "debian_03.png"

def include(target, file):
    """ include a file content """
    if DEBUG:
        target.write("\n")
        target.write("<!-- include %s -->\n" % file)
    
    for line in open(file):
        target.write(line)

def mkheader(rel = ""):
    """ Read the HEADER file and do some replacements """
    if rel == "":
        css  = CSS
        logo = LOGO
    else:
        css  = mkfilename(rel, CSS)
        logo = mkfilename(rel, LOGO)

    return open(HEADER).read().replace("%css%", css).replace("%logo%", logo)

# mkmenu will generate the menu for files to be included in curdir
#
# curdir is the dir from where we print the menu
# rep is the repertory where to find the linked documents
# level is the menu hierarchy entry level
# files is the list of linked files
# rel is a relative url prefix for links
def mkmenu(curdir = ".", rep = ".", level=0, menu = "", files = [], rel = ""):
    """ Make the menu from rep/menu resource file """
    if rep == ".":
        if DEBUG:
            menu += "\n"
            menu += "<!-- mkmenu -->\n"

        menu += '<div class="menus">\n'

    spaces    = level * "&nbsp;&nbsp;"
    firstlink = ""

    if curdir == ".":
        curdepth = 0
    else:
        curdepth = len(curdir.split('/'))

    if rel == "" or rel == ".":
        reldepth = 0
    else:
        reldepth = len(rel.split('/'))

    # Parse the menu file and generate the destination html files
    # accordingly
    for line in open(mkfilename(rep, MENU)).read().split("\n"):
        if line.strip() == "" or line.find('#') == 0:
            continue

        name, link = line.split(":")

        if link[-1] == "/":
            # We include a subdir
            link = link[:-1]

            subrep = mkfilename(rep, link)
            smenu, files, dlink = mkmenu(curdir, subrep,
                                         level+1, "", files, rel)

            # Override firstlink
            if firstlink == "": firstlink = dlink

            # Print out the menu
            #print link, curdir, level, rep
            if link == curdir:
                # we include submenu, so just print rep name
                menu += '  %s%s<br>\n' % (spaces, name)

            else:
                # the rep name has to be a link to the first submenu
                menu += '%s<a href="%s" title="%s" class="menu">%s</a><br>\n' \
                        % (spaces, dlink, name, name)

            # print curdir, subrep
            if subrep.find(curdir.split('/')[0]) == 0 and level+1 <= curdepth:
                menu += smenu
                
                
        else:
            # We include all links for the subdir
            link = mkfilename(rel, mkfilename(rep, link))
            files.append((rep, link))

            # Override firstlink
            if firstlink == "": firstlink = link
            
            # Manage inclusions of dir/file.html from the menu
            # Only on first call, when rel == ""
            if rel == "" and len(link.split('/')) > 1:
                mksubdirs(link)

            if rep == "." or rep == curdir:
                # we display all the curdir links
                menu += '  %s<a href="%s" title="%s">%s</a><br>\n' \
                        % (spaces, link, name, name)
        
    if rep == ".":
        menu += '</div>\n'

    return menu, files, firstlink


def mklist(includes):
    """ copy the file listed on TARGET """
    # Open the 'list' file if it exists, and copy the file listed to
    # their destination

    # We copy each file listed in the LIST files
    listed_files = []
    for root, dirs, files in os.walk("."):
        if LIST in files:
            listfile = os.path.join(root, LIST)
            for line in open(listfile).read().split("\n"):
                filename = line.strip()
                if filename != "" and filename[0] != "#":
                    # Skip the "./" in the root (from os.walk("."))
                    reldir = root[2:]
                    rel    = ("../" * len(reldir.split('/')))[:-1]
                    parent = string.join(reldir.split('/')[:-1], '/')

                    # Keep trace of copied files
                    listed_files.append(filename)

                    # mkdir -p
                    mksubdirs(filename)

                    # If the file is a .html one, we include header
                    # and footer
                    if filename[-5:] == ".html" and \
                           (includes.has_key(reldir) or \
                            includes.has_key(parent)):
                        if not includes.has_key(reldir):
                            includes[reldir] = {}
                            includes[reldir]["menu"] = includes[parent]["menu"]
                            includes[reldir]["head"] = mkheader(rel)
                        
                        mkhtml(includes, filename, reldir)

                    else:
                        # Just copy the listed file
                        dest = os.path.join(TARGET, filename)
                        if is_newer(filename, dest):
                            if VERBOSE:
                                print dest
                            
                            if os.path.isfile(filename):
                                shutil.copyfile(filename, dest)
                            elif os.path.isdir(filename):
                                mkdir(filename)
                            else:
                                if VERBOSE:
                                    print "Ignoring", filename
                                    listed_files.remove(filename)

    return listed_files

def mkhtml(includes, name, rep = "."):
    """ provide a file name and the rep where to expect it, output the html """
    src_file  = name
    html_file = mkfilename(TARGET, name)

    # Do not create the html_file if up to date
    if not is_newer(src_file, html_file):
        return

    if VERBOSE:
        print html_file

    f = open(html_file, "w")
    f.write(includes[rep]["head"])
    f.write(includes[rep]["menu"])
    include(f, src_file)
    include(f, FOOTER)

    f.close()
    return

def mksite():
    """ Make the static html web site """
    mkdir()

    # Menu links are not the same depending on the level where we
    # include the menu
    menu, files, l = mkmenu()

    includes = {}
    includes["."] = {"menu":menu, "head":mkheader()}

    for rep, file in files:
        mkdir(rep)
        level = len(file.split('/')) - 1

        # We make a new menu in each subdir
        if not includes.has_key(rep):
            #print rep, file
            includes[rep] = {}
            rel = ("../" * level)[:-1]
            includes[rep]["menu"] = mkmenu(curdir=rep, files=[], rel=rel)[0]
            includes[rep]["head"] = mkheader(rel)

        mkhtml(includes, file, rep)

    # Now look for files to publish in LIST files
    mklist(includes)

    return

def main(target):
    """ Here we do the job """
    global TARGET
    TARGET = target

    if VERBOSE:
        print "Using %s target directory" % TARGET

    mksite()
    
if __name__ == "__main__":
    if len(sys.argv) > 1:
        main(sys.argv[1])
    else:
        print "Please specify a target directory"
