/*
 * Proyecto: LLDominus
 * Fichero: TFormLLDominusProgress.prg
 * Descripcion: progreso no modal para TLLEngine:RunEngine().
 */

#include "Xailer.ch"
#include "error.ch"

CLASS TFormLLDominusProgress FROM TForm

   COMPONENT oProgressBar1
   COMPONENT oIconBack
   COMPONENT oIconFront
   COMPONENT oHeaderSeparator
   COMPONENT oLabelSubtitulo
   COMPONENT oLineasPanel
   COMPONENT oPaginasPanel
   COMPONENT oLabelEstado
   COMPONENT oLabelLineas
   COMPONENT oLabelPaginas
   COMPONENT oLabelTiempo
   COMPONENT oButtonCancelar

   DATA lCanceled          INIT .F.
   DATA lStarted           INIT .F.
   DATA lOwnerWasEnabled   INIT .T.
   DATA nInicioMs          INIT 0.0
   DATA nUltimaLinea       INIT 0
   DATA nTotalLineas       INIT 0
   DATA nPaginas           INIT 0
   DATA nTotalPaginas      INIT 0
   DATA cPhase             INIT ""
   DATA oOwner             INIT NIL

   METHOD CreateForm( lCreate )
   METHOD End()
   METHOD StartProgress( oOwner )
   METHOD UpdateProgress( nLinea, nTotal, nPaginas )
   METHOD StartRenderProgress( nTotalObjetos, nTotalPaginas )
   METHOD StartPrintProgress( nTotalObjetos, nTotalPaginas )
   METHOD StartPDFProgress( nTotalPaginas )
   METHOD StartImageProgress( nTotalPaginas )
   METHOD StartCSVProgress( nTotalRegistros, nTotalTablas )
   METHOD StartXLSXProgress( nTotalRegistros, nTotalTablas )
   METHOD UpdateRenderProgress( nObjeto, nTotalObjetos, nPagina, nTotalPaginas )
   METHOD UpdateCSVProgress( nRegistro, nTotalRegistros, nTabla, nTotalTablas )
   METHOD UpdateXLSXProgress( nRegistro, nTotalRegistros, nTabla, nTotalTablas )
   METHOD CancelProgress()
   METHOD FinishProgress()
   METHOD CloseProgress()
   METHOD RefreshProgress()
   METHOD FormatTime( nElapsedMs )

ENDCLASS

//------------------------------------------------------------------------------

