#
#   DataTableForm.ptl
#
#   Form for display of Database Query Contents
#
#   by: Benjamin Scherrey
#   (C)opyright 2003, Proteus Technologies, Inc.
#   All Rights Reserved
#
#   History -   2003.04.26  Ben Scherrey            Initial file creation
#

from quixote.form import Form
from pyPgSQL import PgSQL
import time

def likeclause( dict ):
    likecount = 0
    result = ' where '
    for n in dict:
        if dict[n]:
            if likecount:
                result = result + ' and '
            likecount += 1
            result = result + ' "' + n + '" ~* ' + "'" + str(dict[n]) + "'"
        
    if likecount:
        return result
    else:
        return None

# Basic display table.
# Filterable if the 'select' statement is provided so cursor can be updated.
# TODO - Implement row-wrap around after maxlinewidth is exceeded.
# TODO - Do something with the startpos, Bof & Eof...
class DataTableForm( Form ):
    def __init__( self, cur, startpos = None, displimit = 10, maxlinewidth = 90, select = None, predicate = None ):
        print "DataTableForm::__init__"
        Form.__init__( self )

        if startpos:
            self.Bof        = False
            self.Record     = startpos
            self.StartPos   = startpos
        else:
            self.Bof        = True
            self.Record     = 0
            self.StartPos   = 0

        if cur.rowcount:
            self.Eof        = False
        else:
            self.Eof        = True
            self.Bof        = True
            self.Record     = 0
            self.StartPos   = 0

        self.Cur            = cur        
        self.DispLimit      = displimit
        self.MaxLineWidth   = maxlinewidth
        self.Select         = select
        self.Predicate      = predicate
        self.Filter         = None
        
        # Add our widgets now...
        for i in self.Cur.description:
            # TODO - This should probably be changed to identify appropriate widget types.
            self.add_widget("string", i[0], title = i[0], size = i[3])

        self.add_submit_button("PrevX5","PrevX5")        
        self.add_submit_button("Prev","Prev")
        self.add_submit_button("Next","Next")
        self.add_submit_button("NextX5","NextX5")

        # Can't filter without our select statement.        
        if self.Select:
            self.add_submit_button("Filter","Filter")

    def genHeader [html] ( self, request ):
        """     <tr>"""

        # Spacer for button column
        """         <td></td>"""

        for i in self.widget_order:
            """<td> %s </td>""" % (i.name)

        # No filter fields without a select statement to update.
        if self.Select:

            # This submit will not work without a matching widget for Quixote to recognize...            
            """ </tr>
                <tr>
                <td> <input type="submit" name="Filter" value="Filter" /> </td>
            """
        
            # Create search filters
            for w in self.widget_order:
                # Don't print 'None' for empty data                        
                data = w.value
                if not data or data == 'None':
                    data=""
    
                # TODO - This should probably be changed to support widget types...                        
                input = """<input type=text name=%s size=%i maxlength=%i value="%s" />""" \
                        % ( w.name, w.size, w.size, data )
                """<td> %s </td>""" % input
            
        """ </tr>"""

    def genContent [html] ( self, request ):
        print "genContent"
        if self.Cur:
            x = self.Cur.fetchmany( self.DispLimit )
            self.Record += self.Cur.rowcount
            
            # Are we at the end?
            if self.Cur.rowcount < self.DispLimit:
                self.Eof = True
            else:
                self.Eof = False

            if x:
                row = 0
                for y in x:
                    # Has spacer for button column...
                    """
                    <tr>
                        <td></td>
                    """
                    field = 0
                    for i in y:

                        # Don't print 'None' for empty data                        
                        data = i
                        if not data or data == 'None':
                            data=""

                        w = self.widget_order[field]

                        # TODO - This should probably be changed to support widget types...                        
                        input = """<input type=text name=%s%i size = %i maxlength=%i value="%s" """ \
                                % ( w.name + '-', row, w.size, w.size, data )
                            
                        """<td> %s </td>""" % input
                        field += 1
                        
                    """
                    </tr>
                    """
                    row += 1

            else:
                print "WARNING - ran out of records!"

            # Put our cursor back where it belongs...                
            self.prev() 
                            
    def cursorBackward( self, records ):
        self.Cur.execute('MOVE BACKWARD %i IN "%s"' % ( records, self.Cur.name ))

    def cursorForward( self, records ):
        self.Cur.execute('MOVE FORWARD %i IN "%s"' % ( records, self.Cur.name ))

    def prev( self, multiple = 1 ):
        print "DataTable::prev"
        self.Record -= self.DispLimit
        if self.Record <= 0:
            self.Record = 0
            self.Bof = True
        if self.Cur.rowcount < self.DispLimit:
            self.Eof = True
        self.cursorBackward( self.DispLimit * multiple )
        
    def next( self, multiple = 1 ):
        print "DataTableForm::next"
        #self.Record += self.DispLimit
        self.Bof = False;
        if self.Cur.rowcount < self.DispLimit:
            self.Eof = True
        self.cursorForward( self.DispLimit * multiple )
        
    # Overload Form::_render_visible_widgets()
    def _render_visible_widgets( self, request ):
        r = TemplateIO(html=1)
        r += self.genHeader( request )
        r += self.genContent( request )
        return r.getvalue()

    def process (self, request):
        # check data
        print "DataTableForm::process"
        form_data = Form.process(self, request)
        return form_data

    def action [html] (self, request, submit_button, form_data):
        # The data has been submitted and verified.  Do something interesting

        print "DataTableForm::action ->", submit_button
        if submit_button=="Next":
            self.next()
        elif submit_button=="Prev":
            self.prev()
        elif submit_button=="NextX5":
            self.next(5)
        elif submit_button=="PrevX5":
            self.prev(5)
        elif submit_button=="Filter":
            print "NEED TO FILTER NOW!"
            wc = likeclause( form_data )
            print "wc = ",wc
            print "self.Filter = ",self.Filter
            if self.Select and ((self.Filter != wc) or (not wc)):
                print "Filter updated! Reselect!"
                self.Filter = wc
                istmt = self.Select
                if self.Filter:
                    istmt += self.Filter
                    if self.Predicate:
                        istmt += " and " + self.Predicate
                else:
                    if self.Predicate:
                        istmt += " where " + self.Predicate
                self.Cur.execute( istmt )
            else:
                print "Filter is the same. No change."
        else:
            print "Unknown Action : %s." % submit_button
        self.render( request, "table" )

        print "request          =", request
        print "submit_button    =", submit_button
        print "form_data        =", form_data
