"""$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/links.py $
$Id: links.py 26260 2005-02-28 15:55:47Z dbinger $
"""
import random
from datetime import datetime
from quixote.html import htmlescape, htmltext, href
from dulcinea.attachable import Attachable
from dulcinea.category import Category, Categorized, CategoryDatabase
from dulcinea.item import Item, ItemFolder
from dulcinea.spec import any, boolean
from dulcinea.typeutils import typecheck
from dulcinea.util import format_text, wrap_paragraphs, sanitize_url

class LinkItem(Item, Attachable, Categorized):
    """
    Instance attributes:
      link_url : string
        Link to relevant target URL
      text : string
        A few sentences describing the link.
      email : string
        Submitter's e-mail address
      first_class : boolean
        Flag to indicate that this link can be shown in a prominent
        place like the home page of a site
    """

    link_url_is = any(str, None)
    text_is = any(str, None)
    email_is = any(str, None)
    first_class = boolean

    def __init__(self):
        Item.__init__(self)
        Attachable.__init__(self)
        Categorized.__init__(self)
        self.link_url = None
        self.text = None
        self.email = None
        self.first_class = False

    def get_allowed_mime_types(self, user=None):
         """() -> [string]
         """
         if user and user.is_admin():
             return Attachable.get_allowed_mime_types(self)
         else:
             return ["image/gif", "image/jpeg", "image/png",
                     "image/tiff", "image/x-ms-bmp"]


    def set_link_url(self, url):
        typecheck(url, str)
        self.link_url = sanitize_url(url)
        self.timestamp = datetime.now()

    def get_link_url(self):
        "Return the URL to the link this item refers to"
        return self.link_url

    def set_text(self, text):
        self.text = text

    def get_text(self):
        return self.text

    def set_email(self, email):
        self.email = email

    def get_email(self):
        return self.email

    def is_first_class(self):
        return self.first_class

    def set_first_class(self, first_class):
        typecheck(first_class, bool)
        self.first_class = first_class

    def get_local_url(self):
        "Return the URL to this Item"
        return "/links/%s/" % self.get_key()

    def img_href(self, width=None):
        files = self.get_attached_files()
        if files:
            return href("%sgoto" % self.get_local_url(), htmltext(
                '<img src="%sfile/%s" %s class="sponsor" alt="%s" />' % (
                self.get_local_url(), files[0].get_id(),
                width and 'width="%s"' % width or '', self.get_title())))
        return htmltext('')

    def as_html(self, full=0, action_links=None):
        title = href("%sgoto" % self.get_local_url(),
                     htmlescape(self.get_title()))
        if not self.approved:
            title += ' ' + href("%sedit" % self.get_local_url(), "(Unapproved)")
        if action_links:
            title += ' ' + action_links
        body = (self.get_text() and format_text(self.get_text())) or ''
        body = self.img_href() + body
        if full:
            email = htmltext('<p><b>Contact email:</b> %s</p>' % (
                href('mailto:%s' % self.get_email(), self.get_email())))
            key = htmltext('<p><b>Key:</b> %s</p>' % self.get_key())
            categories = htmltext('<p><b>Categorys:</b> %s</p> ' % ', '.join(
                [category.get_label() for category in self.get_categories()]))
            url = htmltext('<p><b>URL:</b> %s</p>' % href(
                self.get_link_url(), self.get_link_url()))
            first_class = htmltext('<p><b>First Class</b> %s</p>' % (
                self.is_first_class()))
            body += key + categories + email + url + first_class
        value = htmltext('\n<dt>%s</dt>\n' % title)
        if body:
            value += htmltext('<dd>%s</dd>\n' % body)
        return value

    def as_text(self):
        return "%s\n\n%s\nURL: %s" % (self.get_title(), self.get_text(),
                                      self.get_link_url())
    def as_email(self):
        body = "%s\n" % self.get_title()
        if self.get_link_url():
            body += "(%s)\n" % self.get_link_url()
        body += "\n%s" % wrap_paragraphs(self.get_text())
        return self.title, body

    def as_rss(self, servername):
        return """<item>
        <title>%s<title>
        <link>http://%s%s/goto</link>
        <description>%s</description>
        </item>""" % (htmlescape(self.get_title()),
                      servername,
                      htmlescape(self.get_local_url()),
                      htmlescape(self.get_text()))


class LinkFolder(ItemFolder, CategoryDatabase):
    """
    Instance attributes: none
    
    To add a new leaf Category, create the Category instance, set it's 'name'
    and 'label', choose a parent Category from the LinkFolder.categories
    dictionary and call it's 'add_child' to add the new category, finally call
    LinkFolder.add_category to add the new Category to categories
    """

    def __init__(self):
        ItemFolder.__init__(self)
        CategoryDatabase.__init__(self)
        links_category = Category(name='all')
        links_category.set_label('All Links')
        self.add_category(links_category)

    def links_with_category(self, category):
        return [link for link in self.get_items() if link.in_category(category)]

    def get_all_links(self):
        return self.get_items()

    def get_first_class_links(self):
        return [link for link in self.get_items() if link.is_first_class()]

    def random_first_class_link(self):
        first_class_links = self.get_first_class_links()
        if first_class_links:
            return random.choice(first_class_links)
        return None

def sort_reverse_by_date(link1, link2):
    # Sort links cronologically with most recent first
    return cmp(link2.get_timestamp(), link1.get_timestamp())

def sort_by_title(link1, link2):
    title1 = (link1.get_title() and link1.get_title().lower()) or None
    title2 = (link2.get_title() and link2.get_title().lower()) or None
    return cmp(title1, title2)