METHOD CreateForm( lCreate ) CLASS TFormLLDominusProgress

   DEFAULT lCreate TO .T.

   // TForm:New() ya llama a CreateForm(.T.). Evita una segunda creacion
   // si una llamada antigua conserva :New():CreateForm().
   IF HB_ISOBJECT( ::oProgressBar1 )
      RETURN Self
   ENDIF

   IF lCreate
      ::SetBounds( 310, 269, 604, 340 )
      ::SetClientSize( 596, 306 )
      ::cText        := "LL-Dominus"
      ::oFont        := TFont():Create( "Segoe UI", 10, 0, 400 )
      ::nClrPane     := clWhite
      ::lCentered    := .T.
      ::nBorderStyle := bsDIALOG
      ::lSysMenu     := .F.
      ::lCloseBox    := .F.
      ::lMinimizeBox := .F.
      ::lMaximizeBox := .F.
      ::Create()
   ENDIF

   ::Super:CreateForm( .F. )

   WITH OBJECT ::oIconBack := TBevel():New( Self )
      :SetBounds( 38, 26, 35, 43 )
      :nClrPane     := RGB( 229, 237, 248 )
      :nBorderStyle := bvWIN10
      :nPenColor    := RGB( 161, 180, 205 )
      :nPenSize     := 1
      :Create()
   END

   WITH OBJECT ::oIconFront := TBevel():New( Self )
      :SetBounds( 45, 20, 35, 43 )
      :nClrPane     := clWhite
      :nBorderStyle := bvWIN10
      :nPenColor    := RGB( 52, 64, 84 )
      :nPenSize     := 1
      :Create()
   END

   WITH OBJECT ::oLabelEstado := TLabel():New( Self )
      :SetBounds( 104, 23, 454, 28 )
      :cText      := "Preparando informe..."
      :oFont      := TFont():Create( "Segoe UI", 15, 0, 600 )
      :nClrText   := RGB( 34, 43, 56 )
      :lAutoSize  := .F.
      :Create()
   END

   WITH OBJECT ::oLabelSubtitulo := TLabel():New( Self )
      :SetBounds( 104, 54, 454, 20 )
      :cText      := "Creando el documento y preparando su salida"
      :oFont      := TFont():Create( "Segoe UI", 9, 0, 400 )
      :nClrText   := RGB( 112, 122, 137 )
      :lAutoSize  := .F.
      :Create()
   END

   WITH OBJECT ::oHeaderSeparator := TBevel():New( Self )
      :SetBounds( 34, 91, 528, 1 )
      :nClrPane     := RGB( 224, 229, 235 )
      :nBorderStyle := bvNONE
      :Create()
   END

   WITH OBJECT ::oProgressBar1 := TProgressBar():New( Self )
      :SetBounds( 34, 108, 528, 10 )
      :nMin       := 0
      :nMax       := 1
      :nValue     := 0
      :nClrPane   := RGB( 232, 237, 241 )
      :nClrText   := RGB( 42, 157, 96 )
      :lSmooth    := .T.
      :Create()
   END

   WITH OBJECT ::oLineasPanel := TBevel():New( Self )
      :SetBounds( 34, 140, 254, 64 )
      :nClrPane     := RGB( 247, 249, 251 )
      :nBorderStyle := bvNONE
      :Create()
   END

   WITH OBJECT ::oPaginasPanel := TBevel():New( Self )
      :SetBounds( 308, 140, 254, 64 )
      :nClrPane     := RGB( 247, 249, 251 )
      :nBorderStyle := bvNONE
      :Create()
   END

   WITH OBJECT ::oLabelLineas := TLabel():New( ::oLineasPanel )
      :SetBounds( 16, 21, 222, 24 )
      :cText      := TextLineas() + " procesadas: 0"
      :oFont      := TFont():Create( "Segoe UI", 11, 0, 500 )
      :nClrText   := RGB( 52, 64, 84 )
      :lAutoSize  := .F.
      :Create()
   END

   WITH OBJECT ::oLabelPaginas := TLabel():New( ::oPaginasPanel )
      :SetBounds( 16, 21, 222, 24 )
      :cText      := TextPaginas() + ": 0"
      :oFont      := TFont():Create( "Segoe UI", 11, 0, 500 )
      :nClrText   := RGB( 52, 64, 84 )
      :lAutoSize  := .F.
      :Create()
   END

   WITH OBJECT ::oLabelTiempo := TLabel():New( Self )
      :SetBounds( 34, 237, 330, 24 )
      :cText      := "Tiempo transcurrido: 00:00:00"
      :oFont      := TFont():Create( "Segoe UI", 10, 0, 400 )
      :nClrText   := RGB( 91, 101, 116 )
      :lAutoSize  := .F.
      :Create()
   END

   WITH OBJECT ::oButtonCancelar := TButtonMod():New( Self )
      :SetBounds( 432, 226, 130, 36 )
      :cText         := "Cancelar"
      :oFont         := TFont():Create( "Segoe UI", 10, 0, 500 )
      :nClrPane      := RGB( 52, 64, 84 )
      :nClrText      := clWhite
      :nClrBorder    := RGB( 52, 64, 84 )
      :nBorderRadius := 4
      :lFlat         := .F.
      :lCancel       := .F.
      :OnClick       := {|| ::CancelProgress(), .F. }
      :Create()
   END

RETURN Self

//------------------------------------------------------------------------------

METHOD End() CLASS TFormLLDominusProgress

   ::CloseProgress()

RETURN ::Super:End()

//------------------------------------------------------------------------------

