###############################################################################
#
# Comments - A class for writing the Excel XLSX Worksheet file.
#
# Copyright 2013-2020, John McNamara, jmcnamara@cpan.org
#

import re

from . import xmlwriter
from .utility import xl_rowcol_to_cell


class Comments(xmlwriter.XMLwriter):
    """
    A class for writing the Excel XLSX Comments file.


    """

    ###########################################################################
    #
    # Public API.
    #
    ###########################################################################

    def __init__(self):
        """
        Constructor.

        """

        super(Comments, self).__init__()
        self.author_ids = {}

    ###########################################################################
    #
    # Private API.
    #
    ###########################################################################

    def _assemble_xml_file(self, comments_data=[]):
        # Assemble and write the XML file.

        # Write the XML declaration.
        self._xml_declaration()

        # Write the comments element.
        self._write_comments()

        # Write the authors element.
        self._write_authors(comments_data)

        # Write the commentList element.
        self._write_comment_list(comments_data)

        self._xml_end_tag('comments')

        # Close the file.
        self._xml_close()

    ###########################################################################
    #
    # XML methods.
    #
    ###########################################################################

    def _write_comments(self):
        # Write the <comments> element.
        xmlns = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'

        attributes = [('xmlns', xmlns)]

        self._xml_start_tag('comments', attributes)

    def _write_authors(self, comment_data):
        # Write the <authors> element.
        author_count = 0

        self._xml_start_tag('authors')

        for comment in comment_data:
            author = comment[3]

            if author is not None and author not in self.author_ids:
                # Store the author id.
                self.author_ids[author] = author_count
                author_count += 1

                # Write the author element.
                self._write_author(author)

        self._xml_end_tag('authors')

    def _write_author(self, data):
        # Write the <author> element.
        self._xml_data_element('author', data)

    def _write_comment_list(self, comment_data):
        # Write the <commentList> element.
        self._xml_start_tag('commentList')

        for comment in comment_data:
            row = comment[0]
            col = comment[1]
            text = comment[2]
            author = comment[3]
            font_name = comment[6]
            font_size = comment[7]
            font_family = comment[8]

            # Look up the author id.
            author_id = None
            if author is not None:
                author_id = self.author_ids[author]

            # Write the comment element.
            font = (font_name, font_size, font_family)
            self._write_comment(row, col, text, author_id, font)

        self._xml_end_tag('commentList')

    def _write_comment(self, row, col, text, author_id, font):
        # Write the <comment> element.
        ref = xl_rowcol_to_cell(row, col)

        attributes = [('ref', ref)]

        if author_id is not None:
            attributes.append(('authorId', author_id))

        self._xml_start_tag('comment', attributes)

        # Write the text element.
        self._write_text(text, font)

        self._xml_end_tag('comment')

    def _write_text(self, text, font):
        # Write the <text> element.
        self._xml_start_tag('text')

        # Write the text r element.
        self._write_text_r(text, font)

        self._xml_end_tag('text')

    def _write_text_r(self, text, font):
        # Write the <r> element.
        self._xml_start_tag('r')

        # Write the rPr element.
        self._write_r_pr(font)

        # Write the text r element.
        self._write_text_t(text)

        self._xml_end_tag('r')

    def _write_text_t(self, text):
        # Write the text <t> element.
        attributes = []

        if re.search(r'^\s', text) or re.search(r'\s$', text):
            attributes.append(('xml:space', 'preserve'))

        self._xml_data_element('t', text, attributes)

    def _write_r_pr(self, font):
        # Write the <rPr> element.
        self._xml_start_tag('rPr')

        # Write the sz element.
        self._write_sz(font[1])

        # Write the color element.
        self._write_color()

        # Write the rFont element.
        self._write_r_font(font[0])

        # Write the family element.
        self._write_family(font[2])

        self._xml_end_tag('rPr')

    def _write_sz(self, font_size):
        # Write the <sz> element.
        attributes = [('val', font_size)]

        self._xml_empty_tag('sz', attributes)

    def _write_color(self):
        # Write the <color> element.
        attributes = [('indexed', 81)]

        self._xml_empty_tag('color', attributes)

    def _write_r_font(self, font_name):
        # Write the <rFont> element.
        attributes = [('val', font_name)]

        self._xml_empty_tag('rFont', attributes)

    def _write_family(self, font_family):
        # Write the <family> element.
        attributes = [('val', font_family)]

        self._xml_empty_tag('family', attributes)
