#INCLUDE WCONNECT.H

SET PROCEDURE TO wwShowCursor ADDITIVE
SET PROCEDURE TO wwUtils ADDITIVE
SET PROCEDURE TO wwResponse ADDITIVE
SET PROCEDURE TO wwResponseString ADDITIVE


*** FixUp Project Manager
EXTERNAL ARRAY lvHeader

*************************************************************
DEFINE CLASS wwShowCursor AS Custom
*************************************************************
***    Author: Rick Strahl
***            (c) West Wind Technologies, 1997
***   Contact: (541) 386-2087  / rstrahl@west-wind.com
***  Modified: 01/17/97
***
***  Function:
*************************************************************

*** Custom Properties
DIMENSION aFieldList[1]               && Result of AFIELDS
nFieldCount=0						  && Count from AFIELDS

cTableTitle=""
cHeaderString=""                      && Table Header String

cHeaderBGColor="DarkBlue"
cHeaderColor="White"
cHeaderFont="Verdana,Helvetica"

cTableBGColor="#EEEEEE"
cAlternatingBGColor="#b5c7d6"
lAlternateRows=.T.

cTableWidth="98%"
cTableBorder="1"
cExtraTableTags= [class="blackborder"]
cCellPadding="4"
cCellSpacing="0"

*** Columns for ASCII mode description
nASCIILeftColumns=20
nMemoWidth=25

lCenterTable=.T.
lSumNumerics=.F.
lShowAsTable=.T.        && 0 = No  1 = Yes   2 = Rollover to <PRE> 
lSortable=.F.

*** Paging Properties
nPage_ItemsPerPage=0
nPage_ShowPage=0

*** Internal Paging properties
PROTECTED cPAGE_LINKHTML, cPAGE_OldAlias
nPage_TotalPages=0
nPage_NextPage=0
nPage_PrevPage=0
cPage_PageURL=""
cPage_LinkHTML=""
cPage_OldAlias=""

nForceToPREList=MAX_TABLE_CELLS

oHTML=.NULL.

*** TableEditor
cBaseUrl = ""
cKeyField = ""
cKeyType = "N"
cTableFieldList = ""
cTableEditFieldList = ""
cTableRecordFieldList = ""
cTableSortColumn = ""
lAllowAdd = .T.
lAllowDelete = .T.


*** Save Old Alias if we're dropping a table onto the class
cOldAlias=""
cNewAlias=""

*** Stock Properties

************************************************************************
* ShowCursor :: Init
*********************************
***  Function: Decides whether to use internal HTML object or one passed
***            from the outside. Sets up the fields of the table
************************************************************************
FUNCTION Init
LPARAMETER loHTML

IF VARTYPE(loHTML)#"O"
  THIS.oHTML=CREATE([WWC_RESPONSESTRING])
ELSE
  THIS.oHTML=loHTML  
ENDIF

*** Grab all the fields of the current cursor
THIS.nFieldCount=AFIELDS(THIS.aFieldList)
  
ENDFUNC
* Init


************************************************************************
* ShowCursor :: SetCursor
*********************************
***  Function: Use this method to set a DBF or cursor other than the
***            currently selected Alias
***      Pass: lcDBF   -    Pass name of DBF or ALIAS
************************************************************************
FUNCTION SetCursor
LPARAMETERS lcDBF

lcDBF=IIF(type("lcDBF")="C",lcDBF,"")

lcStem=juststem(lcDBF)
IF !USED(lcStem)			
   THIS.cOldAlias=ALIAS()
   USE (lcDBF) IN 0
ENDIF

SELE (lcStem)

ENDFUNC
* SetCursor

************************************************************************
* ShowCursor :: Destroy
*********************************
***  Function: Cleans up the open table if one was opened explicitly
************************************************************************
FUNCTION Destroy

IF !EMPTY(THIS.cOldAlias) AND USED(THIS.cOldAlias)
  USE IN (THIS.cNewAlias)
  IF !EMPTY(THIS.cOldAlias)
    SELE (THIS.cOldAlias)
  ENDIF
  THIS.cOldAlias=""
  THIS.cNewAlias=""
ENDIF  
   
ENDFUNC
* Destroy

************************************************************************
* ShowCursor :: BuildFieldListHeader
************************************
***  Function: Builds up the array of headers
***      Pass:
***    Return:
************************************************************************
FUNCTION BuildFieldListHeader
LPARAMETER lvHeader, llPreList
LOCAL lcHeader,lnX
lcheader=""

*** Just return if the string is already filled
IF !EMPTY(THIS.cHeaderString)
   RETURN
ENDIF   

IF this.lSortable AND EMPTY(this.cBaseUrl)
   this.cBaseUrl = Request.GetCurrentUrl() + "&"
ENDIF