METHOD StartProgress( oOwner ) CLASS TFormLLDominusProgress

   IF HB_ISOBJECT( Printer )
      ::cText := ProgressTitle( Printer:cJobTitle )
   ELSE
      ::cText := "LL-Dominus"
   ENDIF

   IF HB_ISOBJECT( oOwner )
      ::oOwner := oOwner
   ELSEIF HB_ISOBJECT( ::oParent ) .AND. ::oParent:IsKindOf( "XForm" )
      ::oOwner := ::oParent
   ELSEIF HB_ISOBJECT( Application:oMainForm )
      ::oOwner := Application:oMainForm
   ENDIF

   ::lCanceled     := .F.
   ::lStarted      := .T.
   ::nUltimaLinea  := 0
   ::nTotalLineas  := 0
   ::nPaginas      := 0
   ::nTotalPaginas := 0
   ::cPhase        := "ENGINE"
   ::nInicioMs     := CurrentMilliseconds()

   ::oLabelEstado:cText         := "Preparando informe..."
   ::oLabelSubtitulo:cText      := "Creando el documento y preparando su salida"
   ::oLabelLineas:cText         := TextLineas() + " procesadas: 0"
   ::oLabelPaginas:cText        := TextPaginas() + ": 0"
   ::oLabelTiempo:cText         := "Tiempo transcurrido: 00:00:00"
   ::oProgressBar1:nMin         := 0
   ::oProgressBar1:nMax         := 1
   ::oProgressBar1:nValue       := 0
   ::oButtonCancelar:cText      := "Cancelar"
   ::oButtonCancelar:lEnabled   := .T.

   IF HB_ISOBJECT( ::oOwner )
      ::lOwnerWasEnabled := ::oOwner:lEnabled
      ::oOwner:Disable()
   ENDIF

   ::Show( SW_SHOW, .T. )
   ::SetFocus()
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD UpdateProgress( nLinea, nTotal, nPaginas ) CLASS TFormLLDominusProgress

   LOCAL nElapsedMs

   IF ::lCanceled
      RETURN .F.
   ENDIF

   DEFAULT nLinea   TO 0
   DEFAULT nTotal   TO 0
   DEFAULT nPaginas TO 0

   ::nUltimaLinea := Max( ::nUltimaLinea, Max( 0, Int( nLinea ) ) )
   ::nTotalLineas := Max( 0, Int( nTotal ) )
   ::nPaginas     := Max( ::nPaginas, Max( 0, Int( nPaginas ) ) )

   IF ::nUltimaLinea == 0 .AND. ::nPaginas == 0
      ::oLabelEstado:cText := "Preparando informe..."
      IF ::nTotalLineas > 0
         ::oLabelLineas:cText := TextLineas() + " a procesar: " + LTrim( Str( ::nTotalLineas ) )
      ELSE
         ::oLabelLineas:cText := "Preparando datos del informe..."
      ENDIF
      ::oProgressBar1:nMin   := 0
      ::oProgressBar1:nMax   := Max( 1, ::nTotalLineas )
      ::oProgressBar1:nValue := 0
   ELSE
      ::oLabelEstado:cText   := "Generando informe..."
      ::oProgressBar1:nMin   := 0
      ::oProgressBar1:nMax   := Max( 1, ::nTotalLineas )
      ::oProgressBar1:nValue := Min( ::nUltimaLinea, ::oProgressBar1:nMax )

      IF ::nTotalLineas > 0
         ::oLabelLineas:cText := TextLinea() + " " + LTrim( Str( ::nUltimaLinea ) ) + ;
            " de " + LTrim( Str( ::nTotalLineas ) )
      ELSE
         ::oLabelLineas:cText := TextLinea() + " procesada: " + LTrim( Str( ::nUltimaLinea ) )
      ENDIF
   ENDIF

   ::oLabelPaginas:cText := TextPaginas() + " generadas: " + LTrim( Str( ::nPaginas ) )

   nElapsedMs := Max( 0.0, CurrentMilliseconds() - ::nInicioMs )
   ::oLabelTiempo:cText := "Tiempo transcurrido: " + ::FormatTime( nElapsedMs )

   ::RefreshProgress()

RETURN ! ::lCanceled

//------------------------------------------------------------------------------

