//  CAFE2011.EXE is licensed under the terms of the CC-LGPL.
//  (CC-LGPL Version 3, 29 junio 2007 y CAFE2011 version 2011)
//  El objetivo es el libre uso comercial y no comercial del software.
//  Una copia de dicho documento se incluye en esta distribucion.
//  CWSDPMI.EXE, STREAMCO.PAS, el procedimiento TextOut
//  se tomaron de la distribucion FreePascal 2.4.2. con patente similar.
//        StreamCo.PAS es una contraccion conveniente a ocho letras del
//        nombre StreamColl.PAS en la distribucion FreePascal
  {$MODE                OBJFPC          }
  {$INCLUDEPATH         ..\INCLUDE      }
  {$INCLUDE             CAFE_INC.INC    }
  {$DEFINE              SILENCIAR       }
// Al eliminar ExternoCAFE se ha detectado inestabilidad
// Probablemente el ReWrite y el Reset en CAFE_Tu1
// informen al FreeDOS, y este accione un sistema de alerta
// Yo esperaba que no hubiera problemas, debido
// al tipo TMemoryStream
// Se propaga la inestabildiad al modo ExternoCAFE, no lo se en este momento
UNIT CafUtils;

INTERFACE
USES
  SysUtils, Classes ,
  CAFE_Ej1, CAFE_Ej2, CAFE_Ej3, CAFE_Tu1, CAFE_Ej4, CAFE_Ej5;

CONST
  CAFE_Title            : ShortString   = 'LibreCAFE';

TYPE
  SysCafeModo           = ( DefaultModoCAFE, PipeCAFE,
                                        BreveCAFE, ExternoCAFE );
  SetSysCafeModo        = SET OF SysCafeModo;

  ECAFEError            = CLASS ( Exception ) END;

  SysCafe               = CLASS  ( CAFE_TriplePipeTraductor )

  Class
PROCEDURE   Activar
  (       ModoActivar   : SetSysCafeModo                                );

  Class
FUNCTION    EsModoCoherente
  ( VAR   ModoActivar   : SetSysCafeModo                        ) : Boolean;

  Class
PROCEDURE   CAFECompleted
  (       ListaRespuesta        : TStringList;
    CONST MyOrden               : ShortString;
          ListaError            : TStringList   = NIL                   );

  Class
PROCEDURE   Desactivar;

  Protected
PROCEDURE   DoRun; override;

    Public
    Property
  CAFEInput                     : TextFile READ Pipe_In;

    Public
    Property
  CAFEOutput                    : TextFile READ Pipe_Out;

    Public
    Property
  CAFEStdErr                    : TextFile READ Pipe_StdErr;

                          END;  { SysCafe }

VAR
  CAFE                          : SysCafe;

IMPLEMENTATION

  Class
PROCEDURE   SysCafe.Activar
  (       ModoActivar   : SetSysCafeModo                                );
BEGIN  { PROCEDURE SysCafe.Activar }
  IF NOT( EsModoCoherente( ModoActivar ) ) THEN BEGIN
    RAISE ECAFEError.Create( 'Intento de crear modo CAFE incoherente' );
  END;  { IF IncoherenteModo( ModoActivar ) }
  Inherited;
  CAFE_TipoCollectionPrincipal.Activar;
  CAFE_Application            := CAFE_ReferenciaApplication.Create( NIL )
                as CAFE_TriplePipeMemory;
  WITH ( CAFE_Application as SysCafe ) DO BEGIN
    IF PipeCAFE IN ModoActivar THEN BEGIN
      BanderaDirectoSubordinado   := FALSE;
      ModalidadTraductor          := [ BiunivocoInputMOET ];
    END;  { IF PipeCAFE IN ModoActivar }
    IF BreveCAFE IN ModoActivar THEN BEGIN
      BanderaDirectoSubordinado := FALSE;
      ModalidadTraductor        := [ BiunivocoInputMOET, SoloResultadoMOET ];
    END;  { IF BreveCAFE IN ModoActivar }
    IF ExternoCAFE IN ModoActivar THEN BEGIN
      BanderaTIOStream          := TRUE;
    END ELSE BEGIN  { IF ExternoCAFE IN ModoActivar }
      Include( ModalidadTraductor, DirectoInputMOET );
      IF PipeCAFE IN ModoActivar THEN BanderaDirectoSubordinado := TRUE;
    END;            { IF ExternoCAFE IN ModoActivar }
  END;  { WITH CAFE_Application }
  CAFE_Application.Initialize;
  CAFE_RaizManejadores.GetInterfaceByStr
      ( CAFE_GUIDInterfacePipe, CAFE_Application.InterfaceEjecutora );
  CAFE                          := CAFE_Application as SysCafe;
  CAFE.Title                    := CAFE_Title;
  IF NOT( ExternoCAFE IN ModoActivar ) THEN ReWrite( CAFE.Pipe_In );
END;   { PROCEDURE SysCafe.Activar }

  Class
FUNCTION    SysCafe.EsModoCoherente
  ( VAR   ModoActivar   : SetSysCafeModo                        ) : Boolean;
BEGIN  { FUNCTION SysCafe.EsModoCoherente }
  EsModoCoherente       := FALSE;
  IF [ PipeCAFE, DefaultModoCAFE ]*ModoActivar <> [] THEN BEGIN
    IF ( ModoActivar-[ PipeCAFE, DefaultModoCAFE, ExternoCAFE ] ) =  [ ]
    THEN BEGIN
      EsModoCoherente          := TRUE;
      ModoActivar              := [ PipeCAFE ]+ModoActivar*[ ExternoCAFE ];
    END;  { IF ExternoActivar IN ModoActivar }
  END;  { IF [ PipeCAFE, DefaultModoCAFE ]*ModoActivar <> [] }
  IF ModoActivar <= [ BreveCAFE, ExternoCAFE ] THEN BEGIN
    IF BreveCAFE IN ModoActivar THEN BEGIN
      EsModoCoherente          := TRUE;
    END;  { IF BreveCAFE IN ModoActivar }
  END;  { IF ModoActivar = [ BreveCAFE ] }
END;   { FUNCTION SysCafe.EsModoCoherente }

PROCEDURE   SysCafe.DoRun;
BEGIN  { PROCEDURE SysCafe.OnRun }
  Inherited;
  WaitOnCompleted;
END;   { PROCEDURE SysCafe.OnRun }

  Class
PROCEDURE   SysCafe.CAFECompleted
  (       ListaRespuesta        : TStringList;
    CONST MyOrden               : ShortString;
          ListaError            : TStringList   = NIL                   );
BEGIN  { PROCEDURE SysCafe.CAFECompleted }
  CAFE.ResultadoWaitOnCompleted( ListaRespuesta, MyOrden, ListaError );
END;   { PROCEDURE SysCafe.CAFECompleted }

  Class
PROCEDURE   SysCafe.Desactivar;
BEGIN  { PROCEDURE SysCafe.Activar }
  FreeAndNil( CAFE_Application );
  CAFE                          := NIL;
  CAFE_TipoCollectionPrincipal.Desactivar;
  Inherited;
END;   { PROCEDURE SysCafe.Activar }

INITIALIZATION  { Bloque Initialization }
  CAFE_ReferenciaApplication    := SysCafe;
  CAFE_TipoCollectionPrincipal  := CAFE_TCollectionManejadorString;
END.            { Bloque Initialization }
