/*
 * Xailer source code:
 *
 * DataField.prg
 * Clase TDataField()
 *
 * Copyright 2003, 2007 Ignacio Ortiz de Zúñiga
 * Copyright 2003, 2007 Xailer.com
 * All rights reserved
 *
 */

#include "Xailer.ch"
#include "error.ch"


//--------------------------------------------------------------------------

CLASS XDataField FROM TComponent

PUBLISHED:
   PROPERTY Value     READ GetValue     WRITE SetValue
   PROPERTY Buffer    READ GetValue     WRITE SetValue // deprecated
   PROPERTY lModified READ GetModified  WRITE SetModified
   PROPERTY DefValue

   PROPERTY oDataSet  AS TDataSet

   PROPERTY cName           INIT ""
   PROPERTY cDisplayName    INIT ""
   PROPERTY cFullname       INIT ""
   PROPERTY cDbfName        INIT ""
   PROPERTY cType           INIT ""
   PROPERTY nSQLType        INIT ""
   PROPERTY nLen            INIT 10 WRITE SetLen
   PROPERTY nSQLLen         INIT 0
   PROPERTY nDec            INIT 0
   PROPERTY nSQLDec         INIT 0
   PROPERTY nIndex          INIT 0
   PROPERTY lAllowsNull     INIT .T.
   PROPERTY lEditable       INIT .T.
   PROPERTY lAutoInc        INIT .F.
   PROPERTY lPrimaryKey     INIT .F.
   PROPERTY lSetNullIfEmpty INIT .f.
   PROPERTY cTable          INIT ""

RESERVED:
   DATA bGetValue // se utiliza sólo para clonar datafields

PUBLIC:
   METHOD Create( oDataSet, nIndex, cName ) CONSTRUCTOR
   METHOD Free() INLINE ( ::oDataSet := ::OnGetValue := ::OnSetValue := NIL, ::Super:Free() )

   METHOD Load() // --> Value
   METHOD Blank() // --> Value
   METHOD InitValue() INLINE ::oDataset:oRecords:aRecord[ ::nIndex ] // --> InitValue

RESERVED:
   METHOD VarGet()           INLINE ( Logdebug( "TDatafield:Varget() deprecated, use Value", ::Value ) )
   METHOD VarPut( v )        INLINE ( Logdebug( "TDatafield:Varput() deprecated, use Value := ?", ::SetValue( v ) ) )
   METHOD FieldGet( lRecno ) INLINE ::oDataSet:FieldGet( ::nIndex, lRecno )
   METHOD FieldPut( Value )  INLINE ::oDataSet:FieldPut( ::nIndex, Value, .T. ) //.T. para que no actualice ningun DC
   METHOD SetValue( Value, lFromDC )
   METHOD GetValue( lForceRecno )
   METHOD SetGetFValue( v ) INLINE iif( v != NIL, ::FValue := v, ::FValue ) // necesario para TDataset:AddUserVar
   METHOD BasicType() // --> cType
   METHOD ValType()  // --> cType
   METHOD HasChanged( v )

PUBLISHED:
   EVENT OnGetValue  // --> xValue
   EVENT OnSetValue  // --> Nil

PROTECTED:
   METHOD SetModified( lValue )
   METHOD GetModified()
   METHOD SetLen( nValue )

ENDCLASS

//--------------------------------------------------------------------------

METHOD Create( oDataSet, nIndex, cName ) CLASS XDataField

    ::Super:Create( oDataSet )

   ::oDataSet     := oDataSet
   ::nIndex       := nIndex
   ::cName        := cName
   ::cDbfName     := cName
   ::cDisplayName := cName
   ::cFullname    := cName

RETURN Self

//--------------------------------------------------------------------------

METHOD GetValue( lForceRecno ) CLASS XDataField

   IF ::EventAssigned( "OnGetValue" )
      ::FValue := ::OnGetValue( lForceRecno )
   ELSE
      ::FValue := ::oDataSet:FieldGet( ::nIndex, lForceRecno )
   ENDIF

RETURN ::FValue

//--------------------------------------------------------------------------

METHOD SetValue( Value, lFromDC ) CLASS XDataField

   IF ::EventAssigned( "OnSetValue" )
      ::FValue := ::OnSetValue( Value, lFromDC )
   ELSE
      IF ::lSetNullIfEmpty .AND. Empty( Value )
         Value := NIL
      ENDIF
      ::FValue := ::oDataSet:FieldPut( ::nIndex, Value, lFromDC )
   ENDIF

RETURN ::FValue

//--------------------------------------------------------------------------

METHOD SetLen( nValue ) CLASS XDataField

   IF Empty( nValue ) .AND. ::BasicType == "N"
      ::oDataSet:NewError( "Invalid TDataField [" + ::cName + "] length" )
   ENDIF

   ::FnLen := nValue

RETURN ::FnLen

//--------------------------------------------------------------------------

METHOD SetModified( lValue ) CLASS XDataField

	::FlModified := lValue

RETURN lValue

//--------------------------------------------------------------------------

METHOD GetModified() CLASS XDataField

	LOCAL lValue

	IF ::FlModified != NIL
		lValue := ::FlModified
	ELSE
		TRY
         lValue := ::HasChanged( ::Value )
		CATCH
			lValue := .T.
		END
	ENDIF

RETURN lValue

//--------------------------------------------------------------------------


METHOD HasChanged( xValue ) CLASS XDataField

   REQUEST VarsEqual

//RETURN !VarsEqual( ::InitValue(), xValue )
RETURN !( ::InitValue() == xValue )

//--------------------------------------------------------------------------

METHOD Load() CLASS XDataField

	::lModified := NIL

RETURN ::Value

//--------------------------------------------------------------------------

METHOD Blank() CLASS XDataField

   ::lModified := Nil

RETURN ::DefValue

//--------------------------------------------------------------------------

METHOD BasicType() CLASS XDataField

   LOCAL cType := ::cType

   // Bug en tipo MONEY para ADS

   IF Empty( cType ) .AND. ::oDataSet:oDataSource:IsKindOf( "TAdsDataSource" )
      cType := "N"
   ENDIF

   DO CASE
      CASE cType == "INTEGER" .OR. cType == "SHORT" .OR. cType == "CURDOUBLE" .OR. ;
         cType == "SHORTINT" .OR. cType == "DOUBLE" .OR. cType == "AUTOINCREMENT" .OR. ;
         cType == "AUTOINC"
         cType := "N"
      CASE cType == "TIME" .OR. cType == "TIMESTAMP"
         cType := "C"
      CASE cType == "BINARY" .OR. cType == "IMAGE" .OR. cType == "RAW" .OR. cType = "B"
         cType := "M"
   ENDCASE

RETURN cType

//--------------------------------------------------------------------------

METHOD ValType() CLASS XDataField

   LOCAL cType := ValType( ::Value )

   IF cType == "U"
      cType := ::BasicType()
   ENDIF

RETURN cType

//--------------------------------------------------------------------------

#pragma BEGINDUMP

#include "xailer.h"

HB_FUNC_STATIC( VARSEQUAL )
{
   int iResult;

   if( hb_itemCompare( hb_param( 1, HB_IT_ANY ),
                       hb_param( 2, HB_IT_ANY ),
                       HB_TRUE, &iResult ) )
      hb_retl( iResult == 0 );
   else
      hb_retl( HB_FALSE );
}

#pragma ENDDUMP