METHOD StartRenderProgress( nTotalObjetos, nTotalPaginas ) CLASS TFormLLDominusProgress

   DEFAULT nTotalObjetos TO 0
   DEFAULT nTotalPaginas TO 0

   ::cPhase        := "RENDER"
   ::nUltimaLinea  := 0
   ::nTotalLineas  := Max( 0, Int( nTotalObjetos ) )
   ::nPaginas      := 0
   ::nTotalPaginas := Max( 0, Int( nTotalPaginas ) )

   ::oLabelEstado:cText       := "Preparando vista previa..."
   ::oLabelSubtitulo:cText    := "Creando el documento y preparando su salida"
   ::oLabelLineas:cText       := "Progreso: 0%"
   ::oLabelPaginas:cText      := TextPaginas() + " a generar: " + LTrim( Str( ::nTotalPaginas ) )
   ::oProgressBar1:nMin       := 0
   ::oProgressBar1:nMax       := Max( 1, ::nTotalLineas )
   ::oProgressBar1:nValue     := 0
   ::oButtonCancelar:cText    := "Cancelar"
   ::oButtonCancelar:lEnabled := ! ::lCanceled
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD StartPrintProgress( nTotalObjetos, nTotalPaginas ) CLASS TFormLLDominusProgress

   ::StartRenderProgress( nTotalObjetos, nTotalPaginas )
   ::cPhase := "PRINT"
   ::oLabelEstado:cText := "Preparando impresion..."
   IF HB_ISOBJECT( Printer ) .AND. ! Empty( Printer:cPrinterName )
      ::oLabelSubtitulo:cText := "Impresora: " + Printer:cPrinterName
   ELSE
      ::oLabelSubtitulo:cText := "Impresora predeterminada"
   ENDIF
   ::oLabelPaginas:cText := TextPaginas() + " a imprimir: " + LTrim( Str( ::nTotalPaginas ) )
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD StartPDFProgress( nTotalPaginas ) CLASS TFormLLDominusProgress

   DEFAULT nTotalPaginas TO 0

   ::StartRenderProgress( nTotalPaginas, nTotalPaginas )
   ::cPhase := "PDF"
   ::oLabelEstado:cText    := "Preparando PDF..."
   ::oLabelSubtitulo:cText := "Creando el documento PDF"
   ::oLabelPaginas:cText   := TextPaginas() + " a exportar: " + LTrim( Str( ::nTotalPaginas ) )
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD StartImageProgress( nTotalPaginas ) CLASS TFormLLDominusProgress

   DEFAULT nTotalPaginas TO 0

   ::StartRenderProgress( nTotalPaginas, nTotalPaginas )
   ::cPhase := "IMAGE"
   ::oLabelEstado:cText    := hb_UTF8ToStr( "Preparando imágenes...", "ESWIN" )
   ::oLabelSubtitulo:cText := hb_UTF8ToStr( "Creando los archivos de imagen", "ESWIN" )
   ::oLabelPaginas:cText   := TextPaginas() + " a exportar: " + LTrim( Str( ::nTotalPaginas ) )
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD StartCSVProgress( nTotalRegistros, nTotalTablas ) CLASS TFormLLDominusProgress

   DEFAULT nTotalRegistros TO 0
   DEFAULT nTotalTablas TO 1

   ::StartRenderProgress( nTotalRegistros, nTotalTablas )
   ::cPhase := "CSV"
   ::oLabelEstado:cText    := "Preparando CSV..."
   ::oLabelSubtitulo:cText := "Exportando datos estructurados"
   ::oLabelLineas:cText    := "Registros: 0 de " + LTrim( Str( Max( 0, Int( nTotalRegistros ) ) ) )
   ::oLabelPaginas:cText   := "Tabla: 0 de " + LTrim( Str( Max( 1, Int( nTotalTablas ) ) ) )
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD UpdateCSVProgress( nRegistro, nTotalRegistros, nTabla, nTotalTablas ) CLASS TFormLLDominusProgress

   LOCAL nElapsedMs

   IF ::lCanceled
      RETURN .F.
   ENDIF
   ::nUltimaLinea := Max( 0, Int( nRegistro ) )
   ::nTotalLineas := Max( 0, Int( nTotalRegistros ) )
   ::nPaginas := Max( 0, Int( nTabla ) )
   ::nTotalPaginas := Max( 1, Int( nTotalTablas ) )
   ::oLabelEstado:cText := "Generando CSV..."
   ::oProgressBar1:nMin := 0
   ::oProgressBar1:nMax := Max( 1, ::nTotalLineas )
   ::oProgressBar1:nValue := Min( ::nUltimaLinea, ::oProgressBar1:nMax )
   ::oLabelLineas:cText := "Registros: " + LTrim( Str( ::nUltimaLinea ) ) + " de " + LTrim( Str( ::nTotalLineas ) )
   ::oLabelPaginas:cText := "Tabla: " + LTrim( Str( ::nPaginas ) ) + " de " + LTrim( Str( ::nTotalPaginas ) )
   nElapsedMs := Max( 0.0, CurrentMilliseconds() - ::nInicioMs )
   ::oLabelTiempo:cText := "Tiempo transcurrido: " + ::FormatTime( nElapsedMs )
   ::RefreshProgress()

RETURN ! ::lCanceled

//------------------------------------------------------------------------------

