# -*- coding: utf-8 -*-
#
# Tulip Python Bindings documentation build configuration file, created by
# sphinx-quickstart on Sat Apr  2 17:21:15 2011.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sphinx
import sys

from docutils.nodes import emphasis
from docutils.parsers.rst.roles import set_classes

sphinxVersionStr = sphinx.__version__
sphinxVersion = float(sphinxVersionStr[:sphinxVersionStr.rfind('.')])

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage']
if sphinxVersion < 1.4:
    extensions.append('sphinx.ext.pngmath')
else:
    extensions.append('sphinx.ext.imgmath')

# Add any paths that contain templates here, relative to this directory.
templates_path = ['@CMAKE_CURRENT_SOURCE_DIR@/../common/_templates']

# The suffix of source filenames.
source_suffix = '.rst'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'Tulip Python'
copyright = u'@CurrentYear@, Tulip Team'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '@TulipMMVersion@'
# The full version, including alpha/beta/rc tags.
release = '@Tulip_VERSION@'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['html']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# -- Options for HTML output --------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'agogo'
html_style = 'customized.css'

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = '@CMAKE_CURRENT_SOURCE_DIR@/../../textures/logo32x32.ico'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['@CMAKE_CURRENT_SOURCE_DIR@/../common/_static',
                    '@CMAKE_CURRENT_SOURCE_DIR@/_static']

# If false, no module index is generated.
html_domain_indices = False

# If true, the index is split into individual pages for each letter.
html_split_index = False

# Output file base name for HTML help builder.
htmlhelp_basename = 'TulipPythonBindingsdoc'

# -- Options for LaTeX output ------------------------------------------------

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass.
latex_documents = [
  ('index', 'TulipPythonBindings.tex', u'Tulip Python Bindings Documentation',
   u'Tulip Team', 'manual'),
]

# -- Options for manual page output -------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    ('index', 'tulippythonbindings', u'Tulip Python Documentation',
     [u'Tulip Team'], 1)
]

autoclass_content = 'both'
methodDocstring = {}
methodSignature = {}


def process_docstring(app, what, name, obj, options, lines):

    if what == 'class' or not obj.__doc__:
        return

    currentSignature = ''
    n = name.replace('tulipgui.', '')
    n = n.replace('tulip.', '')

    nbMethods = 0
    pos = 0
    signaturePos = {}
    while obj.__doc__.find(n, pos) != -1:
        pos = obj.__doc__.find(n, pos)
        signaturePos[nbMethods] = pos
        pos += len(n)
        nbMethods += 1

    if n not in methodDocstring.keys():
        methodDocstring[n] = [0] * nbMethods

    methodIdx = 0

    for i in range(nbMethods):
        if methodDocstring[n][i] == 0:
            methodIdx = i
            start = signaturePos[i]
            end = obj.__doc__.find(')\n', start) + 1
            currentSignature = obj.__doc__[start:end]
            methodDocstring[n][i] = 1
            break

    signatureInLines = False
    for l in lines:
        if l.find(currentSignature) != -1:
            signatureInLines = True
            break

    if not signatureInLines:
        lines.insert(0, currentSignature)

    while len(lines) > 0 and lines[0].find(currentSignature) == -1:
        del lines[0]
    if len(lines) > 0 and lines[0].find(currentSignature) != -1:
        del lines[0]
    if len(lines) > 0 and methodIdx < nbMethods - 1:
        start = signaturePos[methodIdx+1]
        end = obj.__doc__.find(')\n', start) + 1
        nextSignature = obj.__doc__[start:end]
        linesIdx = 0
        while lines[linesIdx].find(nextSignature) == -1:
            linesIdx += 1
            if linesIdx >= len(lines):
                break

        curNbLines = len(lines)
        for i in range(curNbLines - linesIdx):
            del lines[linesIdx]


def process_signature(app, what, name, obj, opts, sig, ann):
    global methodSignature
    currentSignature = ''
    n = name.replace('tulipgui.', '')
    n = n.replace('tulip.', '')

    if what != 'class' and obj.__doc__:
        nbMethods = 0
        pos = 0
        signaturePos = {}
        while obj.__doc__.find(n, pos) != -1:
            pos = obj.__doc__.find(n, pos)
            signaturePos[nbMethods] = pos
            pos += len(n)
            nbMethods += 1

        if n not in methodSignature.keys():
            methodSignature[n] = [0] * nbMethods

        for i in range(nbMethods):
            if methodSignature[n][i] == 0:
                start = signaturePos[i]
                end = obj.__doc__.find(')\n', start) + 1
                currentSignature = obj.__doc__[start:end]
                methodSignature[n][i] = 1
                break

        idx1 = currentSignature.find('(')
        idx2 = currentSignature.rfind(')')

        if idx1 != -1 and idx2 != -1:
            s = currentSignature[idx1:idx2+1]
            if s != '':
                sig = s

    return (sig, ann)


# icon role taken from the sphinx-trap theme
# (https://github.com/jfardello/Sphinxtrap)
def faicon_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    options.update({'classes': ["fa"] + ["fa-" + x for x in text.split(",")]})
    options['classes'].append('icon-holder')
    set_classes(options)
    node = emphasis(**options)
    return [node], []


def mdicon_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    options.update({
        'classes': ['mdi'] + ['mdi-' + x for x in text.split(',')]
    })
    options['classes'].append('icon-holder')
    set_classes(options)
    node = emphasis(**options)
    return [node], []


# hack to include dynamically generated Tulip plugins documentation
def source_read(app, docname, source):
    if docname == 'tulippluginsdocumentation':
        f = open('@CMAKE_CURRENT_BINARY_DIR@/tulippluginsdocumentation.rst',
                 'r', encoding='utf-8')
        source[0] += f.read()


def setup(app):
    app.connect('autodoc-process-signature', process_signature)
    app.connect('autodoc-process-docstring', process_docstring)
    app.connect('source-read', source_read)
    app.add_role('faicon', faicon_role)
    app.add_role('mdicon', mdicon_role)
