#!/usr/bin/env python3
# -*- coding: utf-8; mode: python -*-
# pylint: disable=C0330, R0903, R0912

u"""
    flat-table
    ~~~~~~~~~~

    Implementation of the ``flat-table`` reST-directive.

    :copyright:  Copyright (C) 2016  Markus Heiser
    :license:    GPL Version 2, June 1991 see linux/COPYING for details.

    The ``flat-table`` (:py:class:`FlatTable`) is a double-stage list similar to
    the ``list-table`` with some additional features:

    * *column-span*: with the role ``cspan`` a cell can be extended through
      additional columns

    * *row-span*: with the role ``rspan`` a cell can be extended through
      additional rows

    * *auto span* rightmost cell of a table row over the missing cells on the
      right side of that table-row.  With Option ``:fill-cells:`` this behavior
      can be changed from *auto span* to *auto fill*, which automatically inserts
      (empty) cells instead of spanning the last cell.

    Options:

    * header-rows:   [int] count of header rows
    * stub-columns:  [int] count of stub columns
    * widths:        [[int] [int] ... ] widths of columns
    * fill-cells:    instead of autospann missing cells, insert missing cells

    roles:

    * cspan: [int] additionale columns (*morecols*)
    * rspan: [int] additionale rows (*morerows*)
"""

# ==============================================================================
# imports
# ==============================================================================

from docutils import nodes
from docutils.parsers.rst import directives, roles
from docutils.parsers.rst.directives.tables import Table
from docutils.utils import SystemMessagePropagation

# ==============================================================================
# common globals
# ==============================================================================

__version__  = '1.0'

# ==============================================================================
def setup(app):
# ==============================================================================

    app.add_directive("flat-table", FlatTable)
    roles.register_local_role('cspan', c_span)
    roles.register_local_role('rspan', r_span)

    return dict(
        version = __version__,
        parallel_read_safe = True,
        parallel_write_safe = True
    )

# ==============================================================================
def c_span(name, rawtext, text, lineno, inliner, options=None, content=None):
# ==============================================================================
    # pylint: disable=W0613

    options  = options if options is not None else {}
    content  = content if content is not None else []
    nodelist = [colSpan(span=int(text))]
    msglist  = []
    return nodelist, msglist

# ==============================================================================
def r_span(name, rawtext, text, lineno, inliner, options=None, content=None):
# ==============================================================================
    # pylint: disable=W0613

    options  = options if options is not None else {}
    content  = content if content is not None else []
    nodelist = [rowSpan(span=int(text))]
    msglist  = []
    return nodelist, msglist


# ==============================================================================
class rowSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321
class colSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321
# ==============================================================================

# ==============================================================================
class FlatTable(Table):
# ==============================================================================

    u"""FlatTable (``flat-table``) directive"""

    option_spec = {
        'name': directives.unchanged
        , 'class': directives.class_option
        , 'header-rows': directives.nonnegative_int
        , 'stub-columns': directives.nonnegative_int
        , 'widths': directives.positive_int_list
        , 'fill-cells' : directives.flag }

    def run(self):

        if not self.content:
            error = self.state_machine.reporter.error(
                'The "%s" directive is empty; content required.' % self.name,
                nodes.literal_block(self.block_text, self.block_text),
                line=self.lineno)
            return [error]

        title, messages = self.make_title()
        node = nodes.Element()          # anonymous container for parsing
        self.state.nested_parse(self.content, self.content_offset, node)

        tableBuilder = ListTableBuilder(self)
        tableBuilder.parseFlatTableNode(node)
        tableNode = tableBuilder.buildTableNode()
        # SDK.CONSOLE()  # print --> tableNode.asdom().toprettyxml()
        if title:
            tableNode.insert(0, title)
        return [tableNode] + messages