METHOD StartXLSXProgress( nTotalRegistros, nTotalTablas ) CLASS TFormLLDominusProgress

   DEFAULT nTotalRegistros TO 0
   DEFAULT nTotalTablas TO 1

   ::StartRenderProgress( nTotalRegistros, nTotalTablas )
   ::cPhase := "XLSX"
   ::oLabelEstado:cText    := "Preparando Excel..."
   ::oLabelSubtitulo:cText := "Exportando datos estructurados"
   ::oLabelLineas:cText    := "Registros: 0 de " + LTrim( Str( Max( 0, Int( nTotalRegistros ) ) ) )
   ::oLabelPaginas:cText   := "Tabla: 0 de " + LTrim( Str( Max( 1, Int( nTotalTablas ) ) ) )
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD UpdateXLSXProgress( nRegistro, nTotalRegistros, nTabla, nTotalTablas ) CLASS TFormLLDominusProgress

   LOCAL lContinue := ::UpdateCSVProgress( nRegistro, nTotalRegistros, nTabla, nTotalTablas )
   ::cPhase := "XLSX"
   ::oLabelEstado:cText := "Generando Excel..."
   ::RefreshProgress()

RETURN lContinue

//------------------------------------------------------------------------------

METHOD UpdateRenderProgress( nObjeto, nTotalObjetos, nPagina, nTotalPaginas ) CLASS TFormLLDominusProgress

   LOCAL nElapsedMs
   LOCAL nPercent

   IF ::lCanceled
      RETURN .F.
   ENDIF

   DEFAULT nObjeto       TO 0
   DEFAULT nTotalObjetos TO 0
   DEFAULT nPagina       TO 0
   DEFAULT nTotalPaginas TO 0

   ::nUltimaLinea  := Max( ::nUltimaLinea, Max( 0, Int( nObjeto ) ) )
   ::nTotalLineas  := Max( 0, Int( nTotalObjetos ) )
   ::nPaginas      := Max( ::nPaginas, Max( 0, Int( nPagina ) ) )
   ::nTotalPaginas := Max( 0, Int( nTotalPaginas ) )

   ::oLabelEstado:cText   := iif( ::cPhase == "PRINT", "Enviando a impresora...", ;
      iif( ::cPhase == "PDF", "Generando PDF...", ;
      iif( ::cPhase == "IMAGE", hb_UTF8ToStr( "Generando imágenes...", "ESWIN" ), ;
      iif( ::cPhase == "CSV", "Generando CSV...", ;
      iif( ::cPhase == "XLSX", "Generando Excel...", "Generando vista previa..." ) ) ) ) )
   ::oProgressBar1:nMin   := 0
   ::oProgressBar1:nMax   := Max( 1, ::nTotalLineas )
   ::oProgressBar1:nValue := Min( ::nUltimaLinea, ::oProgressBar1:nMax )

   nPercent := iif( ::nTotalLineas > 0, Min( 100, Int( ( ::nUltimaLinea * 100 ) / ::nTotalLineas ) ), 0 )
   ::oLabelLineas:cText := "Progreso: " + LTrim( Str( nPercent ) ) + "%"

   IF ::nTotalPaginas > 0
      ::oLabelPaginas:cText := TextPagina() + " " + LTrim( Str( ::nPaginas ) ) + ;
         " de " + LTrim( Str( ::nTotalPaginas ) )
   ELSE
      ::oLabelPaginas:cText := TextPaginas() + ": " + LTrim( Str( ::nPaginas ) )
   ENDIF

   nElapsedMs := Max( 0.0, CurrentMilliseconds() - ::nInicioMs )
   ::oLabelTiempo:cText := "Tiempo transcurrido: " + ::FormatTime( nElapsedMs )
   ::RefreshProgress()

RETURN ! ::lCanceled

//------------------------------------------------------------------------------

METHOD CancelProgress() CLASS TFormLLDominusProgress

   IF ! ::lCanceled
      ::lCanceled                    := .T.
      ::oLabelEstado:cText           := iif( ::cPhase == "RENDER", "Cancelando vista previa...", ;
         iif( ::cPhase == "PRINT", "Cancelando impresion...", ;
         iif( ::cPhase == "PDF", "Cancelando PDF...", ;
         iif( ::cPhase == "IMAGE", hb_UTF8ToStr( "Cancelando imágenes...", "ESWIN" ), ;
         iif( ::cPhase == "CSV", "Cancelando CSV...", ;
         iif( ::cPhase == "XLSX", "Cancelando Excel...", "Cancelando informe..." ) ) ) ) ) )
      ::oButtonCancelar:cText        := "Cancelando..."
      ::oButtonCancelar:lEnabled     := .F.
      ::RefreshProgress()
   ENDIF

