#!/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 changed from *auto span* to *auto fill*, which automaticly 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
# ==============================================================================

import sys

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
# ==============================================================================

# The version numbering follows numbering of the specification
# (Documentation/books/kernel-doc-HOWTO).
__version__  = '1.0'

PY3 = sys.version_info[0] == 3
PY2 = sys.version_info[0] == 2

if PY3:
    # pylint: disable=C0103, W0622
    unicode     = str
    basestring  = str

# ==============================================================================
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)
        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 buidler, 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[:]
