#include "hbclass.ch"

CREATE CLASS TPlantilla

   DATA hPlantilla INIT { => }
   DATA oDocumento INIT NIL
   DATA cRuta INIT ""

   METHOD New( cRuta ) CONSTRUCTOR
   METHOD Init( cRuta )
   METHOD Create()
   METHOD End()
   METHOD SetRuta( cRuta )
   METHOD SetData( hPlantilla )
   METHOD GetPagina()
   METHOD GetObjetos() INLINE iif( HB_ISOBJECT( ::oDocumento ), ::oDocumento:aObjects, {} )
   METHOD GetUserVars() INLINE iif( HB_ISOBJECT( ::oDocumento ), ::oDocumento:hUserVars, { => } )
   METHOD GetAcumVars() INLINE iif( HB_ISOBJECT( ::oDocumento ), ::oDocumento:hAcumVars, { => } )
   METHOD IsLabelDocument() INLINE iif( HB_ISOBJECT( ::oDocumento ), ::oDocumento:IsLabelDocument(), .F. )
   METHOD GetLabelLayout()
   METHOD GetData() INLINE ::hPlantilla

   HIDDEN:
   METHOD CargarJson( cRuta )
   METHOD NormalizarDocumento( hPlantilla )
   METHOD DefaultLabelLayout()
   METHOD HGet( hHash, cKey, uDefault )
   METHOD HashKeys( hHash ) INLINE iif( HB_ISHASH( hHash ), hb_HKeys( hHash ), {} )
   METHOD ValueString( uValue )
   METHOD ValueNumber( uValue )

ENDCLASS

METHOD New( cRuta ) CLASS TPlantilla

   ::Init( cRuta )

RETURN Self

METHOD Init( cRuta ) CLASS TPlantilla

   ::cRuta := iif( HB_ISSTRING( cRuta ), cRuta, "" )
   ::hPlantilla := { => }
   ::oDocumento := NIL

RETURN Self

METHOD Create() CLASS TPlantilla

   IF Len( ::cRuta ) > 0
      ::hPlantilla := ::CargarJson( ::cRuta )
   ENDIF

   ::oDocumento := TDocument():New():Create():Load( ::NormalizarDocumento( ::hPlantilla ) )

RETURN Self

METHOD End() CLASS TPlantilla

   IF HB_ISOBJECT( ::oDocumento ) .AND. __objHasMsg( ::oDocumento, "END" )
      ::oDocumento:End()
   ENDIF
   ::hPlantilla := { => }
   ::oDocumento := NIL
   ::cRuta := ""

RETURN NIL

METHOD SetRuta( cRuta ) CLASS TPlantilla

   ::cRuta := iif( HB_ISSTRING( cRuta ), cRuta, "" )

RETURN Self

METHOD SetData( hPlantilla ) CLASS TPlantilla

   ::hPlantilla := iif( HB_ISHASH( hPlantilla ), hPlantilla, { => } )

RETURN Self

METHOD GetPagina() CLASS TPlantilla

   LOCAL nWidth := 210.0
   LOCAL nHeight := 297.0
   LOCAL cHeightMode := "fixed"
   LOCAL nDesignHeight := 250.0
   LOCAL nBottomMargin := 5.0

   IF HB_ISOBJECT( ::oDocumento )
      nWidth := ::oDocumento:nPaperWidth
      nHeight := ::oDocumento:nPaperHeight
      cHeightMode := ::oDocumento:cPaperHeightMode
      nDesignHeight := ::oDocumento:nDesignHeight
      nBottomMargin := ::oDocumento:nContinuousBottomMargin
   ENDIF

RETURN { ;
   "ancho" => nWidth, ;
   "alto" => nHeight, ;
   "modoAlto" => cHeightMode, ;
   "altoDiseno" => nDesignHeight, ;
   "margenInferiorContinuo" => nBottomMargin, ;
   "unidad" => "mm" }

METHOD GetLabelLayout() CLASS TPlantilla

   IF HB_ISOBJECT( ::oDocumento )
      RETURN ::oDocumento:hLabelLayout
   ENDIF

RETURN ::DefaultLabelLayout()

METHOD CargarJson( cRuta ) CLASS TPlantilla

   LOCAL cContenido
   LOCAL hData := { => }

   cRuta := ::ValueString( cRuta )
   IF Len( cRuta ) == 0 .OR. ! File( cRuta )
      RETURN { => }
   ENDIF

   cContenido := MemoRead( cRuta )
   IF Empty( cContenido )
      RETURN { => }
   ENDIF
   hb_jsonDecode( cContenido, @hData )
   IF ! HB_ISHASH( hData )
      RETURN { => }
   ENDIF