RETURN NIL

//------------------------------------------------------------------------------

METHOD FinishProgress() CLASS TFormLLDominusProgress

   LOCAL nElapsedMs := Max( 0.0, CurrentMilliseconds() - ::nInicioMs )

   IF ::lCanceled
      ::oLabelEstado:cText := "Informe cancelado."
   ELSEIF ::cPhase == "RENDER"
      ::oLabelEstado:cText := "Vista previa generada."
      ::oProgressBar1:nValue := ::oProgressBar1:nMax
   ELSEIF ::cPhase == "PRINT"
      ::oLabelEstado:cText := "Informe enviado a impresora."
      ::oProgressBar1:nValue := ::oProgressBar1:nMax
   ELSEIF ::cPhase == "PDF"
      ::oLabelEstado:cText := "PDF generado."
      ::oProgressBar1:nValue := ::oProgressBar1:nMax
   ELSEIF ::cPhase == "IMAGE"
      ::oLabelEstado:cText := hb_UTF8ToStr( "Imágenes generadas.", "ESWIN" )
      ::oProgressBar1:nValue := ::oProgressBar1:nMax
   ELSEIF ::cPhase == "CSV"
      ::oLabelEstado:cText := "CSV generado."
      ::oProgressBar1:nValue := ::oProgressBar1:nMax
   ELSEIF ::cPhase == "XLSX"
      ::oLabelEstado:cText := "Excel generado."
      ::oProgressBar1:nValue := ::oProgressBar1:nMax
   ELSE
      ::oLabelEstado:cText := "Informe generado."
      IF ::nTotalLineas > 0
         ::oProgressBar1:nValue := ::oProgressBar1:nMax
      ENDIF
   ENDIF

   IF ::cPhase == "RENDER" .OR. ::cPhase == "PRINT" .OR. ::cPhase == "PDF" .OR. ::cPhase == "IMAGE" .OR. ::cPhase == "CSV" .OR. ::cPhase == "XLSX"
      ::oLabelLineas:cText  := "Progreso: 100%"
      ::oLabelPaginas:cText := TextPaginas() + ": " + LTrim( Str( ::nPaginas ) )
   ELSE
      ::oLabelLineas:cText  := TextLineas() + " procesadas: " + LTrim( Str( ::nUltimaLinea ) )
      ::oLabelPaginas:cText := TextPaginas() + ": " + LTrim( Str( ::nPaginas ) )
   ENDIF
   ::oLabelTiempo:cText  := "Tiempo total: " + ::FormatTime( nElapsedMs )
   ::RefreshProgress()

RETURN Self

//------------------------------------------------------------------------------

METHOD CloseProgress() CLASS TFormLLDominusProgress

   IF ::lStarted
      ::lStarted := .F.
      ::Close( .T. )

      IF HB_ISOBJECT( ::oOwner )
         IF ::lOwnerWasEnabled
            ::oOwner:Enable()
            ::oOwner:SetFocus()
         ELSE
            ::oOwner:Disable()
         ENDIF
      ENDIF

      ProcessMessages()
   ENDIF

RETURN Self

//------------------------------------------------------------------------------

METHOD RefreshProgress() CLASS TFormLLDominusProgress

   ::Refresh( .T. )
   ::oLabelEstado:Update()
   ::oProgressBar1:Update()
   ::oLabelLineas:Update()
   ::oLabelPaginas:Update()
   ::oLabelTiempo:Update()
   ::oButtonCancelar:Update()
   ::Update()
   ProcessMessages()

RETURN Self

//------------------------------------------------------------------------------

METHOD FormatTime( nElapsedMs ) CLASS TFormLLDominusProgress

   LOCAL nTotalSeconds := Int( Max( 0, nElapsedMs ) / 1000 )
   LOCAL nHours        := Int( nTotalSeconds / 3600 )
   LOCAL nMinutes      := Int( ( nTotalSeconds % 3600 ) / 60 )
   LOCAL nSeconds      := nTotalSeconds % 60

