
"""
An interactive demonstration of L{xmantissa.test.scrolltable}

Run this test like this::
    $ twistd -n athena-widget --element=xmantissa.test.acceptance.scrolltable.scroller
    $ firefox http://localhost:8080/

This will display a large scrollable table, containing 5000 rows.
"""
from zope.interface import implements

import time

from epsilon.extime import Time

from axiom.store import Store

from axiom.item import Item

from axiom.attributes import integer, text, timestamp

from nevow.athena import LiveElement
from nevow import loaders, tags

from xmantissa.scrolltable import ScrollingElement, TYPE_WIDGET
from xmantissa.webtheme import getLoader
from xmantissa import ixmantissa



class Sample(Item):
    """
    A sample item which will be used as the rows in the table displayed.
    """

    quantity = integer(indexed=True)
    title = text()
    date = timestamp(indexed=True)
    color = text(allowNone=False)


class SampleColorWidget(LiveElement):
    """
    Trivial L{LiveElement} which renders a square with the background color of
    L{sampleItem}'s C{color} attribute.

    @ivar sampleItem: The sample item.
    @type sampleItem: L{Sample}
    """
    def __init__(self, sampleItem):
        super(SampleColorWidget, self).__init__(
            docFactory=loaders.stan(
                tags.div(style='background-color: %s' % (sampleItem.color,),
                         render=tags.directive('liveElement'))['hi']))
        self.sampleItem = sampleItem



class SampleColorWidgetColumn(object):
    """
    A widget column which renders a L{SampleColorWidget}.
    """
    implements(ixmantissa.IColumn)
    attributeID = 'color'

    def sortAttribute(self):
        """
        L{SampleColorWidgetColumn} objects cannot be sorted.
        """
        return None


    def extractValue(self, model, sampleItem):
        """
        Make a L{SampleColorWidget} out of C{sampleItem}.
        """
        fragment = SampleColorWidget(sampleItem)
        fragment.setFragmentParent(model)
        return fragment


    def getType(self):
        """
        Return L{TYPE_WIDGET}
        """
        return TYPE_WIDGET



def populate(aStore, itemCount=5000):
    """
    Populate the store.

    @param aStore: an Axiom store to populate

    @param itemCount: the number of L{Sample} items to create.
    """
    now = time.time()
    colors = [u'red', u'blue']
    def fxn():
        for x in xrange(itemCount):
            yield (x * 2,
                   u"Number %d" % (x,),
                   Time.fromPOSIXTimestamp(now - x),
                   colors[x % 2])
    aStore.batchInsert(Sample, [Sample.quantity, Sample.title, Sample.date, Sample.color],
                       fxn())



class FakeTranslator(object):
    """
    This is a fake implementation of IWebTranslator to simplify testing.
    """
    def __init__(self, aStore):
        """
        Create a FakeTranslator from a store.
        """
        self.store = aStore


    def toWebID(self, theItem):
        """
        Generate a simple webID for a given row.
        """
        return str(theItem.storeID)


    def fromWebID(self, webID):
        """
        Retrieve a given item from an ID generated by FakeTranslator.toWebID.
        """
        return self.store.getItemByID(int(webID))



def scroller():
    """
    Create a scrolling element with a large number of rows for use in an
    interactive demonstration.
    """
    aStore = Store()
    populate(aStore)
    se = ScrollingElement(aStore, Sample, None,
                          [Sample.quantity,
                           Sample.date,
                           Sample.title,
                           SampleColorWidgetColumn()],
                          webTranslator=FakeTranslator(aStore),
                          defaultSortAscending=False)
    se.docFactory = getLoader(se.fragmentName)
    return se
