# LinkExchange - Universal link exchange service client
# Copyright (C) 2009 Konstantin Korikov
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# NOTE: In the context of the Python environment, I interpret "dynamic
# linking" as importing -- thus the LGPL applies to the contents of
# the modules, but make no requirements on code importing these
# modules.


class BaseFormatter(object):
    def __init__(self, count):
        """
        @param count: links count in the block (0 or None - catch all)
        """
        self.count = count

    def format(self, tags, links):
        """
        Perform links formatting. tags is a list of unicode strings that don't
        contains '<a '. links is a list of unicode strings that contains links
        HTML code.

        @param tags: list of special tags
        @param links: list of links
        @return: HTML code
        """
        pass

    def _add_prefix(self, link, prefix):
        i = 0
        while not (prefix[:i] + link).startswith(prefix):
            i += 1
        link = prefix[:i] + link
        return link

    def _add_suffix(self, link, suffix):
        i = len(suffix)
        while not (link + suffix[i:]).endswith(suffix):
            i -= 1
        link += suffix[i:]
        return link

    def _format_container(self, tag, id, class_, content):
        html = u'<' + tag
        if id:
            html += u' id="%s"' % id
        if class_:
            html += u' class="%s"' % class_
        html += u'>'
        html += content
        html += u'</%s>' % tag
        return html

class InlineFormatter(BaseFormatter):
    def __init__(self, count,
            delimiter = '',
            prefix = '',
            suffix = '',
            prolog = '',
            epilog = '',
            id = None,
            class_ = None,
            class_for_empty = None):
        """
        @param count: links count in the block (None - catch all)
        @keyword delimiter: links delimiter
        @keyword prefix: links prefix
        @keyword suffix: links suffix
        @keyword prolog: text before links
        @keyword epilog: text after links
        @keyword id: value for id attribute
        @keyword class_: CSS class for nonempty block
        @keyword class_for_empty: CSS class for empty block
        """
        super(InlineFormatter, self).__init__(count)
        self.delimiter = delimiter
        self.prefix = prefix
        self.suffix = suffix
        self.prolog = prolog
        self.epilog = epilog
        self.id = id
        self.class_ = class_
        self.class_for_empty = class_for_empty

    def format(self, tags, links):
        def format_link(link):
            if self.prefix:
                link = self._add_prefix(link, self.prefix)
            if self.suffix:
                link = self._add_suffix(link, self.suffix)
            return link
        if links:
            css_class = self.class_
        else:
            css_class = self.class_for_empty
        html = self._format_container('div', self.id, css_class,
                links and (self.prolog +
                    self.delimiter.join(map(format_link, links)) +
                    self.epilog) or u'')
        html += u''.join(tags)
        return html

class ListFormatter(BaseFormatter):
    def __init__(self, count,
            prefix = '',
            suffix = '',
            id = None,
            class_ = None,
            class_for_empty = None,
            tag_for_empty = 'span'):
        """
        @param count: links count in the block (None - catch all)
        @keyword prefix: links prefix
        @keyword suffix: links suffix
        @keyword id: value for id attribute
        @keyword class_: CSS class for nonempty block
        @keyword class_for_empty: CSS class for empty block
        @keyword tag_for_empty: HTML tag for empty block
        """
        super(ListFormatter, self).__init__(count)
        self.prefix = prefix
        self.suffix = suffix
        self.id = id
        self.class_ = class_
        self.class_for_empty = class_for_empty
        self.tag_for_empty = tag_for_empty

    def format(self, tags, links):
        def format_link(link):
            if self.prefix:
                link = self._add_prefix(link, self.prefix)
            if self.suffix:
                link = self._add_suffix(link, self.suffix)
            link = u'<li>%s</li>' % link
            return link
        if links:
            css_class = self.class_
        else:
            css_class = self.class_for_empty
        html_tag = links and u'ul' or self.tag_for_empty
        html = self._format_container(html_tag, self.id, css_class,
                u''.join(map(format_link, links)))
        html += u''.join(tags)
        return html
