"""Table widget.
"""
import grok
from hurry import yui
from zope.interface import Interface
from waeup.sirp.widgets.interfaces import ITableProvider

def varName(string):
    varname = string.lower()
    return ''.join([x for x in varname
                    if x in 'abcdefghijklmnopqrstuvwxyz_0123456789'])

class Col(object):
    """A column in a table.
    """
    header = 'Unnamed'
    type = None
    sortable = False
    width = 100

    def __init__(self, header=u'Unnamed', width=None, sortable=False,
                 type=None, data=()):
        self.header = header
        self.width = width
        self.sortable = sortable
        self.type = type
        self.data = data
        self.key = varName(header)
    
class Table(object):
    """A table.
    """
    def __init__(self, title=u'Unnamed', width=500, height=180, cols=()):
        self.title = title
        self.cols = cols
        self.width = width
        self.height = height
        self.internal_title = varName(title)

    def renderHTML(self):
        result = '<div id="%s-tablecontainer"><table id="%s-table">' % (
            self.internal_title, self.internal_title)
        data_rows = self.getRows()
        result += '<thead><tr>'
        for col in self.cols:
            result += '<th>%s</th>' % (col.header,)
        result += '</tr></thead>\n'
        result += '<tbody>'
            
        for row in data_rows:
            result += '<tr>\n  '
            for elem in row:
                result += '<td>%s</td>' % elem
            result += '\n</tr>'
        result += '</tbody></table></div>'
        return result

    def getRows(self):
        data_cols = (x.data for x in self.cols)
        # turn rows into cols and vice versa:
        # ((a, 1, p), (b, 2, q)) --> ((a, b), (1, 2), (p, q))
        data_rows = tuple(map(lambda *x: (x), *data_cols))
        return data_rows


class YUITable(Table):
    """A table that can generate JavaScript code for use with YUI.
    """
    def need(self):
        yui.dragdrop.need() # datatable needs dragdrop loaded in advance.
                            # This dependency is not defined yet in hurry.yui.
        yui.paginator.need()
        yui.datatable.need()
        yui.sam.need()
        yui.fonts.need()

    def getJSTableCode(self, paginator=True):
        title = self.internal_title
        fielddefs = ",".join(['{key:"%s"}'%x.key for x in self.cols])
        coldefs = ",".join([
                '{key:"%s",label:"%s",sortable:%s}' % (
                    x.key, x.header, str(x.sortable).lower())
                for x in self.cols
                ])
        result = """
YAHOO.util.Event.addListener(window, "load", function() {
  var %sDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("%s-table"));
  %sDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
  %sDataSource.responseSchema = {
    fields: [%s]
  };

  var %sColDefs = [%s];
  var %sDataTable = new YAHOO.widget.DataTable("%s-tablecontainer",
                                               %sColDefs, %sDataSource,
                                               {
paginator: new YAHOO.widget.Paginator({ 
	                rowsPerPage: 15, 
	                template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE, 
	                rowsPerPageOptions: [10,15,30,50,100], 
	                pageLinks: 5 
	            }), 
draggableColumns:true });
});
""" % (
            title, title, title, title, fielddefs, title, coldefs,
            title, title, title, title)
        return result


    
class YUIStaticTableView(grok.View):
    grok.context(Interface)
    grok.name('yuistatictables.js')

    def render(self):
        try:
            provider = ITableProvider(self.context)
        except:
            # No table provider for the context. Be gentle...
            return ''
        self.response.setHeader('Content-Type',
                                'text/javascript; charset=UTF-8')
        tables = provider.getTables()
        results = [table.getJSTableCode() for table in tables]
        return '\n'.join(results)
