#include "hbclass.ch"

CREATE CLASS TObjectBaseProbe FROM TObjectBase

   METHOD Padding()

ENDCLASS

METHOD Padding() CLASS TObjectBaseProbe

RETURN ::PaddingRenderizable()

CREATE CLASS TObjectBaseContext

   DATA aAvisos INIT {}
   DATA aDescartados INIT {}
   DATA hFormulas INIT { => }
   DATA hCondiciones INIT { => }
   DATA lCapaActiva INIT .T.
   DATA lModoDisenador INIT .F.

   METHOD New() CONSTRUCTOR
   METHOD EvaluarFormula( cFormula )
   METHOD EvaluarCondicion( cCondicion )
   METHOD CapaActiva( oObjeto )
   METHOD DescartarObjeto( oObjeto, cMotivo )
   METHOD AddAviso( cAviso )
   METHOD EsModoDisenador()

ENDCLASS

METHOD New() CLASS TObjectBaseContext

RETURN Self

METHOD EvaluarFormula( cFormula ) CLASS TObjectBaseContext

   IF hb_HHasKey( ::hFormulas, cFormula )
      RETURN ::hFormulas[ cFormula ]
   ENDIF

RETURN ""

METHOD EvaluarCondicion( cCondicion ) CLASS TObjectBaseContext

   cCondicion := iif( cCondicion == NIL, "", cCondicion )
   IF hb_HHasKey( ::hCondiciones, cCondicion )
      RETURN ::hCondiciones[ cCondicion ]
   ENDIF

RETURN { "lVisible" => .T., "cMotivo" => "" }

METHOD CapaActiva( oObjeto ) CLASS TObjectBaseContext

   HB_SYMBOL_UNUSED( oObjeto )

RETURN ::lCapaActiva

METHOD DescartarObjeto( oObjeto, cMotivo ) CLASS TObjectBaseContext

   HB_SYMBOL_UNUSED( oObjeto )
   AAdd( ::aDescartados, cMotivo )

RETURN NIL

METHOD AddAviso( cAviso ) CLASS TObjectBaseContext

   AAdd( ::aAvisos, cAviso )

RETURN NIL

METHOD EsModoDisenador() CLASS TObjectBaseContext

RETURN ::lModoDisenador