RETURN hData

METHOD NormalizarDocumento( hPlantilla ) CLASS TPlantilla

   LOCAL hPagina
   LOCAL aObjects := {}
   LOCAL aObjetos
   LOCAL hObjeto
   LOCAL nIndex
   LOCAL cTipo
   LOCAL nObjetosLen

   hPlantilla := iif( HB_ISHASH( hPlantilla ), hPlantilla, { => } )
   IF HB_ISARRAY( ::HGet( hPlantilla, "aObjects", NIL ) )
      RETURN hPlantilla
   ENDIF

   hPagina := iif( HB_ISHASH( ::HGet( hPlantilla, "pagina", NIL ) ), ::HGet( hPlantilla, "pagina", NIL ), { => } )
   aObjetos := iif( HB_ISARRAY( ::HGet( hPlantilla, "objetos", NIL ) ), ::HGet( hPlantilla, "objetos", NIL ), {} )
   nObjetosLen := Len( aObjetos )
   FOR nIndex := 1 TO nObjetosLen
      hObjeto := aObjetos[ nIndex ]
      IF ! HB_ISHASH( hObjeto )
         LOOP
      ENDIF
      cTipo := ::ValueString( ::HGet( hObjeto, "tipo", "" ) )
      AAdd( aObjects, { ;
         "cId" => ::ValueString( ::HGet( hObjeto, "id", "" ) ), ;
         "cName" => ::ValueString( ::HGet( hObjeto, "nombre", ::HGet( hObjeto, "id", "" ) ) ), ;
         "cType" => iif( cTipo == "TRectangle", "TRectangle", "TText" ), ;
         "nLeft" => ::ValueNumber( ::HGet( hObjeto, "x", 0 ) ), ;
         "nTop" => ::ValueNumber( ::HGet( hObjeto, "y", 0 ) ), ;
         "nWidth" => ::ValueNumber( ::HGet( hObjeto, "ancho", 0 ) ), ;
         "nHeight" => ::ValueNumber( ::HGet( hObjeto, "alto", 0 ) ), ;
         "cText" => ::ValueString( ::HGet( hObjeto, "valor", "" ) ), ;
         "cCondition" => ::ValueString( ::HGet( hObjeto, "condicion", "" ) ) } )
   NEXT

RETURN { ;
   "cType" => "TDocument", ;
   "cFormatVersion" => "1.0", ;
   "cTemplateName" => ::ValueString( ::HGet( hPlantilla, "nombre", "Documento" ) ), ;
   "nPaperWidth" => ::ValueNumber( ::HGet( hPagina, "ancho", 210 ) ), ;
   "nPaperHeight" => ::ValueNumber( ::HGet( hPagina, "alto", 297 ) ), ;
   "aObjects" => aObjects }

METHOD DefaultLabelLayout() CLASS TPlantilla
RETURN { ;
   "nLabelWidth" => 70.0, ;
   "nLabelHeight" => 37.0, ;
   "nColumns" => 3, ;
   "nRows" => 8, ;
   "nMarginLeft" => 0.0, ;
   "nMarginTop" => 0.0, ;
   "nGapHorizontal" => 0.0, ;
   "nGapVertical" => 0.0, ;
   "cFlow" => "row", ;
   "cLabelFormat" => "manual", ;
   "nPrintOffsetX" => 0.0, ;
   "nPrintOffsetY" => 0.0 }

METHOD HGet( hHash, cKey, uDefault ) CLASS TPlantilla

   IF HB_ISHASH( hHash ) .AND. hb_HHasKey( hHash, cKey )
      RETURN hHash[ cKey ]
   ENDIF

RETURN uDefault

METHOD ValueString( uValue ) CLASS TPlantilla

   IF uValue == NIL
      RETURN ""
   ENDIF
   IF HB_ISSTRING( uValue )
      RETURN uValue
   ENDIF
   IF HB_ISNUMERIC( uValue )
      RETURN AllTrim( Str( uValue ) )
   ENDIF
   IF HB_ISLOGICAL( uValue )
      RETURN iif( uValue, "1", "" )
   ENDIF

RETURN AllTrim( hb_ValToStr( uValue ) )

METHOD ValueNumber( uValue ) CLASS TPlantilla

   IF HB_ISNUMERIC( uValue )
      RETURN uValue
   ENDIF
   IF HB_ISSTRING( uValue )
      RETURN Val( StrTran( uValue, ",", "." ) )
   ENDIF
   IF HB_ISLOGICAL( uValue )
      RETURN iif( uValue, 1, 0 )
   ENDIF

RETURN 0
