#!/usr/bin/python

import os, sys, subprocess
from optparse import OptionParser
import otbApplication

outputpath = os.path.join( os.environ["HOME"], ".qgis/python/plugins/sextante/otb/description" )
endl = os.linesep

docpath = os.path.join(outputpath, 'doc')
if not os.path.exists(docpath):
    os.makedirs(docpath)


def unique(seq): 
    # order preserving
    checked = []
    for e in seq:
        if e not in checked:
            checked.append(e)
    return checked

def ConvertString(s):
    '''Convert a string for compatibility in txt dump'''
    return s


def get_app_list():
    blackList = ["TestApplication"]
    appNames = [app for app in otbApplication.Registry.GetAvailableApplications() if app not in blackList]
    return appNames

def generate_all_app_docs( ) :
    appliIdx = 0
    for appliname in get_app_list():
        appliIdx = appliIdx+1
        appli = otbApplication.Registry.CreateApplication(appliname)
        appli.UpdateParameters() # TODO do we really need this ?
        generate_app_doc_rst( appli, os.path.join(outputpath, 'doc', appliname + '.rst') )

def generate_app_doc_rst( appli, outputrst ):

    rst = ''
    
    rst += '=' * 100 + endl
    rst += appli.GetDocName() + endl
    rst += '=' * 100 + 2*endl
    
    rst += appli.GetDescription() + endl
    rst += endl

    rst += '-' * 100 + endl
    rst += 'Detailed Description' + endl
    rst += '-' * 100 + 2*endl
    
    rst += appli.GetDocLongDescription() + endl
    rst += endl
    
    rst += '-' * 100 + endl
    rst += 'Parameters' + endl
    rst += '-' * 100 + 2*endl
    rst += endl
    
    depth = GetParametersDepth(appli.GetParametersKeys())
    deep = depth > 0
    rst += generate_param_doc(appli,appli.GetParametersKeys(),deep) + endl

    with open( outputrst, 'w' ) as rstfile:
        rstfile.write(rst)


def GetPixelType(value):
    # look for type
    foundcode = -1
    foundname = ""
    for ptypename, ptypecode in pixeltypes.iteritems():
        if value.endswith(ptypename):
            foundcode = ptypecode
            foundname = ptypename
            break
    return foundcode,foundname

def GetParametersDepth(paramlist):
    depth = 0
    for param in paramlist:
        depth = max(param.count("."),depth)
    return depth

def GenerateChoice(app,param,paramlist, level):
    output = indent(level) + "Available choices are: " + 2*endl
    for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
        output +=  indent(level) + "* " + ConvertString(choicename) + endl
        choicedesc = app.GetParameterDescription(param+"."+choicekey)
        if len(choicedesc) >= 2:
            output += indent(level) + indent(1) + ConvertString(choicedesc) + 2*endl
        # List option associated to one choice
        options = []
        for p in paramlist:
            if p.startswith(param+"."+choicekey+"."):
                options.append(p)
        if len(options) > 0:
            for option in options:
                output += indent(level+1) +  "* " + ConvertString(app.GetParameterName(option)) + endl
                output += indent(level+1) + indent(1) + ConvertString(app.GetParameterDescription(option)) + 2*endl
    return output

def indent(n):
    return ' ' * 4 *  n

def generate_param_doc(app,paramlist,deep = False,current="", level=0):
    output = ""
    # First run
    if len(current)==0:
        firstlevelparams = []
        for param in paramlist:
            paramsplit = param.partition(".")
            firstlevelparams.append(paramsplit[0])
        firstlevelparams = unique(firstlevelparams)
        if deep:
            for param in firstlevelparams:
                output += indent(level) + "* " + ConvertString(app.GetParameterName(param)) + endl
                output += indent(level) + indent(1) + ConvertString(app.GetParameterDescription(param)) + 2*endl
                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
                    output += GenerateChoice(app,param,paramlist,level+1)
                else:
                    output += generate_param_doc(app,paramlist,deep,param,level+1)
        else:
            for param in firstlevelparams:
                output += indent(level) + "* " + ConvertString(app.GetParameterName(param)) + endl
                output+=  indent(level) + indent(1) + ConvertString(app.GetParameterDescription(param)) + 2*endl
                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
                    output += GenerateChoice(app,param,paramlist,level+1)
    else:
        currentlevelparams = []
        for param in paramlist:
            if param.startswith(current+".") and param.count(".") == current.count(".")+1:
                currentlevelparams.append(param)
        if len(currentlevelparams) > 0:
            for param in currentlevelparams:
                output += indent(level) + "* " + ConvertString(app.GetParameterName(param)) + endl
                output+=  indent(level) + indent(1) + ConvertString(app.GetParameterDescription(param)) + 2*endl
                output+= generate_param_doc(app,paramlist,deep,param,level+1) + endl
                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
                    output += GenerateChoice(app,param,paramlist,level+1) 
    return output


if __name__ == "__main__" :
    appli = otbApplication.Registry.CreateApplication("OrthoRectification")
    appli.UpdateParameters()
    
    rst = os.path.join(outputpath, 'doc', 'OrthoRectification.rst')
    generate_app_doc_rst(appli, rst)
    
    html = os.path.join(outputpath, 'doc', 'OrthoRectification.html')
    subprocess.call(['rst2html', '--stylesheet', os.path.join(outputpath, '..', 'helper','test.css'), rst, html])
    
    #latex = os.path.join(outputpath, 'doc', 'OrthoRectification.latex.tex')
    #pdflatex = os.path.join(outputpath, 'doc', 'OrthoRectification.latex.pdf')
    #subprocess.call(['rst2latex', rst, latex])
    #subprocess.call(['pdflatex', latex, pdflatex])
    
    #pdf = os.path.join(outputpath, 'doc', 'OrthoRectification.pdf')
    #subprocess.call(['rst2pdf', '-o', pdf, rst])
    