PROCEDURE Main()

   LOCAL oObject := TObjectBaseProbe():New():Create()
   LOCAL oContext := TObjectBaseContext():New()
   LOCAL oLoaded
   LOCAL oVisible
   LOCAL oOculto
   LOCAL nFailures := 0

   oContext:hFormulas := { ;
      "COLOR_OK" => "#ABCDEF", ;
      "COLOR_TRANSPARENT" => "transparent", ;
      "COLOR_BAD" => "nope" }
   oContext:hCondiciones := { ;
      "VISIBLE" => { "lVisible" => .T., "cMotivo" => "" }, ;
      "OCULTO" => { "lVisible" => .F., "cMotivo" => "condicion falsa" } }

   oLoaded := TObjectBaseProbe():New():Load( { ;
      "cId" => "obj1", ;
      "cName" => "Objeto cargado", ;
      "nLeft" => 10.5, ;
      "nTop" => 2.25, ;
      "nWidth" => 30.0, ;
      "nHeight" => 4.75, ;
      "lVisible" => .F., ;
      "nPaddingTop" => -2, ;
      "nPaddingRight" => 1.5, ;
      "nLl12LinkID" => 17, ;
      "nLl12LinkToID" => 9, ;
      "nLl12LinkMode" => 32, ;
      "nLl12GroupId" => 1, ;
      "lLl12WrapBefore" => .T. } )

   nFailures += AssertHashValue( "default cType", oObject:Save(), "cType", "TObjectBase" )
   nFailures += AssertHashValue( "default cName", oObject:Save(), "cName", "Objeto" )
   nFailures += AssertHashValue( "default visible", oObject:Save(), "lVisible", .T. )
   nFailures += AssertHashValue( "loaded cId", oLoaded:Save(), "cId", "obj1" )
   nFailures += AssertHashValue( "loaded cName", oLoaded:Save(), "cName", "Objeto cargado" )
   nFailures += AssertHashValue( "loaded visible", oLoaded:Save(), "lVisible", .F. )
   nFailures += AssertHashValue( "loaded link id", oLoaded:Save(), "nLl12LinkID", 17 )
   nFailures += AssertHashValue( "loaded link target", oLoaded:Save(), "nLl12LinkToID", 9 )
   nFailures += AssertHashValue( "loaded link mode", oLoaded:Save(), "nLl12LinkMode", 32 )
   nFailures += AssertHashValue( "loaded group id", oLoaded:Save(), "nLl12GroupId", 1 )
   nFailures += AssertHashValue( "loaded wrap before", oLoaded:Save(), "lLl12WrapBefore", .T. )
   nFailures += AssertEqual( "nRight", oLoaded:NRight(), 40.5 )
   nFailures += AssertEqual( "nBottom", oLoaded:NBottom(), 7.0 )
   nFailures += AssertHashValue( "padding top clamp", oLoaded:Padding(), "paddingSuperior", 0.0 )
   nFailures += AssertHashValue( "padding right", oLoaded:Padding(), "paddingDerecho", 1.5 )
   nFailures += AssertEqual( "renderizable base", oObject:GenerarRenderizable( oContext ), NIL )
   nFailures += AssertEqual( "color fijo", oObject:EvaluarColor( oContext, "", "#123456" ), "#123456" )
   nFailures += AssertEqual( "color texto fijo invalido", oObject:EvaluarColor( oContext, "", "transparent", .T. ), "#000000" )
   nFailures += AssertEqual( "color formula ok", oObject:EvaluarColor( oContext, "COLOR_OK", "#000000" ), "#abcdef" )
   nFailures += AssertEqual( "color formula transparent", oObject:EvaluarColor( oContext, "COLOR_TRANSPARENT", "#000000" ), "transparent" )
   nFailures += AssertEqual( "color formula bad fallback", oObject:EvaluarColor( oContext, "COLOR_BAD", "#112233" ), "#112233" )
   nFailures += AssertEqual( "aviso color invalido", Len( oContext:aAvisos ), 1 )

   oVisible := TObjectBaseProbe():New():Load( { "cCondition" => "VISIBLE" } )
   oOculto := TObjectBaseProbe():New():Load( { "cCondition" => "OCULTO" } )
   nFailures += AssertEqual( "visible ok", oVisible:EsVisibleEnEjecucion( oContext ), .T. )
   nFailures += AssertEqual( "visible condicion falsa", oOculto:EsVisibleEnEjecucion( oContext ), .F. )
   nFailures += AssertEqual( "descartado condicion", oContext:aDescartados[ 1 ], "condicion falsa" )

   IF nFailures == 0
      LogLine( "TObjectBase Harbour OK: 25 casos equivalentes a la referencia PHP" )
   ELSE
      LogLine( "TObjectBase Harbour FAIL: " + hb_NToS( nFailures ) )
   ENDIF

   ErrorLevel( nFailures )

RETURN

FUNCTION AssertHashValue( cCaseName, hHash, cKey, uExpected )

   IF ! hb_HHasKey( hHash, cKey )
      LogLine( "FAIL " + cCaseName )
      LogLine( "  falta clave: " + cKey )
      RETURN 1
   ENDIF

RETURN AssertEqual( cCaseName, hHash[ cKey ], uExpected )

FUNCTION AssertEqual( cCaseName, uActual, uExpected )

   IF uActual == uExpected
      RETURN 0
   ENDIF

   LogLine( "FAIL " + cCaseName )
   LogLine( "  esperado: " + hb_ValToStr( uExpected ) )
   LogLine( "  actual  : " + hb_ValToStr( uActual ) )

RETURN 1

FUNCTION LogLine( cText )

   OutStd( cText + hb_eol() )

RETURN NIL