IF !llPreList
	IF TYPE("lvHeader[1]")#"U"
	      lcheader=""
	      THIS.nFieldCount=ALEN(lvheader,1)
	      FOR lnX=1 TO THIS.nFieldCount
	         lcheader=lcheader+[<TH><font FACE="] + THIS.cHeaderFont + ;
                            [" color="]+ THIS.cHeaderColor + [">] +lvheader[lnX]+[</font></TH>]
	      ENDFOR && lnX=1 TO ALEN(lvType,1)
	ELSE
	   *** Otherwise fill it with the field names
		   
		*** No Array Passed Use Field Headers
		FOR lnX=1 TO THIS.nFieldCount
         *** Fix Memo Length
         IF THIS.aFieldList[lnX,2]="M"
            THIS.aFieldList[lnX,3]=THIS.nMemowidth
         ENDIF
         
         *** Fix Time Data Length
         IF THIS.aFieldList[lnX,2]="T"
            THIS.aFieldList[lnX,3]=20
         ENDIF
         
         *** Fix Integers
         IF THIS.aFieldList[lnX,2]="I"
            THIS.aFieldList[lnX,3]=9
         ENDIF
      	 IF THIS.lSortable AND THIS.aFieldList[lnX,2] $ "CNILDTY"
      	 	 lcFieldName = PROPER(CHRTRAN(THIS.afieldlist[lnX,1],"_"," ")) + " " +;
	                        [<a href="] + this.cBaseUrl + [Sorted=] + TRANSFORM(lnX) +[" ] +;
	         				[style="color:]+this.cHeaderColor+[;font-size:10pt;font-family:Verdana;text-decoration:none" title="Sort Ascending">] + ;
	         				CHR(171) +"</a> "  + ;
	                        [<a href="] + this.cBaseUrl + [Sorted=] + TRANSFORM(lnX) +[&SortDescending=True" ] +;
	         				[style="color:]+this.cHeaderColor+[;font-size:10pt;font-family:Verdana;text-decoration:none" title="Sort Descending">] + ;
	         				 CHR(187) + "</a> "  + CRLF
         ELSE
    	     lcFieldName =  PROPER(CHRTRAN(THIS.afieldlist[lnX,1],"_"," "))		
         ENDIF
         lcheader=lcheader+[<TH style="font-family:] + THIS.cHeaderFont + ;
 		                     [;color:]+ THIS.cHeaderColor + [">] + ;
							 lcFieldName+[</TH>]
		ENDFOR && lnX=1 TO ALEN(lvType,1)
	ENDIF	

	THIS.cHeaderString=[<TR BGCOLOR="]+THIS.cHeaderBGColor+[">]+lcheader+[</TR>]
ELSE
   IF TYPE("lvHeader[1]")="U"
      *** No Array Passed Use Field Headers
      lcheader=""
      FOR lnX=1 TO lnfields
         *** If header is longer than field widen the display
         IF LEN(TRIM(THIS.aFieldList[lnX,1]))>THIS.aFieldList[lnX,3]
            THIS.aFieldList[lnX,3]=LEN(TRIM(THIS.aFieldList[lnX,1]))
         ENDIF

         *** Fix Memo Length
         IF THIS.aFieldList[lnX,2]="M"
            THIS.aFieldList[lnX,3]=THIS.nMemoWidth
         ENDIF
         
         *** Fix Time Data Length
         IF THIS.aFieldList[lnX,2]="T"
            THIS.aFieldList[lnX,3]=20
         ENDIF
         
         *** Fix Integer Length
         IF THIS.aFieldList[lnX,2]="I"
            THIS.aFieldList[lnX,3]=9
         ENDIF
         
         IF THIS.aFieldList[lnX,2] $ "NFBIY"
            lcheader=lcheader+"<b>"+PADC(THIS.aFieldList[lnX,1],THIS.aFieldList[lnX,3])+"</b>   "
         ELSE
            lcheader=lcheader+"<b>"+PADC(THIS.aFieldList[lnX,1],THIS.aFieldList[lnX,3])+"</b>   "
         ENDIF
      ENDFOR && lnX=1 TO ALEN(lvType,1)
   ELSE
      *** Array of headers was passed
      lcheader=""
      FOR lnX=1 TO ALEN(lvheader,1)
         IF LEN(TRIM(lvheader[lnX]))>THIS.aFieldList[lnX,3]
            THIS.aFieldList[lnX,3]=LEN(TRIM(THIS.aFieldList[lnX,1]))
         ENDIF

         *** Fix Memo Length
         IF THIS.aFieldList[lnX,2]="M"
            THIS.aFieldList[lnX,3]=20
         ENDIF
         
         *** Fix Time Data Length
         IF THIS.aFieldList[lnX,2]="T"
            THIS.aFieldList[lnX,3]=20
         ENDIF
         
         *** Check for header width override
         lnSizeLoc=ATC(":",lvHeader[lnX])
         IF lnSizeLoc>0
            lnSize=VAL(SUBSTR(ALLTRIM(lvHeader[lnX]),lnSizeLoc+1))
            lvHeader[lnX]=SUBSTR(lvHeader[lnX],1,lnSizeLoc-1)
         ELSE
            lnSize=THIS.aFieldList[lnX,3]
         ENDIF
         

        IF THIS.aFieldList[lnX,2] $ "NFBIY"
            lcheader=lcheader+"<b>"+PADC(lvheader[lnX],lnSize)+"</b>   "
         ELSE
            lcheader=lcheader+"<b>"+PADC(lvheader[lnX],lnSize)+"</b>   "
         ENDIF
      ENDFOR && lnX=1 TO ALEN(lvType,1)
   ENDIF
   THIS.cHeaderString=lcHeader
ENDIF
  
ENDFUNC
* BuildHeaders



************************************************************************
* ShowCurosr :: ShowCursor
*********************************
***  Function: Displays the currently selected table.
***            300 recs and less display HTML 3.0 table,
***            otherwise PRE formatted list is displayed.
***      Pass: lvHeader   -    1D Array: Column Headers for each col
***                            Pass by reference!!! 
***             lcTitle   -    Table Header (only works with Tables)
***        llSumNumbers   -    Auto sum all numeric fields in table
***    Return: .T. or .F.
************************************************************************
FUNCTION ShowCursor
LOCAL lcheader, lnX, latotals, lcOutput, lnSizeLoc, lnSize, lvValue

IF EMPTY(ALIAS())
   RETURN ""
ENDIF

IF THIS.lSortable
   lnSort = VAL( Request.QueryString("Sorted") )
   IF lnSort > 0
      THIS.cTableSortColumn = TRANSFORM(lnSort)
      IF !EMPTY(Request.QueryString("SortDescending"))
	     THIS.cTableSortColumn = THIS.cTableSortColumn +" DESCENDING"
	  ENDIF
   ENDIF
ENDIF   

IF !EMPTY(THIS.cTableFieldList)
    lcFields = THIS.cTableFieldList
    lcOrder = IIF(!EMPTY(THIS.cTableSortColumn),"ORDER BY " + THIS.cTableSortColumn,"")
    SELECT &lcFields ;
        FROM Alias() ;
        &lcOrder ;
        INTO Cursor __TQuery 
    THIS.nFieldCount=AFIELDS(THIS.aFieldList)
ELSE
    IF !EMPTY(this.cTableSortColumn)
	    lcOrder = IIF(!EMPTY(THIS.cTableSortColumn),"ORDER BY " + THIS.cTableSortColumn,"")
	    SELECT * ;
	        FROM ( Alias() ) ;
	        &lcOrder ;
	        INTO Cursor __TQuery 
    ENDIF
ENDIF
     
lcOutput=""
lnfields=THIS.nFieldCount
lnreccount=RECCOUNT()

IF THIS.nPage_ItemsPerPage # 0  
   THIS.PageFilter()
   lnreccount=RECCOUNT()
ENDIF   

*** Keep track of numeric totals
IF THIS.lsumnumerics
   DIMENSION latotals[1,lnFields]
   latotals=0
ENDIF

IF THIS.lShowAsTable  AND lnReccount*lnFields <= THIS.nForceToPREList + 1 
   *** SHOW HTML TABLE
   
   IF !EMPTY(THIS.cTableTitle)
      lctitle=[<TR><TH COLSPAN=]+ALLTRIM(STR(lnfields))+[ ALIGN="CENTER"><H2>]+THIS.cTableTitle+[</H2></TH></TR>]
   ELSE
      lcTitle=""
   ENDIF

   IF this.lCenterTable
      this.oHtml.Write("<CENTER>" + CRLF)
   ENDIF
   
   THIS.oHTML.Write([<TABLE ] + ;
                   [ BGCOLOR="]+THIS.cTableBGColor+[" CELLPADDING="]+THIS.cCellPadding+;
                   [" CELLSPACING="]+THIS.cCellSpacing+[" BORDER="]+THIS.cTableBorder + [" ]+;
                   IIF(!EMPTY(THIS.cTableWidth),[ WIDTH="] + THIS.cTableWidth + ["],"") + [ ] +;
                   THIS.cExtraTableTags + [>]+crlf + IIF(!EMPTY(lcTitle),lctitle+ CRLF,""))

   THIS.BuildFieldListHeader()
   
   THIS.oHTML.Write(THIS.cHeaderString)

   llAlternate = .T.   
  
   *** Now loop through table
   SCAN
      *** Build a Field String
      lcrow=""

      FOR lnX=1 TO lnfields
         lcfieldname=THIS.afieldList[lnX,1]
         lcfieldtype=THIS.afieldList[lnX,2]
         
         *** ???ras - unresolved 01/17/97
         ***          Add Cell based formatting
                      
         lvValue=EVAL(lcfieldname)

         DO CASE
         CASE ISNULL(lvValue)
            lcrow=lcrow+"<TD>n/a</TD>"
         CASE lcfieldtype="C" OR lcFieldType = "V"
            *lcrow=lcrow+"<TD>"+IIF(EMPTY( EVAL(lcfieldname) ),"<BR>",ALLTRIM( EVAL(lcfieldname) ))+"</TD>"
            lcrow=lcrow+"<TD>"+IIF( EMPTY(lvValue),"&nbsp;",TRIM( lvValue) )+"</TD>"
         CASE lcFieldType="M"
            lcrow=lcrow+"<TD >"+IIF( EMPTY(lvValue),"<BR>",DisplayMemo(lvValue))+"</TD>"
         CASE lcfieldtype $ "I" OR lcFieldType = "Y"
            lcrow=lcrow+[<TD align="right">]+TRANSFORM(lvValue)+[</TD>]
            IF THIS.lSumNumerics
               latotals[1,lnX]=latotals[1,lnX]+lvValue
            ENDIF
         CASE lcfieldtype $ "NFB"
            lcrow=lcrow+[<TD ALIGN=RIGHT>]+LTRIM(STR(lvValue,THIS.aFieldList[lnX,3],THIS.aFieldList[lnX,4]))+[</TD>]
            IF THIS.lSumNumerics
               latotals[1,lnX]=latotals[1,lnX]+lvValue
            ENDIF
         CASE lcfieldtype="L"
            lcrow=lcrow+[<TD ALIGN=CENTER>]+IIF(lvValue,"True","False")+[</TD>]
         CASE lcfieldtype="D"
            lcrow=lcrow+[<TD ALIGN=CENTER>]+IIF(EMPTY(lvValue),"<BR>",DTOC(lvValue))+[</TD>]
         CASE lcfieldtype="T"
            lcrow=lcrow+[<TD ALIGN=CENTER>]+IIF(EMPTY(lvValue),"<BR>",lower(ttoc(lvValue)))+[</TD>]
         ENDCASE

      ENDFOR && lnX=1 TO lnFields

      IF THIS.lAlternateRows and llAlternate
         lcrow=[<TR style="background:] + THIS.cAlternatingBGColor + [" VALIGN=TOP>]+lcrow+"</TR>"
      ELSE
         lcrow=[<TR VALIGN=TOP>]+lcrow+"</TR>"
      ENDIF
      
      llAlternate = !llAlternate
            
      THIS.oHTML.Write(lcrow+CRLF)
   ENDSCAN

   *** Print Totals for numeric fields
   IF THIS.lsumnumerics
      lcrow=""
      FOR lnX=1 TO lnfields
         lcfieldname=THIS.aFieldList[lnX,1]
         lcfieldtype=THIS.aFieldList[lnX,2]

         IF lcfieldtype $ "NFBIY"
            lntotal=latotals[1,lnX]
            lcrow=lcrow+[<TD ALIGN=RIGHT><font color="]+THIS.cHeaderColor+["><B>]+;
                        IIF(lcFieldType="Y",;
                            TRANSFORM(lnTotal),;
                            STR(lntotal,THIS.aFieldList[lnX,3]+1,THIS.aFieldList[lnX,4]))+;
                        [</b></font></TD>]
         ELSE
            lcrow=lcrow+"<TD></TD>"
         ENDIF
      ENDFOR

      THIS.oHTML.Write([<TR BGCOLOR="]+THIS.cHeaderBGColor+[" style="font-face:bold">]+lcrow+[</TR>]+CRLF)
   ENDIF

   *** Write out next/prev if available
   IF THIS.nPage_ItemsPerPage # 0 
      IF USED("_TXQuery")
         USE IN _TXQuery
      ENDIF
      IF USED(THIS.cPage_OldALias)
         SELE (THIS.cPage_OldAlias)
      ENDIF   
      
      
      *** Add the links to the bottom of the page
      IF !EMPTY(THIS.cPage_LinkHTML)
        THIS.oHTML.FastWrite([<tr bgcolor="] + THIS.cHeaderBGColor + ["><td align="right" colspan="] +TRANSFORM(lnFields)+ [">] +;
                             [<font color="]+ THIS.cHeaderColor + [">]   +;
                             THIS.cPage_LinkHTML + [</font></td></tr>])   
      ENDIF
   ENDIF    


   THIS.oHTML.Write("</TABLE>"+IIF(THIS.lCenterTable,[</CENTER>],[])+CRLF)
   *** End HTML Table
ELSE
   *** SHOW <PRE> LIST
   
   THIS.oHTML.Write([<PRE>]+CRLF+IIF(THIS.lCenterTable,[<CENTER>]+CRLF,[]))

   IF !EMPTY(THIS.cTableTitle)
      lctitle=[<H2>]+THIS.cTableTitle+[</H2>]
   ELSE
      lcTitle=""
   ENDIF

   THIS.cHeaderString=""
   THIS.BuildFieldListHeader(,.T.)
   
   THIS.oHTML.FastWrite(THIS.cHeaderString+CRLF)

   *** Now loop through table
   SCAN
      *** Build a Field String
      lcrow=""

      FOR lnX=1 TO lnfields
         lcfieldname=THIS.afieldList[lnX,1]
         lcfieldtype=THIS.afieldList[lnX,2]
         
         *** ???ras - unresolved 01/17/97
         ***          Add Cell based formatting
         lvValue=EVAL(lcfieldname)

         DO CASE
         CASE ISNULL(lvValue)
            lcrow=lcrow+PADC("n/a",THIS.aFieldList[lnX,3])
         CASE lcfieldtype="C" OR lcFieldType="V"
            lcrow=lcrow+PADR(lvValue, THIS.aFieldList[lnX,3]) 
         CASE lcfieldtype="M" 
            lcrow=lcrow+PADR(MLINE(lvValue,1), 25) 
         CASE lcfieldtype $ "NFBIY"
            lcrow=lcrow+ STR(lvValue,THIS.aFieldList[lnX,3],THIS.aFieldList[lnX,4])
            IF THIS.lSumNumerics
               latotals[1,lnX]=latotals[1,lnX]+lvValue
            ENDIF
         CASE lcfieldtype="L"
            lcrow=lcrow+ PADR(IIF(lvValue,"True ","False"),THIS.aFieldList[lnX,3])
         CASE lcfieldtype="D"
            lcrow=lcrow+DTOC(lvValue)
         CASE lcfieldtype="T"
            lcrow=lcrow+ttoc(lvValue)
         ENDCASE
         *** Separator 2 spaces
         lcRow=lcRow + " | "

      ENDFOR && lnX=1 TO lnFields

      THIS.oHTML.FastWrite(lcrow+CRLF)
   ENDSCAN

   *** Print Totals for numeric fields
   IF THIS.lsumnumerics
      lcrow=""
      FOR lnX=1 TO lnfields
         lcfieldname=THIS.aFieldList[lnX,1]
         lcfieldtype=THIS.aFieldList[lnX,2]

         IF lcfieldtype $ "NFBIY"
            lntotal=latotals[1,lnX]
            lcrow=lcrow+STR(lntotal,THIS.aFieldList[lnX,3],THIS.aFieldList[lnX,4]) +"   "
         ELSE
            lcrow=lcrow+SPACE(THIS.aFieldList[lnX,3] + 3)
         ENDIF
      ENDFOR

      THIS.oHTML.FastWrite([<b>]+lcrow+[</b>])
   ENDIF

   THIS.oHTML.FastWrite(IIF(THIS.lCenterTable,[</CENTER>]+CRLF,[])+"</PRE>")
ENDIF


IF !EMPTY(THIS.cTableFieldList)
   IF USED("__TQuery")
      USE IN __TQUery
   ENDIF
ENDIF
   
RETURN
* ShowTable




FUNCTION ShowASCIIRecord
************************************************************************
* ShowCursor :: DisplayASCIIRecord
***********************************
***  Function: Show all fields in an ASCII list format. If used on a 
***            Web page use the <PRE> tag to force to formatted text.
************************************************************************
LOCAL lnX, lcFieldCaption, lnFieldCount, lcfieldtype, lcfieldname

lcOutput=""
lcFieldCaption=""


IF !EMPTY(DBC()) AND ;
    INDBC(ALIAS() + '.' + THIS.aFieldList[1,1], 'Field') AND ;
    TYPE(ALIAS() + "." + THIS.aFieldList[1,1]) # "U"
   for lnX=1 to THIS.nFieldCount
      lcFieldCaption=Proper(PADL(dbgetprop(ALIAS()+"."+THIS.aFieldList[lnX,1],"FIELD","Caption"),25))+": "
      THIS.aFieldList[lnX,11]=lcFieldCaption
   endfor
ELSE   
   for lnX=1 to THIS.nFieldCount
      THIS.aFieldList[lnX,11]=PADL(Proper(THIS.aFieldList[lnX,1]),THIS.nASCIILeftColumns)+": "
   endfor
ENDIF

*** Just loop through fields and display
FOR lnX=1 to THIS.nFieldCount
         lcfieldname=THIS.afieldList[lnX,1]
         lcfieldtype=THIS.afieldList[lnX,2]
         lcfieldcaption=THIS.afieldList[lnX,11]  && overridden UpdateTrigger
         
         lvValue=EVAL(lcfieldname)
            
         lcRow=lcFieldCaption
 
         DO CASE
         CASE ISNULL(lvValue)
            lcrow=lcrow+"n/a"
         CASE lcfieldtype="C" OR lcFieldType = "V"
            lcrow=lcRow+trim(lvValue)
         CASE lcfieldtype="M"
            lcrow=lcrow+THIS.oHTML.WriteMemo(TRIM(lvValue),.T.)
         CASE lcfieldtype $ "NFBIY"
            lcrow=lcrow+LTRIM(STR(lvValue,THIS.aFieldList[lnX,3],THIS.aFieldList[lnX,4]))
         CASE lcfieldtype="L"
            lcrow=lcrow+IIF(lvValue,"True","False")
         CASE lcfieldtype="D"
            lcrow=lcrow+DTOC(lvValue)
         CASE lcfieldtype="T"
            lcrow=lcrow+ttoc(lvValue)
         ENDCASE
         
         THIS.oHTML.Write(lcRow+CRLF)
ENDFOR && lnX=1 to lnFieldCount

ENDFUNC
* DisplayRecordASCII

FUNCTION ShowRecord
************************************************************************
* ShowCursor :: ShowRecord
***********************************
***  Function: Show all fields in an ASCII list format. If used on a 
***            Web page use the <PRE> tag to force to formatted text.
************************************************************************
LOCAL lnX, lcFieldCaption, lnFieldCount, lcfieldtype, lcfieldname

lcOutput=""
lcFieldCaption=""

lcFieldlist = THIS.cTableRecordFieldList

*** Filter the field list
IF !EMPTY(lcFieldList)
    lcFields = lcFieldList  
    lnRecno = RECNO()
    SELECT &lcFields ;
        FROM Alias() ;
        WHERE RECNO() = lnRecno ;
        INTO Cursor __TQuery
    THIS.nFieldCount=AFIELDS(THIS.aFieldList)
ENDIF

THIS.oHTML.Write(IIF(THIS.lCenterTable,[<center>]+CRLF,[]) + ;
                   [<table style="background-color: ] + THIS.cTableBGColor+[; border: ] + this.cTableBorder + [;width: ] + this.cTableWidth + [;" ] + ;
                   [ cellpadding="] + THIS.cCellPadding + [" cellspacing="] + THIS.cCellSpacing + [" ] +;
                   THIS.cExtraTableTags + [>])

IF !EMPTY(DBC()) AND ;
   INDBC(ALIAS() + '.' + THIS.aFieldList[1,1], 'Field') AND ;
   TYPE(ALIAS() + "." + THIS.aFieldList[1,1]) # "U"
   for lnX=1 to THIS.nFieldCount
      lcCaption= dbgetprop(ALIAS()+"."+THIS.aFieldList[lnX,1],"FIELD","Caption")
      lcCaption = IIF(!EMPTY(lcCaption),lcCaption,Proper(THIS.aFieldList[lnX,1]))
      lcCaption = Proper(STRTRAN(lcCaption,"_"," "))

      lcFieldCaption=[<tr><td style="vertical-align: top; background-color: ]+THIS.cHeaderBGColor+[; color: ] + this.cHeaderColor +  [ " ><b>]+ ;
                     lcCaption+":"+ [</b></td>] +CRLF
      THIS.aFieldList[lnX,11]=lcFieldCaption
   endfor
ELSE   
   for lnX=1 to THIS.nFieldCount
      THIS.aFieldList[lnX,11]=[<TR><TD VALIGN=TOP BGCOLOR=]+THIS.cHeaderBGColor+[><b><font color="] +THIS.cHeaderColor + [">]+ ;
                     Proper(STRTRAN(THIS.aFieldList[lnX,1],"_"," "))+ [</font></b></TD>]
   endfor
ENDIF

*** Just loop through fields and display
FOR lnX=1 to THIS.nFieldCount
         lcfieldname=THIS.afieldList[lnX,1]
         lcfieldtype=THIS.afieldList[lnX,2]
         lcfieldcaption=THIS.afieldList[lnX,11]  && overridden UpdateTrigger
         
         lvValue=EVAL(lcfieldname)
            
         lcRow=lcFieldCaption 
 
         DO CASE
         CASE ISNULL(lvValue)
            lcrow=lcrow+"<TD>n/a</TD>"
         CASE lcfieldtype="C" OR lcfieldtype="M" OR lcFieldType="V"
            *lcrow=lcrow+"<TD>"+IIF(EMPTY( EVAL(lcfieldname) ),"<BR>",ALLTRIM( EVAL(lcfieldname) ))+"</TD>"
            lcrow=lcrow+"<TD>"+IIF( EMPTY(lvValue),"<BR>",DisplayMemo(lvValue))+"</TD>"
         CASE lcfieldtype $ "NFB"
            lcrow=lcrow+[<TD>]+LTRIM(STR(lvValue,THIS.aFieldList[lnX,3],THIS.aFieldList[lnX,4]))+[</TD>]
         CASE lcFieldType $ "IY"
            lcrow=lcrow+[<TD>]+TRANSFORM(lvValue)+[</TD>]
         CASE lcfieldtype="L"
            lcrow=lcrow+[<TD>]+IIF(lvValue,"True","False")+[</TD>]
         CASE lcfieldtype="D"
            lcrow=lcrow+[<TD>]+IIF(EMPTY(lvValue),"<BR>",DTOC(lvValue))+[</TD>]
         CASE lcfieldtype="T"
            lcrow=lcrow+[<TD>]+IIF(EMPTY(lvValue),"<BR>",ttoc(lvValue))+[</TD>]
         ENDCASE
         
         THIS.oHTML.Write(lcRow+ "</TR>" + CRLF)
ENDFOR && lnX=1 to lnFieldCount

THIS.oHTML.Write("</TABLE>"+ CRLF + IIF(THIS.lCenterTable,[</CENTER>]+CRLF,""))

ENDFUNC
* ShowRecord

FUNCTION ShowObject
************************************************************************
* ShowCursor :: ShowRecord
***********************************
***  Function: Show all fields in an ASCII list format. If used on a
***            Web page use the <PRE> tag to force to formatted text.
************************************************************************
LPARAMETERS loObject
LOCAL lnX, lcFieldCaption, lnFieldCount, lcfieldtype, lcfieldname, lcRow

lcOutput=""

THIS.oHTML.WRITE(IIF(THIS.lCenterTable,[<CENTER>]+CRLF,[])+;
    [<TABLE BGCOLOR="]+THIS.cTableBGColor+[" CELLPADDING=]+THIS.cCellPadding+;
    [ CELLSPACING=]+THIS.cCellSpacing+[ BORDER=]+THIS.cTableBorder + [ WIDTH=] + ;
    THIS.cTableWidth + [ ] +;
    THIS.cExtraTableTags + [>])

lnFieldCount = AMEMBERS(laFields,loObject)


FOR lnX = 1 TO lnFieldCount
    lcField = laFields[lnX]

    *** Create the header item
    lcRow = ;
        [<TR><TD VALIGN=TOP BGCOLOR=]+THIS.cHeaderBGColor+[><b><font color="] +THIS.cHeaderColor + [">]+ ;
        PROPER(lcField) +":"+ [</font></b></TD>]

    lvValue = EVALUATE("loObject." + lcField)
    lcType = VARTYPE(lvValue)

    DO CASE
            *** Create the actual data item
        CASE ISNULL(lvValue)
            lcValue = "null"
        CASE lcType = "C" OR lcFieldType = "V"
            IF EMPTY(lvValue)
                lcValue = "&nbsp;"
            ELSE
                lcValue = DisplayMemo(lvValue)
            ENDIF
        CASE lcType = "D"
            lcValue = TRANSFORM(lvValue)
        CASE lcType = "T"
            lcValue = TimeToC(lvValue)
        CASE lcType = "L"
            lcValue = IIF(lvValue,"True","False")
        CASE lcType = "O"
            lcValue = "Object"
        CASE lcType = "U"
            lcValue = "Undefined"
        OTHERWISE
            lcValue = TRANSFORM(lvValue)
    ENDCASE

    THIS.oHTML.WRITE(lcRow + "<td>" + lcValue + "</td></tr>"+CRLF)
ENDFOR


THIS.oHTML.WRITE(IIF(THIS.lCenterTable,[</CENTER>]+CRLF,"")+ "</TABLE>"+CRLF)

ENDFUNC
* ShowObject


FUNCTION EditRecord
************************************************************************
* ShowCursor :: EditRecord
***********************************
***  Function: Show all fields as edit fields. The names of the edit
***            field is the name of the actual table field.
************************************************************************
LPARAMETERS lnDisplayMode,lcObjectName 
LOCAL lnX, lcFieldCaption, lnFieldCount, lcfieldtype, lcfieldname, lcKeyValue

IF EMPTY(lnDIsplayMode)
   lnDisplayMode = 0
ENDIF
IF EMPTY(lcObjectName)
   lcObjectName = ALIAS()
ENDIF

lcOutput=""
lcFieldCaption=""

lcFieldList = THIS.cTableEditFieldList

*** We have to make sure we embed the PK as a hidden var
IF !EMPTY(THIS.cKeyField)
   lcKeyValue = EVALUATE(THIS.cKeyField)
ELSE
   lcKeyValue = ""   
ENDIF

*** Filter the field list
IF !EMPTY   (lcFieldList)
    lcFields = lcFieldList  
    lnRecno = RECNO()
    SELECT &lcFields ;
        FROM Alias() ;
        WHERE RECNO() = lnRecno ;
        INTO Cursor __TQuery
    THIS.nFieldCount=AFIELDS(THIS.aFieldList)
ENDIF

THIS.oHTML.Write(IIF(THIS.lCenterTable,[<CENTER>]+CRLF,[])+;
                   [<TABLE BGCOLOR="]+THIS.cTableBGColor+[" CELLPADDING=]+THIS.cCellPadding+;
                   [ CELLSPACING=]+THIS.cCellSpacing+[ BORDER=]+THIS.cTableBorder + [ WIDTH=] + ;
                   THIS.cTableWidth + [ ] +;
                   THIS.cExtraTableTags + [>] + CRLF)

IF !EMPTY(DBC()) AND ;
   INDBC(ALIAS() + '.' + THIS.aFieldList[1,1], 'Field') AND ;
   TYPE(ALIAS() + "." + THIS.aFieldList[1,1]) # "U"
   for lnX=1 to THIS.nFieldCount
      lcCaption= dbgetprop(ALIAS()+"."+THIS.aFieldList[lnX,1],"FIELD","Caption")
      lcCaption = IIF(!EMPTY(lcCaption),lcCaption,Proper(THIS.aFieldList[lnX,1]))
      lcCaption = Proper(STRTRAN(lcCaption,"_"," "))

      lcFieldCaption=[<TR><TD  VALIGN=TOP BGCOLOR="]+THIS.cHeaderBGColor+["><b><font color="] +THIS.cHeaderColor + [">]+ ;
                     +lcCaption+":"+ [</font></b></TD>] +CRLF
      THIS.aFieldList[lnX,11]=lcFieldCaption
   endfor
ELSE   
   FOR lnX=1 to THIS.nFieldCount
      THIS.aFieldList[lnX,11]=[<TR><TD VALIGN=TOP BGCOLOR="]+THIS.cHeaderBGColor+["><b><font color="] +THIS.cHeaderColor + [">]+ ;
                            Proper(STRTRAN(THIS.aFieldList[lnX,1],"_"," "))+ [</font></b></TD>] +CRLF
   ENDFOR
ENDIF

*** Just loop through fields and display
FOR lnX=1 to THIS.nFieldCount
	 lcfieldname=PROPER(THIS.afieldList[lnX,1])
	 lcfieldtype=THIS.afieldList[lnX,2]
	 lnFieldWidth=THIS.aFieldList[lnX,3]
	 lcfieldcaption=THIS.afieldList[lnX,11]  && overridden UpdateTrigger
	 
    IF lcFieldType # "G"
	    lvValue=EVAL(lcfieldname)
    ENDIF
    	    
	 lcRow=lcFieldCaption 
	 
    DO CASE
    CASE lnDisplayMode = 0
   	 DO CASE
   	 CASE lcfieldtype="C" OR lcFieldType="V" 
   	    lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" style="width:400px" value="] + lvValue + ["></td>]
   	 CASE lcfieldtype="M"
   	    *lcrow=lcrow+"<TD>"+IIF(EMPTY( EVAL(lcfieldname) ),"<BR>",ALLTRIM( EVAL(lcfieldname) ))+"</TD>"
   	    lcrow=lcrow+[<TD><textArea wrap=virtual style="width:400px;height:100px" name="]+ lcFieldName +[">]+lvValue+[</textarea></TD>]
   	 CASE lcfieldtype $ "NFBIY"
   	    lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=] + TRANS(lnFieldWidth + 1) + [ value="] + TRANS(lvValue) + ["></td>]
   	 CASE lcfieldtype="L"
   	    lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=1 value="] + IIF(lvValue,"T","F") + ["></td>]
   	 CASE lcfieldtype="D"
   	    lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=10 value="] + TRANS(lvValue) + ["></td>]
   	 CASE lcfieldtype="T"
   	    lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=15 value="] + lower(TRANS(lvValue)) + ["></td>]
   	 OTHERWISE
          lcRow = lcRow + "<td></td>"
     ENDCASE
       
    CASE lnDisplayMode = 2
       DO CASE
       CASE lcfieldtype="C" OR lcFieldType="V" 
          lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=] + TRANS(lnFieldWidth) + [ value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="M"
          *lcrow=lcrow+"<TD>"+IIF(EMPTY( EVAL(lcfieldname) ),"<BR>",ALLTRIM( EVAL(lcfieldname) ))+"</TD>"
          lcrow=lcrow+[<TD><textArea wrap=virtual cols=55 rows=5 name="txt]+ lcFieldName +["><%= ] + lcObjectName + "." + lcFieldName + [%></textarea></TD>]
       CASE lcfieldtype $ "NFBIY"
          lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=] + TRANS(lnFieldWidth + 1) + [ value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="L"
          lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=1 value="<%= iif( ] + lcObjectName + "." + lcFieldName + [,'T','F') %>"></td>]
       CASE lcfieldtype="D"
          lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=10 value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="T"
          lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=15 value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       OTHERWISE
          lcRow = lcRow + "<td></td>"
       ENDCASE
    CASE lnDisplayMode = 4
       DO CASE
       CASE lcfieldtype="C" OR lcFieldType="V"
          lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=] + TRANS(lnFieldWidth) + [ value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="M"
          *lcrow=lcrow+"<TD>"+IIF(EMPTY( EVAL(lcfieldname) ),"<BR>",ALLTRIM( EVAL(lcfieldname) ))+"</TD>"
          lcrow=lcrow+[<TD><textArea wrap=virtual cols=55 rows=5 name="txt]+ lcFieldName +["><%= ] + lcObjectName + "." + lcFieldName + [%></textarea></TD>]
       CASE lcfieldtype $ "NFBIY"
          lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=] + TRANS(lnFieldWidth + 1) + [ value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="L"
          lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=1 value="<%= iif( ] + lcObjectName + "." + lcFieldName + [,'T','F') %>"></td>]
       CASE lcfieldtype="D"
          lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=10 value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="T"
          lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=15 value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       OTHERWISE
          lcRow = lcRow + "<td></td>"
       ENDCASE
       
    ENDCASE
    
	 THIS.oHTML.Write(lcRow + "</tr>" + CRLF)