RETURN StrZero( nHours, 2 ) + ":" + StrZero( nMinutes, 2 ) + ":" + StrZero( nSeconds, 2 )

//------------------------------------------------------------------------------

FUNCTION RunLLEngineWithProgress( oLLEngine, oOwner )

   LOCAL oProgress      := NIL
   LOCAL oDocumento     := NIL
   LOCAL oError         := NIL
   LOCAL bErrorAnterior

   IF ! HB_ISOBJECT( oLLEngine )
      RETURN NIL
   ENDIF

   oProgress := TFormLLDominusProgress():New( oOwner )
   oProgress:StartProgress( oOwner )
   oLLEngine:SetProgressCallback( ;
      {| nLinea, nTotal, nPaginas | ;
         oProgress:UpdateProgress( nLinea, nTotal, nPaginas ) } )

   bErrorAnterior := ErrorBlock( {| oErr | Break( oErr ) } )
   BEGIN SEQUENCE
      oDocumento := oLLEngine:RunEngine()
   RECOVER USING oError
      oDocumento := NIL
   END SEQUENCE
   ErrorBlock( bErrorAnterior )

   oLLEngine:SetProgressCallback( NIL )
   IF oError == NIL
      oProgress:FinishProgress()
   ENDIF
   oProgress:CloseProgress()
   oProgress:End()

   IF oError != NIL
      Eval( bErrorAnterior, oError )
   ENDIF

RETURN oDocumento

//------------------------------------------------------------------------------

FUNCTION RunLLEngineAndRenderWithProgress( oLLEngine, oRenderer, oOwner )

   LOCAL oProgress      := NIL
   LOCAL oDocumento     := NIL
   LOCAL oError         := NIL
   LOCAL lRendered      := .F.

   IF ! HB_ISOBJECT( oLLEngine ) .OR. ! HB_ISOBJECT( oRenderer )
      RETURN NIL
   ENDIF

   oProgress := TFormLLDominusProgress():New( oOwner )
   oProgress:StartProgress( oOwner )
   oLLEngine:SetProgressCallback( ;
      {| nLinea, nTotal, nPaginas | ;
         oProgress:UpdateProgress( nLinea, nTotal, nPaginas ) } )

   BEGIN SEQUENCE WITH {| oSequenceError | ProgressErrorHandler( oSequenceError ) }
      oDocumento := oLLEngine:RunEngine()
      oLLEngine:SetProgressCallback( NIL )

      IF HB_ISOBJECT( oDocumento ) .AND. ! oLLEngine:WasCanceled()
         oProgress:StartRenderProgress( 0, oDocumento:TotalPaginas() )
          oRenderer:SetProgressCallback( ;
             {| nObjeto, nTotalObjetos, nPagina, nTotalPaginas | ;
                oProgress:UpdateRenderProgress( ;
                   nObjeto, nTotalObjetos, nPagina, nTotalPaginas ) } )
         lRendered := oRenderer:Render( oDocumento )
         IF ! lRendered .AND. ! oRenderer:WasCanceled() .AND. Len( oRenderer:GetAvisos() ) == 0
            AAdd( oRenderer:aAvisos, "TRenderTPrinter: Render() ha devuelto .F. sin indicar la causa." )
         ENDIF
      ELSEIF ! oLLEngine:WasCanceled() .AND. Empty( oLLEngine:cLastError )
         AAdd( oRenderer:aAvisos, "TLLEngine: RunEngine() ha devuelto NIL sin indicar la causa." )
      ENDIF
   RECOVER USING oError
      oDocumento := NIL
      lRendered  := .F.
      AAdd( oRenderer:aAvisos, ProgressErrorText( oError ) )
   END SEQUENCE

   oLLEngine:SetProgressCallback( NIL )
   oRenderer:SetProgressCallback( NIL )
   IF lRendered
      oProgress:FinishProgress()
   ENDIF
   oProgress:CloseProgress()
   oProgress:End()

   IF ! lRendered
      RETURN NIL
   ENDIF

RETURN oDocumento

//------------------------------------------------------------------------------