# ==============================================================================
class ListTableBuilder(object):
# ==============================================================================

    u"""Builds a table from a double-stage list"""

    def __init__(self, directive):
        self.directive = directive
        self.rows      = []
        self.max_cols  = 0

    def buildTableNode(self):

        colwidths    = self.directive.get_column_widths(self.max_cols)
        if isinstance(colwidths, tuple):
            # Since docutils 0.13, get_column_widths returns a (widths,
            # colwidths) tuple, where widths is a string (i.e. 'auto').
            # See https://sourceforge.net/p/docutils/patches/120/.
            colwidths = colwidths[1]
        stub_columns = self.directive.options.get('stub-columns', 0)
        header_rows  = self.directive.options.get('header-rows', 0)

        table = nodes.table()
        tgroup = nodes.tgroup(cols=len(colwidths))
        table += tgroup


        for colwidth in colwidths:
            colspec = nodes.colspec(colwidth=colwidth)
            # FIXME: It seems, that the stub method only works well in the
            # absence of rowspan (observed by the html builder, the docutils-xml
            # build seems OK).  This is not extraordinary, because there exists
            # no table directive (except *this* flat-table) which allows to
            # define coexistent of rowspan and stubs (there was no use-case
            # before flat-table). This should be reviewed (later).
            if stub_columns:
                colspec.attributes['stub'] = 1
                stub_columns -= 1
            tgroup += colspec
        stub_columns = self.directive.options.get('stub-columns', 0)

        if header_rows:
            thead = nodes.thead()
            tgroup += thead
            for row in self.rows[:header_rows]:
                thead += self.buildTableRowNode(row)

        tbody = nodes.tbody()
        tgroup += tbody

        for row in self.rows[header_rows:]:
            tbody += self.buildTableRowNode(row)
        return table

    def buildTableRowNode(self, row_data, classes=None):
        classes = [] if classes is None else classes
        row = nodes.row()
        for cell in row_data:
            if cell is None:
                continue
            cspan, rspan, cellElements = cell

            attributes = {"classes" : classes}
            if rspan:
                attributes['morerows'] = rspan
            if cspan:
                attributes['morecols'] = cspan
            entry = nodes.entry(**attributes)
            entry.extend(cellElements)
            row += entry
        return row

    def raiseError(self, msg):
        error =  self.directive.state_machine.reporter.error(
            msg
            , nodes.literal_block(self.directive.block_text
                                  , self.directive.block_text)
            , line = self.directive.lineno )
        raise SystemMessagePropagation(error)

    def parseFlatTableNode(self, node):
        u"""parses the node from a :py:class:`FlatTable` directive's body"""

        if len(node) != 1 or not isinstance(node[0], nodes.bullet_list):
            self.raiseError(
                'Error parsing content block for the "%s" directive: '
                'exactly one bullet list expected.' % self.directive.name )

        for rowNum, rowItem in enumerate(node[0]):
            row = self.parseRowItem(rowItem, rowNum)
            self.rows.append(row)
        self.roundOffTableDefinition()

    def roundOffTableDefinition(self):
        u"""Round off the table definition.

        This method rounds off the table definition in :py:member:`rows`.

        * This method inserts the needed ``None`` values for the missing cells
        arising from spanning cells over rows and/or columns.

        * recount the :py:member:`max_cols`

        * Autospan or fill (option ``fill-cells``) missing cells on the right
          side of the table-row
        """

        y = 0
        while y < len(self.rows):
            x = 0

            while x < len(self.rows[y]):
                cell = self.rows[y][x]
                if cell is None:
                    x += 1
                    continue
                cspan, rspan = cell[:2]
                # handle colspan in current row
                for c in range(cspan):
                    try:
                        self.rows[y].insert(x+c+1, None)
                    except: # pylint: disable=W0702
                        # the user sets ambiguous rowspans
                        pass # SDK.CONSOLE()
                # handle colspan in spanned rows
                for r in range(rspan):
                    for c in range(cspan + 1):
                        try:
                            self.rows[y+r+1].insert(x+c, None)
                        except: # pylint: disable=W0702
                            # the user sets ambiguous rowspans
                            pass # SDK.CONSOLE()
                x += 1
            y += 1

        # Insert the missing cells on the right side. For this, first
        # re-calculate the max columns.

        for row in self.rows:
            if self.max_cols < len(row):
                self.max_cols = len(row)

        # fill with empty cells or cellspan?

        fill_cells = False
        if 'fill-cells' in self.directive.options:
            fill_cells = True

        for row in self.rows:
            x =  self.max_cols - len(row)
            if x and not fill_cells:
                if row[-1] is None:
                    row.append( ( x - 1, 0, []) )
                else:
                    cspan, rspan, content = row[-1]
                    row[-1] = (cspan + x, rspan, content)
            elif x and fill_cells:
                for i in range(x):
                    row.append( (0, 0, nodes.comment()) )

    def pprint(self):
        # for debugging
        retVal = "[   "
        for row in self.rows:
            retVal += "[ "
            for col in row:
                if col is None:
                    retVal += ('%r' % col)
                    retVal += "\n    , "
                else:
                    content = col[2][0].astext()
                    if len (content) > 30:
                        content = content[:30] + "..."
                    retVal += ('(cspan=%s, rspan=%s, %r)'
                               % (col[0], col[1], content))
                    retVal += "]\n    , "
            retVal = retVal[:-2]
            retVal += "]\n  , "
        retVal = retVal[:-2]
        return retVal + "]"

    def parseRowItem(self, rowItem, rowNum):
        row = []
        childNo = 0
        error   = False
        cell    = None
        target  = None

        for child in rowItem:
            if (isinstance(child , nodes.comment)
                or isinstance(child, nodes.system_message)):
                pass
            elif isinstance(child , nodes.target):
                target = child
            elif isinstance(child, nodes.bullet_list):
                childNo += 1
                cell = child
            else:
                error = True
                break

        if childNo != 1 or error:
            self.raiseError(
                'Error parsing content block for the "%s" directive: '
                'two-level bullet list expected, but row %s does not '
                'contain a second-level bullet list.'
                % (self.directive.name, rowNum + 1))

        for cellItem in cell:
            cspan, rspan, cellElements = self.parseCellItem(cellItem)
            if target is not None:
                cellElements.insert(0, target)
            row.append( (cspan, rspan, cellElements) )
        return row

    def parseCellItem(self, cellItem):
        # search and remove cspan, rspan colspec from the first element in
        # this listItem (field).
        cspan = rspan = 0
        if not len(cellItem):
            return cspan, rspan, []
        for elem in cellItem[0]:
            if isinstance(elem, colSpan):
                cspan = elem.get("span")
                elem.parent.remove(elem)
                continue
            if isinstance(elem, rowSpan):
                rspan = elem.get("span")
                elem.parent.remove(elem)
                continue
        return cspan, rspan, cellItem[:]