ENDFOR && lnX=1 to lnFieldCount

*** Make sure the PK is embedded in here
IF !EMPTY(lcKeyValue)
   THIS.oHTML.Write([<input type="hidden" name="] + THIS.cKeyField + [" value="] + ;
                    TRANSFORM(lcKeyValue) + [">])
ENDIF

THIS.oHTML.Write( "</TABLE>" + IIF(THIS.lCenterTable,[</CENTER>]+CRLF,"") + CRLF)

ENDFUNC
* EditRecord

FUNCTION EditRecordWebForm
************************************************************************
* ShowCursor :: EditRecordWebForm
***********************************
***  Function: Show all fields as edit fields. The names of the edit
***            field is the name of the actual table field.
************************************************************************
LPARAMETERS lcObjectName, lcRowHeaderClass, lcTableClass
LOCAL lnX, lcFieldCaption, lnFieldCount, lcfieldtype, lcfieldname, lcKeyValue

IF EMPTY(lcObjectName)
   lcObjectName = ALIAS()
ENDIF
IF EMPTY(lcRowHeaderClass)
   lcRowHeaderClass = ""
ENDIF   
IF EMPTY(lcTableClass)
	lcTableClass = ""
ENDIF

lcOutput=""
lcFieldCaption=""

lcFieldList = THIS.cTableEditFieldList

*** We have to make sure we embed the PK as a hidden var
IF !EMPTY(THIS.cKeyField)
   lcKeyValue = EVALUATE(THIS.cKeyField)
ELSE
   lcKeyValue = ""   
ENDIF

*** Filter the field list
IF !EMPTY   (lcFieldList)
    lcFields = lcFieldList  
    lnRecno = RECNO()
    SELECT &lcFields ;
        FROM Alias() ;
        WHERE RECNO() = lnRecno ;
        INTO Cursor __TQuery
    THIS.nFieldCount=AFIELDS(THIS.aFieldList)
ENDIF

THIS.oHTML.Write(IIF(THIS.lCenterTable,[<center>]+CRLF,[])+;
                   [<table cellpadding="]+THIS.cCellPadding+;
                   ["  class="] + lcTableClass + [" ] +;
                   THIS.cExtraTableTags + [>] + CRLF)

IF !EMPTY(DBC()) AND ;
   INDBC(ALIAS() + '.' + THIS.aFieldList[1,1], 'Field') AND ;
   TYPE(ALIAS() + "." + THIS.aFieldList[1,1]) # "U"
   for lnX=1 to THIS.nFieldCount
      lcCaption= dbgetprop(ALIAS()+"."+THIS.aFieldList[lnX,1],"FIELD","Caption")
      lcCaption = IIF(!EMPTY(lcCaption),lcCaption,Proper(THIS.aFieldList[lnX,1]))
      lcCaption = Proper(STRTRAN(lcCaption,"_"," "))

      lcFieldCaption=[<tr><td BGCOLOR="]+THIS.cHeaderBGColor+["><b><font color="] +THIS.cHeaderColor + [">]+ ;
                     +lcCaption+":"+ [</font></b></TD>] +CRLF
      THIS.aFieldList[lnX,11]=lcFieldCaption
   endfor
ELSE   
   FOR lnX=1 to THIS.nFieldCount
      THIS.aFieldList[lnX,11]=[<tr>] + CRLF + CHR(9) + [<td ] + IIF(!EMPTY(lcRowHeaderClass),[class="] + lcRowHeaderClass + ["],[]) + [>]+ ;
                            Proper(STRTRAN(THIS.aFieldList[lnX,1],"_"," "))+ [:</td>] +CRLF
   ENDFOR
ENDIF

*** Just loop through fields and display
FOR lnX=1 to THIS.nFieldCount
	 lcfieldname=PROPER(THIS.afieldList[lnX,1])
	 lcfieldtype=THIS.afieldList[lnX,2]
	 lnFieldWidth=THIS.aFieldList[lnX,3]
	 lcfieldcaption=THIS.afieldList[lnX,11]  && overridden UpdateTrigger
	 
    IF lcFieldType # "G"
	    lvValue=EVAL(lcfieldname)
    ENDIF
    	    
	lcRow=lcFieldCaption 
	 
    DO CASE
       CASE lcfieldtype="C" OR lcFieldType = "V"
        	lcRow = lcRow + CHR(9) + [<td><ww:wwWebTextBox runat="server" id="txt]+ lcFieldName +[" width="400px" ControlSource="] + lcObjectName + [.] + lcFieldName + [" /></td>] + CRLF
       CASE lcfieldtype="M"
	        lcRow = lcRow + CHR(9)+ [<td><ww:wwWebTextBox runat="server" TextMode="MultiLine" id="txt]+ lcFieldName +[" width="400px" height="50px" ControlSource="] + lcObjectName + [.] + lcFieldName + [" /></td>] + CRLF
          *lcrow=lcrow+"<TD>"+IIF(EMPTY( EVAL(lcfieldname) ),"<BR>",ALLTRIM( EVAL(lcfieldname) ))+"</TD>"
          * lcrow=lcrow+[<TD><textArea wrap=virtual cols=55 rows=5 name="txt]+ lcFieldName +["><%= ] + lcObjectName + "." + lcFieldName + [%></textarea></TD>]
       CASE lcfieldtype $ "NFBIY"
          lcRow = lcRow + CHR(9)+ [<td><ww:wwWebTextBox runat="server" id="txt]+ lcFieldName +[" Width="80px" ControlSource="] + lcObjectName + [.] + lcFieldName + [" style="text-align: right" /></td>] + CRLF
          *lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=] + TRANS(lnFieldWidth + 1) + [ value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="L"
	      lcRow = lcRow + CHR(9)+ [<td><ww:wwWebCheckBox runat="server" id="chk]+ lcFieldName +[" ControlSource="] + lcObjectName + [.] + lcFieldName + [" /></td>] + CRLF
          *lcRow = lcRow + [<td><input type="text" name="txt]+ lcFieldName +[" size=1 value="<%= iif( ] + lcObjectName + "." + lcFieldName + [,'T','F') %>"></td>]
       CASE lcfieldtype="D"
	      lcRow = lcRow + CHR(9)+ [<td><ww:wwDatePicker runat="server" id="txt]+ lcFieldName +["  ControlSource="] + lcObjectName + [.] + lcFieldName + [" /></td>] + CRLF
          *lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=10 value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       CASE lcfieldtype="T"
	      lcRow = lcRow + CHR(9) + [<td><ww:wwDatePicker runat="server" id="txt]+ lcFieldName +[" width="135px" ControlSource="] + lcObjectName + [.] + lcFieldName + [" ControlSourceFormat="=DTOC" /></td>] + CRLF
	      *lcRow = lcRow + [<td><input type="text" name="]+ lcFieldName +[" size=15 value="<%= ] + lcObjectName + "." + lcFieldName + [%>"></td>]
       OTHERWISE
          lcRow = lcRow + CHR(9)+ "<td>&nbsp;</td>" + CRLF
       ENDCASE
       
    
	 THIS.oHTML.Write(lcRow + "</tr>" + CRLF)
ENDFOR && lnX=1 to lnFieldCount

*** Make sure the PK is embedded in here
IF !EMPTY(lcKeyValue)
   THIS.oHTML.Write([<input type="hidden" name="] + THIS.cKeyField + [" value="] + ;
                    TRANSFORM(lcKeyValue) + [">])
ENDIF

THIS.oHTML.Write( "</table>" + IIF(THIS.lCenterTable,[</center>]+CRLF,"") + CRLF)

ENDFUNC
* EditRecordWebForm


FUNCTION SaveRecord
************************************************************************
* ShowCursor :: SaveRecord
***********************************
***  Function: Show all fields as edit fields. The names of the edit
***            field is the name of the actual table field.
************************************************************************
LOCAL lnX, lcFieldCaption, lnFieldCount, lcfieldtype, lcfieldname


*** Just loop through fields and display
FOR lnX=1 to THIS.nFieldCount
	 lcfieldname=THIS.aFieldList[lnX,1]
	 lcfieldtype=THIS.aFieldList[lnX,2]
	 
	 *** Only update fields that have values on the form
	 *** NOTE: works because all fields are type="text"
	 IF !Request.IsFormVar(lcFieldName) 
	    LOOP
	 ENDIF
	 lvValue=Request.Form(lcFieldName)
	    
	 DO CASE
	 CASE lcfieldtype="C" or lcFieldType = "M" OR lcFieldType="V"
	    replace &lcFieldName with lvValue
	 CASE lcfieldtype $ "NFBIY"
	    replace &lcFieldName with VAL(lvValue)
	 CASE lcfieldtype="L"
	    replace &lcFieldName with IIF(lvValue="T",.t.,.f.)
	 CASE lcfieldtype="D"
	    replace &lcFieldName with CTOD(lvValue)
	 CASE lcfieldtype="T"
	    replace &lcFieldName with CTOT(lvValue)
	 ENDCASE
ENDFOR && lnX=1 to lnFieldCount

ENDFUNC
* SaveRecord



FUNCTION EditTable
************************************************************************
* ShowCursor :: EditTable
***********************************
***  Function: Show all fields as edit fields. The names of the edit
***            field is the name of the actual table field.
************************************************************************
LOCAL lcFields

lcAction = upper(Request.QueryString("Action"))
lcID = Request.QueryString("ID")
 
DO CASE 
  CASE lcAction = "EDIT" OR lcAction = "ADD"

    IF !THIS.lAllowAdd
       THIS.oHTML.Write("Sorry! Adding is not allowed at this time...")
       RETURN
    ENDIF
    
    IF lcAction = "ADD"
      llAdd = .T.
    ELSE
      llAdd = .F.
    ENDIF
    
    loResponse = THIS.oHTML
    lcKeyField = THIS.cKeyField

    IF llAdd
       LOCATE FOR .F.
       loResponse.Write([<form action="] + THIS.cBaseurl + [&Action=SaveNew&ID=] + lcID + [" method="POST">] +CRLF)
    ELSE
	    IF THIS.cKeyType = "N"
	       LOCATE FOR &lcKeyField = VAL(lcID)
	    ELSE
	       LOCATE FOR &lcKeyField = lcID
	    ENDIF
	    
		IF !FOUND()
		   loResponse.StandardPage("Couldn't edit record. Invalid Key Field...",,"NONE")
		   RETURN
		ENDIF
    	loResponse.Write([<form action="] + THIS.cBaseurl + [&Action=Save&ID=] + lcID + [" method="POST">] +CRLF)
    ENDIF
  
	loResponse.Write([<input type="submit" name="btnSubmit" value=" Save " ACCESSKEY="S"><p>])

	THIS.EditRecord()

	loResponse.Write([<p><input type="submit" name="btnSubmit" value=" Save ">])

	loResponse.Write([</form>] + CRLF) 

  CASE lcAction = "SHOW"
    loResponse = THIS.oHTML
    lcKeyField = THIS.cKeyField

    IF THIS.cKeyType = "N"
	       LOCATE FOR &lcKeyField = VAL(lcID)
    ELSE
	       LOCATE FOR &lcKeyField = lcID
    ENDIF
	    
	IF !FOUND()
       loResponse.StandardPage("Couldn't edit record. Invalid Key Field...",,"NONE")
	   RETURN
	ENDIF

	THIS.ShowRecord()
  
  CASE lcAction = "SAVE"
    loResponse = THIS.oHTML
    lcKeyField = THIS.cKeyField

    IF lcAction = "SAVENEW"
       APPEND BLANK
    ELSE
	    IF THIS.cKeyType = "N"
	       LOCATE FOR &lcKeyField = VAL(lcID)
	    ELSE
	       LOCATE FOR &lcKeyField = lcID
	    ENDIF
		IF !FOUND()
		   loResponse.ErrorMsg("Couldn't edit record. Invalid Key Field...")
		   RETURN
		ENDIF
    ENDIF

    THIS.SaveRecord()

    Response.Redirect(THIS.cBaseUrl)
  CASE lcACtion = "DELETE"
    lcKeyField = THIS.cKeyField
    
    IF !THIS.lAllowDelete
       THIS.oHTML.Write("Sorry! Deleting is not allowed at this time...")
       RETURN
    ENDIF
    IF THIS.cKeyType = "N"
       LOCATE FOR &lcKeyField = VAL(lcID)
    ELSE
       LOCATE FOR &lcKeyField = lcID
    ENDIF
	    
	IF !FOUND()
       THIS.oHTML.StandardPage("Couldn't delete record. Invalid Key Field...")
	   RETURN
	ENDIF  
	
	DELETE
	Response.Redirect(THIS.cBaseUrl)
  OTHERWISE
     IF EMPTY(this.cPage_PageUrl)
        THIS.cPage_PageUrl = this.cBaseUrl
     ENDIF
  
     IF THIS.lAllowAdd   
        THIS.oHTML.Write([<a href="] + THIS.cBaseUrl + [Action=Add">Add a new record</a><p>])
     ENDIF
  
     lcKeyField = THIS.cKeyField

     IF EMPTY(THIS.cTableFieldList)
        lcFields = "*"
     ELSE
        lcFields = THIS.cTableFieldList
     ENDIF
     
     lcOrder = IIF(!EMPTY(THIS.cTableSortColumn),"ORDER BY " + THIS.cTableSortColumn,"")
    
     SELECT &lcFields,;
            PADR([<a href="] + THIS.cBaseUrl + [Action=SHOW&ID=]+TRANS(&lcKeyField)+[">Show</a> | <a href="] + THIS.cBaseUrl + [Action=EDIT&Id=]+TRANS(&lcKeyField)+[">Edit</a>] + IIF(THIS.lAllowDelete,[ | <a href="] + THIS.cBaseUrl + [Action=DELETE&Id=]+TRANS(&lcKeyField)+[">Delete</a>],[]), 254) as Action ;
        FROM Alias() ;
        &lcOrder ;
        INTO Cursor __TxQuery
     THIS.nFieldCount=AFIELDS(THIS.aFieldList)
     
     lcOldTableFieldList = THIS.cTableFieldList
     THIS.cTableFieldList = ""

     THIS.ShowCursor()

     THIS.cTableFieldList = lcOldTableFieldList
     USE IN __TxQuery
ENDCASE 

ENDFUNC
* wwShowCursor :: EditTable
                      
************************************************************************
* ShowCursor :: GetOutput
*********************************
***  Function: Returns the generated HTML *after* the ShowCursor
***            method has been run. 
***    Assume: Applies only if a string based HTML object was passed
***            or used internally by wwShowCursor!
***      Pass: Nothing
***    Return: HTML or "" if oHTML is not defined
************************************************************************
FUNCTION GetOutput

IF !ISNULL(THIS.oHTML)
   RETURN THIS.oHTML.GetOutput()
ENDIF

RETURN ""   
ENDFUNC


************************************************************************
* wwShowCursor :: PageFilter
*********************************
***  Function: Filters the current cursor and only displays the 
***            specified page. Uses the vPage_ properties.
***    Assume: data set should be a Cursor with fixed record numbers.
***            Indexed orders or filtered sets will not work!
************************************************************************
FUNCTION PageFilter
LOCAL lnX,lcOutput, lcStyle, lnPages, lnRecLow, lnHighRec, lnEndPage, lnStartPage, lcNoLinkStyle, lnReccount

IF EMPTY(THIS.nPage_ShowPage)
  THIS.nPage_ShowPage = VAL( Request.QueryString("PAGE") )
  IF THIS.nPage_ShowPage < 1
     THIS.nPage_ShowPage = 1
  ENDIf
ENDIF

lnReccount = RECCOUNT()
IF lnReccount <= THIS.nPage_ItemsPerPage
   RETURN
ENDIF

THIS.cPage_OldAlias=ALIAS()
lnPages=lnReccount/THIS.nPage_ItemsPerPage
IF INT(lnPages) < lnPages
   lnPages = INT(lnPages) + 1
   THIS.nPage_TotalPages=lnPages
ELSE
   THIS.nPage_TotalPages=INT(lnPages)
ENDIF
IF THIS.nPage_ShowPage < lnPages
   THIS.nPage_NextPage=THIS.nPage_ShowPage + 1
ELSE
   THIS.nPage_NextPage=0
ENDIF
IF THIS.nPage_ShowPage > 1
   THIS.nPage_PrevPage= THIS.nPage_ShowPage -1
ELSE
   THIS.nPage_PrevPage=0
ENDIF

IF THIS.nPage_ShowPage= 0
   THIS.nPage_ShowPage=1
ENDIF 


IF THIS.nPage_ShowPage <= lnPages
  lnRecLow=(THIS.nPage_ShowPage -1) * THIS.nPage_ItemsperPage + 1
  lnHighRec=THIS.nPage_ShowPage * THIS.nPage_ItemsperPage 

  SELECT  * FROM (THIS.cPage_OldAlias) ;
     where recno() >= lnRecLow and Recno() <= lnHighRec ;
    INTO CURSOR _TXQuery
ENDIF


*** If the user supplied a link URL create the HTML for the links as a string
IF !EMPTY(THIS.cPage_PageURL)
      *** Figure out last and next 10 pages to display
      IF lnPages <= 10
         lnStartPage = 1
         lnEndPage = lnPages
      ELSE
         lnStartPage = THIS.nPage_ShowPage - 4
         IF lnStartPage < 1
            lnStartPage = 1
         ENDIF
         lnEndPage = THIS.nPage_ShowPage + 5
         IF lnEndPage > lnPages
            lnEndPage = lnPages
         ENDIF
      ENDIF

      lcOutput="Pages: &nbsp;"
      lcStyle = [ STYLE="color:]+THIS.cHeaderColor+[;text-decoration:none underline"] 
      lcNoLinkStyle = [ STYLE="color:]+THIS.cHeaderColor+[;"] 

      FOR lnX = lnStartPage TO lnEndPage
         IF lnX = THIS.nPage_ShowPage
            lcOutput = lcOutput + ;
                   [ <b ] + lcNoLinkstyle + [>] + TRANSFORM(lnX) + [</b> ]
         ELSE
            lcOutput=lcOutput +;
                   [<a href="] + THIS.cPage_PageURL + [Page=] + TRANS(lnX) + ["] +lcStyle + [>] +;
                   TRANSFORM(lnX) + [</a> ]      
         ENDIF       
               
      ENDFOR
      
      *** First Page
      lcOutput=lcOutput +;
                  [<b> &nbsp;&nbsp;&nbsp;&nbsp;<a href="] + THIS.cPage_PageURL + [Page=1"] +lcStyle + [>1</a>]
      
      *** First Page
      lcOutput=lcOutput +;
               [..<a href="] + THIS.cPage_PageURL + [Page=] +TRANSFORM(lnPages) + ["] +lcStyle + [>] + TRANSFORM(lnPages) + [</a>&nbsp;&nbsp;]
      
      
      *** Prev Page
      IF THIS.nPage_PrevPage # 0
         lcOutput=lcOutput +;
                  [ <a href="] + THIS.cPage_PageURL + [Page=] +TRANSFORM(THIS.nPage_PrevPage) + ["] +lcStyle + [>Prev</a>]
      ELSE
         lcOutput=lcOutput +;
                  [ &nbsp; </b><span ] +lcNoLinkStyle + [>Prev</span><b>]
      ENDIF
            
      *** Next Page
      IF THIS.nPage_NextPage # 0
         lcOutput=lcOutput +;
                  [ &nbsp;<a href="] + THIS.cPage_PageURL + [Page=] +TRANSFORM(THIS.nPage_NextPage) + ["] +lcStyle + [>Next</a>]
      ELSE
         lcOutput=lcOutput +;
                  [ &nbsp;</b><span ] +lcNoLinkStyle + [>Next</span><b>]
      ENDIF
      
      THIS.cPage_LinkHTML=lcOutput + "&nbsp;</b>"
ENDIF

RETURN
ENDFUNC
* EOF PageFilter   

ENDDEFINE
*EOC ShowCursor