FUNCTION RunLLEngineAndPrintWithProgress( oLLEngine, oRenderer, cTitle, oOwner )

   LOCAL oProgress      := NIL
   LOCAL oDocumento     := NIL
   LOCAL oError         := NIL
   LOCAL lPrinted       := .F.

   DEFAULT cTitle TO "LL-Dominus"

   IF ! HB_ISOBJECT( oLLEngine ) .OR. ! HB_ISOBJECT( oRenderer )
      RETURN NIL
   ENDIF

   IF HB_ISOBJECT( oRenderer:oPrinter )
      oRenderer:oPrinter:cJobTitle := cTitle
   ENDIF

   oProgress := TFormLLDominusProgress():New( oOwner )
   oProgress:StartProgress( oOwner )
   oLLEngine:SetProgressCallback( ;
      {| nLinea, nTotal, nPaginas | ;
         oProgress:UpdateProgress( nLinea, nTotal, nPaginas ) } )

   BEGIN SEQUENCE WITH {| oSequenceError | ProgressErrorHandler( oSequenceError ) }
      oDocumento := oLLEngine:RunEngine()
      oLLEngine:SetProgressCallback( NIL )

      IF HB_ISOBJECT( oDocumento ) .AND. ! oLLEngine:WasCanceled()
         oProgress:StartPrintProgress( 0, oDocumento:TotalPaginas() )
         oRenderer:SetProgressCallback( ;
            {| nObjeto, nTotalObjetos, nPagina, nTotalPaginas | ;
               oProgress:UpdateRenderProgress( ;
                  nObjeto, nTotalObjetos, nPagina, nTotalPaginas ) } )
         lPrinted := oRenderer:Print( oDocumento, cTitle )
         IF ! lPrinted .AND. ! oRenderer:WasCanceled() .AND. Len( oRenderer:GetAvisos() ) == 0
            AAdd( oRenderer:aAvisos, "TRenderTPrinter: Print() ha devuelto .F. sin indicar la causa." )
         ENDIF
      ELSEIF ! oLLEngine:WasCanceled() .AND. Empty( oLLEngine:cLastError )
         AAdd( oRenderer:aAvisos, "TLLEngine: RunEngine() ha devuelto NIL sin indicar la causa." )
      ENDIF
   RECOVER USING oError
      oDocumento := NIL
      lPrinted   := .F.
      AAdd( oRenderer:aAvisos, ProgressErrorText( oError ) )
   END SEQUENCE

   oLLEngine:SetProgressCallback( NIL )
   oRenderer:SetProgressCallback( NIL )
   IF lPrinted
      oProgress:FinishProgress()
   ENDIF
   oProgress:CloseProgress()
   oProgress:End()

   IF ! lPrinted
      RETURN NIL
   ENDIF

RETURN oDocumento

//------------------------------------------------------------------------------

STATIC FUNCTION ProgressErrorHandler( oError )

   // Xailer considera la division por cero controlada y devuelve cero.
   IF HB_ISOBJECT( oError ) .AND. oError:genCode == EG_ZERODIV
      RETURN 0
   ENDIF

RETURN Break( oError )

//------------------------------------------------------------------------------

STATIC FUNCTION ProgressErrorText( oError )

   LOCAL cError := "Error durante la generacion del informe."

   IF ! HB_ISOBJECT( oError )
      RETURN cError
   ENDIF
   IF __objHasMsg( oError, "DESCRIPTION" ) .AND. ! Empty( oError:Description )
      cError += " " + oError:Description
   ENDIF
   IF __objHasMsg( oError, "OPERATION" ) .AND. ! Empty( oError:Operation )
      cError += " Operacion: " + oError:Operation + "."
   ENDIF

RETURN cError

//------------------------------------------------------------------------------

STATIC FUNCTION ProgressTitle( cTitle )

   IF Empty( cTitle )
      RETURN "LL-Dominus"
   ENDIF
   IF hb_StrIsUTF8( cTitle )
      RETURN hb_UTF8ToStr( cTitle, "ESWIN" )
   ENDIF

RETURN cTitle

//------------------------------------------------------------------------------

STATIC FUNCTION CurrentMilliseconds()

RETURN hb_TToN( hb_DateTime() ) * 86400000.0

//------------------------------------------------------------------------------

STATIC FUNCTION TextLinea()

RETURN "L" + Chr( 237 ) + "nea"

//------------------------------------------------------------------------------

STATIC FUNCTION TextLineas()

RETURN TextLinea() + "s"

//------------------------------------------------------------------------------

STATIC FUNCTION TextPaginas()

RETURN "P" + Chr( 225 ) + "ginas"

//------------------------------------------------------------------------------

STATIC FUNCTION TextPagina()

RETURN "P" + Chr( 225 ) + "gina"
