"""
$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/links.py $
$Id: links.py 31152 2008-09-18 11:27:09Z dbinger $
"""
from dulcinea.attachable import Attachable
from dulcinea.category import Category, Categorized, CategoryDatabase
from dulcinea.item import Item, ItemFolder
from dulcinea.util import wrap_paragraphs, sanitize_url
from qp.lib.spec import boolean, spec, init, add_getters_and_setters
from qp.lib.spec import specify, string
from qp.pub.common import get_publisher, site_now
import random

def get_link_db():
    return get_publisher().get_connection().get_root().get('link_db')

class LinkItem(Item, Attachable, Categorized):

    link_url_is = spec(
        (string, None),
        "Link to relevant target URL")
    text_is = spec(
        (string, None),
        "A few sentences describing the link.")
    email_is = spec(
        (string, None),
        "Submitter's e-mail address")
    first_class_is = spec(
        boolean,
        "Flag to indicate that this link can be shown in a prominent "
        "place like the home page of a site")
    old_key_is = spec(
        (None, string),
        "Key used when Items had str keys")

    def __init__(self):
        Item.__init__(self)
        Attachable.__init__(self)
        Categorized.__init__(self)
        init(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 get_search_text_fields(self):
        return Item.get_search_text_fields(self) + [
            self.get_title(),
            self.get_link_url(),
            self.get_email() or '',
            self.get_text() or ''] + [
            category.get_name() for category in self.get_categories()]

    def set_link_url(self, url):
        specify(self,
                link_url=sanitize_url(url),
                timestamp=site_now())

    def is_first_class(self):
        return self.first_class

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

    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

add_getters_and_setters(LinkItem)


class LinkFolder(ItemFolder, CategoryDatabase):
    """
    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 random_first_class_sample(self, size=3):
        first_class_links = self.get_first_class_links()
        if first_class_links:
            return random.sample(first_class_links, size)
        return []

def get_lower_title(link):
    title = link.get_title()
    if title:
        return title.lower()
    else:
        return ''
