unit usimprint;

{$mode delphi}

interface

uses
  Classes, SysUtils, xmatdefs, ucosa, uVarDefs;

type

  { TSimPrint }
  TSimPrint = class
    sala: TCosa;
    id_hilo: integer;
    kCronicaIni, kCronicaFin: integer;
    constructor Create(sala: TCosa; id_hilo, kCronicaIni, kCronicaFin: integer);
    procedure Inicio; virtual; abstract;
    procedure EncabezadoDeCronica; virtual; abstract;
    procedure ResultadosDelPaso; virtual; abstract;
    destructor Destroy; override;

    // auxiliary callback methods
    procedure WriteEncab(s: string); virtual; abstract;
    procedure WriteResultados(s: string); virtual; abstract;
    procedure printEncabezadoResumenSim(nombre, tipo, infoad: string);
      virtual; abstract;
    procedure printResumenSim(nombre, tipo, infoad: string); virtual; abstract;
  end;



  { TSimPrint_text }
  TSimPrint_text = class(TSimPrint)
    constructor Create(sala: TCosa; id_hilo, kCronicaIni, kCronicaFin: integer);
    procedure Inicio; override;
    procedure EncabezadoDeCronica; override;
    procedure ResultadosDelPaso; override;
    destructor Destroy; override;

    // auxiliary callback methods
    procedure WriteEncab(s: string); override;
    procedure WriteResultados(s: string); override;
    procedure printEncabezadoResumenSim(nombre, tipo, infoad: string); override;
    procedure printResumenSim(nombre, tipo, infoad: string); override;

  private
    archi_fsal: string;
    fsal: Textfile;
  end;

  { TBuffPaso }

  TBuffPaso = class
    pos: qword;
    pdata: pointer;
    size: qword;
    constructor Create(size: qword);
    constructor CreateReadFromStream(s: TStream);
    procedure reset;
    procedure write(var source; dsize: integer);
    procedure WriteToStream(s: TStream);
    destructor Destroy; override;
  end;

  PDataPtrRec = ^TDataPtrRec;

  TDataPtrRec = record
    pdata: pointer;
    size: word;
  end;

type


  { TActorRec }

  TActorRec = class
    Nombre, TipoDeActor, InformacionAdicional: string;
    constructor Create( xNombre, xTipoDeActor, xInformacionAdicional: string );
    constructor CreateReadFromStream( s: TStream );
    procedure WriteToStream( s: TStream );
  end;

  { TActoreRec_lst }

  TActoreRec_lst = class( TList )
    procedure addActor( xNombre, xTipoDeActor, xInformacionAdicional: string );
    destructor destroy; override;
    constructor CreateLoadFromStream( s: TStream );
    procedure WriteToStream( s: TStream );
  end;


  TSimPrint_bin = class;

  { TSimPrint_REC }

  TSimPrint_REC = class
    vSimSEESimulador_: string;
    dt_Creacion: TDateTime;
    dt_fechaIniSim, dt_fechaFinSim: TDateTime;
    NCronicasSim: integer;
    NPasos: integer;
    NPostes: integer;
    DurPos: TDAOfNReal;
    NActores: integer;

    nCols: integer;
    ColsCap_arr: array of TStringList;
    ActorRec_lst: TActoreRec_lst;

    constructor Create;
    procedure completarFromSimPrint( SimPrint: TSimPrint_bin );
    constructor CreateReadFromStream( s: TStream );
    procedure WriteToStream( s: TStream );
    destructor destroy; override;
  private
    procedure WriteColsCap(kEncab: integer; s: TStream);
  end;



  { TCronciaEncab_bin }

  TCronciaEncab_bin = class
    kCronica: integer;
    semMadreUniforme: integer;
    semsIds: string;
    constructor Create( kCronica, semMadreUniforme: integer; semsIds: string );
    constructor CreateReadFromStream( s: TStream );
    procedure WriteToStream( s: TStream );
  end;

  { TSimPrint_bin }
  TSimPrint_bin = class(TSimPrint)
    ColsCap_activa: TStringList; // apunta a una del array anterior.

    constructor Create(sala: TCosa; id_hilo, kCronicaIni, kCronicaFin: integer);
    procedure Inicio; override;
    procedure EncabezadoDeCronica; override;
    procedure ResultadosDelPaso; override;
    destructor Destroy; override;

    // auxiliary callback methods
    procedure WriteEncab(s: string); override;
    procedure printEncabezadoResumenSim(nombre, tipo, infoad: string); override;
    procedure printResumenSim(nombre, tipo, infoad: string); override;

  private
    buffpaso: TBuffPaso;
    archi_fsal: string;
    fsal: TFileStream;
    SimPrint_rec: TSimPrint_REC;
    DataPtrRecs: TList;
    buffer_size: qword;
    procedure PrintEncabs( kEncab: integer );
    procedure CrearListaPDataRecs;
    procedure addDataPtrRecs(vars: TListaVarDefs);
    procedure freeDataPtrRecs;
  end;


implementation

uses
  usalasdejuego, uActores, uFuentesAleatorias,
  uConstantesSimSEE, uauxiliares, ufechas, uversiones;

{ TActoreRec_lst }

procedure TActoreRec_lst.addActor(xNombre, xTipoDeActor,
  xInformacionAdicional: string);
var
  aActorRec: TActorRec;
begin
  aActorRec:= TActorRec.Create( xNombre, xTipoDeActor, xInformacionAdicional );
  add( aActorRec );
end;

destructor TActoreRec_lst.destroy;
var
  k: integer;
begin
  for k:= 0 to count -1 do
    TActorRec( items[k] ).Free;
  inherited destroy;
end;

constructor TActoreRec_lst.CreateLoadFromStream(s: TStream);
var
  k: integer;
  n: integer;
  aActorRec: TActorRec;

begin
  inherited Create;
  s.Read( n, sizeOf( n ) );
  for k:= 1 to n do
  begin
    aActorRec:= TActorRec.CreateReadFromStream( s );
    add( aActorRec );
  end;
end;

procedure TActoreRec_lst.WriteToStream(s: TStream);
var
  k: integer;
  n: integer;
  aActorRec: TActorRec;
begin
  n:= count;
  s.write( n, sizeOf( n ) );
  for k:= 0 to count -1 do
  begin
    aActorRec:= items[k];
    aActorRec.WriteToStream( s );
  end;
end;

{ TActorRec }

constructor TActorRec.Create(xNombre, xTipoDeActor,
  xInformacionAdicional: string);
begin
  inherited Create;
  Nombre:= xNombre;
  TipoDeActor:= xTipoDeActor;
  InformacionAdicional:= xInformacionAdicional;
end;

constructor TActorRec.CreateReadFromStream(s: TStream);
begin
  inherited Create;
  Nombre:= s.ReadAnsiString;
  TipoDeActor:= s.ReadAnsiString;
  InformacionAdicional:= s.ReadAnsiString;
end;

procedure TActorRec.WriteToStream(s: TStream);
begin
  s.WriteAnsiString( Nombre );
  s.WriteAnsiString( TipoDeActor );
  s.WriteAnsiString( InformacionAdicional );
end;

{ TCronciaEncab_bin }

constructor TCronciaEncab_bin.Create(kCronica, semMadreUniforme: integer;
  semsIds: string);
begin
  inherited Create;
  self.kCronica:= kCronica;
  self.semMadreUniforme:= semMadreUniforme;
  self.semsIds:= semsIds;
end;

constructor TCronciaEncab_bin.CreateReadFromStream(s: TStream);
begin
  inherited Create;
  s.Read( kCronica, sizeOf( kCronica ));
  s.Read( semMadreUniforme, SizeOf( semMadreUniforme ) );
  semsIds:= s.ReadAnsiString;
end;

procedure TCronciaEncab_bin.WriteToStream(s: TStream);
begin
  s.Write( kCronica, sizeOf( kCronica ));
  s.Write( semMadreUniforme, SizeOf( semMadreUniforme ) );
  s.WriteAnsiString( semsIds );
end;

{ TBuffPaso }

constructor TBuffPaso.Create(size: qword);
begin
  inherited Create;
  self.size := size;
  pdata := getmem(size);
end;

constructor TBuffPaso.CreateReadFromStream(s: TStream);
var
  N: integer;
begin
  inherited Create;
  s.Read(size, SizeOf(size));
  Create(size);
  s.Read(pdata^, size);
end;

procedure TBuffPaso.reset;
begin
  pos:= 0;
end;

procedure TBuffPaso.write(var source; dsize: integer);
begin
    Move( source, (pdata + pos)^, dsize );
    Inc(pos, dsize );
end;

procedure TBuffPaso.WriteToStream(s: TStream);
begin
  s.Write(size, SizeOf(size));
  s.Write(pdata^, size);
end;

destructor TBuffPaso.Destroy;
begin
  Freemem(pdata, size);
  inherited Destroy;
end;

{ TSimPrint_REC }

constructor TSimPrint_REC.Create;
begin
  inherited Create;
  nCols := 0;
  ActorRec_lst:= TActoreRec_lst.Create;
end;

procedure TSimPrint_REC.completarFromSimPrint(SimPrint: TSimPrint_bin);
var
  kActor, kEncab: integer;
begin
  with SimPrint.sala as TSalaDeJuego do
  begin
    self.vSimSEESimulador_:= vSimSEESimulador_;
    self.dt_Creacion := now;
    self.dt_fechaIniSim := globs.fechaIniSim.dt;
    self.dt_fechaFinSim := globs.fechaFinSim.dt;
    self.NCronicasSim:= globs.NCronicasSim_global_;
    self.nPasos:= globs.nPasos;
    self.DurPos:= copy( globs.Durpos );

    for kActor := 0 to high(actores) do
      actores[ kActor ].printResumenSim( SimPrint );

  end;
  setlength( ColsCap_arr, 4 );
  for kEncab:= 0 to high( ColsCap_arr ) do
  begin
    ColsCap_arr[kEncab] := TStringList.Create;
    SimPrint.ColsCap_activa:= ColsCap_arr[kEncab];
    SimPrint.PrintEncabs( kEncab );
    SimPrint.ColsCap_activa:= nil;
  end;

end;

constructor TSimPrint_REC.CreateReadFromStream(s: TStream);
var
  n: integer;
  kColCap: integer;
  kEncab: integer;
  ts: AnsiString;

begin
  inherited Create;
    vSimSEESimulador_:= s.ReadAnsiString;
    s.Read( dt_Creacion, sizeOf( dt_Creacion ) );
    s.Read( dt_fechaIniSim, SizeOf( dt_FechaIniSim ) );
    s.Read( dt_fechaFinSim, SizeOf( dt_fechaFinSim  ));
    s.Read( NCronicasSim, SizeOf( NCronicasSim ) );
    s.Read(nPasos, SizeOf( nPasos ));
    s.Read( n, sizeOf( n ) );
    setlength( durPos, n );
    s.Read( durpos[0], n *  sizeOf( durpos[0] ) );

    s.Read(n, sizeOf(n));

    ActorRec_lst:= TActoreRec_lst.CreateLoadFromStream( s );

    s.Read( n, sizeOf( n ) );
    setlength( ColsCap_arr, n );
    for kEncab:= 0 to high( ColsCap_arr ) do
    begin
      ColsCap_arr[ kEncab ]:= TStringList.Create;
      s.Read( n, sizeOf( n ) );
      for kColCap:= 0 to n -1 do
      begin
        ts:= s.ReadAnsiString;
        ColsCap_arr[ kEncab ].Add( ts );
      end;
    end;
end;

procedure TSimPrint_REC.WriteToStream(s: TStream);
var
  n: integer;
  kColCap: integer;
  kEncab: integer;

begin
  s.WriteAnsiString(vSimSEESimulador_);
  s.Write( dt_Creacion, sizeOf( dt_Creacion ) );
  s.Write( dt_fechaIniSim, SizeOf( dt_FechaIniSim ) );
  s.Write( dt_fechaFinSim, SizeOf( dt_fechaFinSim  ));
  s.Write( NCronicasSim, SizeOf( NCronicasSim ) );
  s.Write(nPasos, SizeOf( nPasos ));
  n:= length( durPos );
  s.Write( n, sizeOf( n ) );
  s.write( durpos[0], n *  sizeOf( durpos[0] ) );

  ActorRec_lst.WriteToStream( s );

  n:= length( ColsCap_arr );
  s.Write( n, sizeOf( n ) );
  for kEncab:= 0 to high( ColsCap_arr ) do
  begin
    n:= ColsCap_arr[ kEncab ].count;
    s.write( n, sizeOf( n ) );
    for kColCap:= 0 to ColsCap_arr[ kEncab ].count -1 do
      s.WriteAnsiString( ColsCap_arr[ kEncab ][kColCap] );
  end;
end;

destructor TSimPrint_REC.destroy;
var
  kEncab: integer;
begin
  ActorRec_lst.Free;

  for kEncab:= 0 to high( ColsCap_arr ) do
    ColsCap_arr[kEncab].Free;
  setlength( ColsCap_arr, 0 );

  inherited destroy;
end;

procedure TSimPrint_REC.WriteColsCap( kEncab: integer; s: TStream );
var
  k, N: integer;
begin
  N:= ColsCap_arr[kEncab].Count;
  s.Write(N, SizeOf(N));
  for k := 0 to ColsCap_arr[kEncab].Count - 1 do
    s.WriteAnsiString(ColsCap_arr[kEncab][k]);
end;



{ TSimPrint_bin }

constructor TSimPrint_bin.Create(sala: TCosa;
  id_hilo, kCronicaIni, kCronicaFin: integer);
begin
  inherited Create(sala, id_hilo, kCronicaIni, kCronicaFin);

  with sala as TSalaDeJuego do
  begin
    //Creo el archivo de simres
    if not DirectoryExists(dirResultadosCorrida) then
      MkDir(dirResultadosCorrida);

    archi_fsal := dirResultadosCorrida + 'simres' + '_' +
      IntToStr(globs.semilla_inicial_sim)
      //+ 'x' + IntToStr(Globs.NCronicasSim)
      + '_' + EscenarioActivo.nombre;

    archi_fsal := archi_fsal + '_d' + padNd(IntToStr(kCronicaIni), 5) +
      'a' + padNd(IntToStr(kCronicaFin), 5) + 'h' + IntToStr(id_hilo);

    archi_fsal := archi_fsal + '.rsb';
    fsal := TFileStream.Create(archi_fsal, fmCreate);
    fsal.Size := 0; // trunco si ya existia
  end;
  buffpaso := nil;
  DataPtrRecs := nil;
  buffer_size := 0;
end;

procedure TSimPrint_bin.Inicio;
begin
  SimPrint_REC:= TSimPRint_REC.Create;
  SimPrint_REC.completarFromSimPrint( self );
  SimPrint_REC.WriteToStream( fsal );

  // ahora contamos las variables y obtenemos listado de punteros a datos y tamaños para
  // luego poder salvar eficientemente en un buffer los resultados
  // y calcula buffer_size
  CrearListaPDataRecs;

  buffpaso := TBuffPaso.Create(buffer_size);

  SimPrint_REC.Free;

end;

procedure TSimPrint_bin.EncabezadoDeCronica;
var
  kfuenterres: integer;
  idCronInicio, s: string;
  aEncab: TCronciaEncab_bin;
begin

  with sala as TSalaDeJuego do
  begin

    s:= '';
    for kfuenterres := 0 to lst_Sim_cronicaIdInicio.Count - 1 do
    begin
      idCronicaInicioFuenteK :=
        TFuenteAleatoria(lst_Sim_cronicaIdInicio[kfuenterres]).cronicaIdInicio;
      if idCronicaInicioFuenteK <> '' then
        s:= s+#9+idCronicaInicioFuenteK;
    end;

    aEncab:= TCronciaEncab_bin.Create( globs.kCronica_, globs.MadresUniformes.get_UltimaSemilla, s );
    aEncab.WriteToStream( fsal );
    aEncab.Free;
  end;
end;

procedure TSimPrint_bin.ResultadosDelPaso;
var
  kRec: integer;
  pRec: PDataPtrRec;
begin
  buffpaso.reset;

  with sala as TSalaDeJuego do
  begin
    buffpaso.write( globs.kPaso_Sim,  sizeOf(globs.kPaso_Sim));
    buffpaso.write(globs.FechaInicioDelPaso.dt,  sizeOf(TDateTime));
  end;

  for kRec := 0 to DataPtrRecs.Count - 1 do
  begin
    pRec := DataPtrRecs[kRec];
    buffpaso.write(pRec.pdata^, pRec^.size);
  end;

  buffpaso.WriteToStream(fsal);
end;


destructor TSimPrint_bin.Destroy;
var
  k: integer;
begin
  freeDataPtrRecs;
  if buffpaso <> nil then
    buffpaso.Free;
  inherited Destroy;
end;

procedure TSimPrint_bin.WriteEncab(s: string);
var
  arr: TStringList;
begin
  arr := TStringList.Create;
  arr.Delimiter := #9;
  arr.Text := s;
  ColsCap_activa.AddStrings(arr);
end;

procedure TSimPrint_bin.printEncabezadoResumenSim(nombre, tipo, infoad: string);
begin
  fsal.WriteAnsiString(nombre);
  fsal.WriteAnsiString(tipo);
  fsal.WriteAnsiString(infoad);
end;

procedure TSimPrint_bin.printResumenSim(nombre, tipo, infoad: string);
var
  aActorRec: TActorRec;
begin
  aActorRec:= TActorRec.Create( nombre, tipo, infoad );
  SimPrint_REC.ActorRec_lst.add( aActorRec );
end;


procedure TSimPrint_bin.PrintEncabs(kEncab: integer);
var
  N: integer;
  k: integer;
  kActorRes, kFuenteRes: integer;

begin
  with sala as TSalaDeJuego do
  begin
    for kactorres := 0 to high(actores) do
      actores[kactorres].sim_PrintResultados_Encab(self, kEncab);
    for kfuenteres := 0 to high(fuentes) do
      fuentes[kfuenteres].sim_PrintResultados_Encab(self, kEncab);

    // esto sí es de la sala y hay que reescribirlo
    sim_PrintResultados_Encab(self, kEncab);
    {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      intermediario.sim_PrintResultados_Encab(self, kEncab);
    {$ENDIF}
  end;
end;

procedure TSimPrint_bin.CrearListaPDataRecs;
var
  kActor, kFuente: integer;
begin
  DataPtrRecs := TList.Create;

  with sala as TSalaDeJuego do
  begin
    buffer_size := sizeOf(globs.kPaso_Sim) + sizeOf(TDateTime);

    for kActor := 0 to high(actores) do
    begin
 //     writeln( 'kActor: ', kActor );
      addDataPtrRecs(actores[kActor].variablesParaSimRes);
    end;
    for kFuente := 0 to high(fuentes) do
    begin
//      writeln( 'kFuente: ', kFuente );
      addDataPtrRecs(fuentes[kFuente].variablesParaSimRes);
    end;

    writeln( 'Sala: ' );
    addDataPtrRecs(variablesParaSimRes);
    {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      addDataPtrRecs(intermediario.variablesParaSimRes);
    {$ENDIF}
  end;
end;

procedure TSimPrint_bin.addDataPtrRecs(vars: TListaVarDefs);
var
  kVar: integer;
  pRec: PDataPtrRec;
  aVar: TVarDef;
begin
  for kVar := 0 to vars.Count - 1 do
  begin
    new(pRec);
    aVar := vars[kVar];
    pRec^.pdata := aVar.getptr;
    pRec^.size := aVar.size;
    DataPtrRecs.add(pRec);
    buffer_size := buffer_size + pRec^.size;
  end;
end;

procedure TSimPrint_bin.freeDataPtrRecs;
var
  kRec: integer;
  pRec: PDataPtrRec;
begin
  if DataPtrRecs <> nil then
  begin
    for kRec := 0 to DataPtrRecs.Count - 1 do
    begin
      pRec := DataPtrRecs[kRec];
      dispose(pRec);
    end;
    DataPtrRecs.Free;
    DataPtrRecs := nil;
  end;
end;


{ TSimPrint_text }

constructor TSimPrint_text.Create(sala: TCosa;
  id_hilo, kCronicaIni, kCronicaFin: integer);

begin
  inherited Create(sala, id_hilo, kCronicaIni, kCronicaFin);

  with sala as TSalaDeJuego do
  begin
    //Creo el archivo de simres
    if not DirectoryExists(dirResultadosCorrida) then
      MkDir(dirResultadosCorrida);

    archi_fsal := dirResultadosCorrida + 'simres' + '_' +
      IntToStr(globs.semilla_inicial_sim)
      //+ 'x' + IntToStr(Globs.NCronicasSim)
      + '_' + EscenarioActivo.nombre;

    archi_fsal := archi_fsal + '_d' + padNd(IntToStr(kCronicaIni), 5) +
      'a' + padNd(IntToStr(kCronicaFin), 5) + 'h' + IntToStr(id_hilo);

    archi_fsal := archi_fsal + '.xlt';

    assignfile(fsal, archi_fsal);
    rewrite(fsal);
  end;
end;

procedure TSimPrint_text.printEncabezadoResumenSim(nombre, tipo, infoad: string);
begin
  writeln(fsal, nombre, #9, tipo, #9, infoad);
end;

procedure TSimPrint_text.printResumenSim(nombre, tipo, infoad: string);
begin
  writeln(fsal, nombre, #9, tipo, #9, Infoad);
end;

procedure TSimPrint_text.Inicio;
var
  iposteres, kactorres: integer;
begin
  with sala as TSalaDeJuego do
  begin
    system.Writeln(fsal, 'Versión del simulador:'#9, vSimSEESimulador_);
    system.writeln(fsal, 'Inicio simulación: '#9, DateTimeToIsoStr(now()));
    system.Writeln(fsal, 'FechaIniSim:'#9, globs.fechaIniSim.AsISOStr,
      #9'FechaFinSim:'#9, globs.fechaFinSim.AsISOStr);
    system.writeln(fsal, 'NCronicas:'#9, globs.NCronicasSim_global_);
    system.writeln(fsal, 'NPasos:'#9, globs.nPasos);
    system.writeln(fsal, 'NPostes:'#9, length(globs.Durpos));
    system.Write(fsal, 'DurPos[h]:');
    for iposteres := 0 to high(globs.DurPos) do
      Write(fsal, #9, globs.DurPos[iposteres]);
    system.writeln(fsal);
    system.writeln(fsal, 'NActores:'#9, length(actores));
    TActor.printEncabezadoResumenSim(self);
    for kactorres := 0 to high(actores) do
      actores[kactorres].printResumenSim(self);
  end;
end;

procedure TSimPrint_text.EncabezadoDeCronica;
var
  kfuenterres, kactorres: integer;
begin
  with sala as TSalaDeJuego do
  begin
    writeln(fsal);
    Write(fsal, 'CRONICA:', #9, globs.kCronica_, #9, 'SemillaAleatoria:', #9,
      globs.MadresUniformes.get_UltimaSemilla);
    for kfuenterres := 0 to lst_Sim_cronicaIdInicio.Count - 1 do
    begin
      idCronicaInicioFuenteK :=
        TFuenteAleatoria(lst_Sim_cronicaIdInicio[kfuenterres]).cronicaIdInicio;
      if idCronicaInicioFuenteK <> '' then
        Write(fsal, #9, idCronicaInicioFuenteK);
    end;
    writeln(fsal);

    // PRINT kencab= 0
    Write(fsal, '-', #9, '-');
    // estos dos guiones estan abajo de donde dice CRONICA y kCronica, lo mismo el resto
    for kactorres := 0 to high(actores) do
      actores[kactorres].sim_PrintResultados_Encab(self, 0);
    for kfuenterres := 0 to high(fuentes) do
      fuentes[kfuenterres].sim_PrintResultados_Encab(self, 0);

    // esto sí es de la sala y hay que reescribirlo
    sim_PrintResultados_Encab(self, 0);
      {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      intermediario.sim_PrintResultados_Encab(self, 0);
      {$ENDIF}
    writeln(fsal);

    // PRINT kencab= 1
    Write(fsal, '-', #9, '-');
    for kactorres := 0 to high(actores) do
      actores[kactorres].sim_PrintResultados_Encab(self, 1);
    for kfuenterres := 0 to high(fuentes) do
      fuentes[kfuenterres].sim_PrintResultados_Encab(self, 1);

    // estas son las unidades de la sala
    sim_PrintResultados_Encab(self, 1);
      {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      intermediario.sim_PrintResultados_Encab(self, 1);
      {$ENDIF}
    writeln(fsal);

    // PRINT kencab= 2
    Write(fsal, '-', #9, '-');
    for kactorres := 0 to high(actores) do
      actores[kactorres].sim_PrintResultados_Encab(self, 2);

    for kfuenterres := 0 to high(fuentes) do
      fuentes[kfuenterres].sim_PrintResultados_Encab(self, 2);

    // estas son las variables de la sala

    sim_PrintResultados_Encab(self, 2);
    {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      intermediario.sim_PrintResultados_Encab(self, 2);
    {$ENDIF}
    writeln(fsal);

    // PRINT kencab= 3
    Write(fsal, 'Paso', #9, 'FechaInicioDelPaso');
    for kactorres := 0 to high(actores) do
      actores[kactorres].sim_PrintResultados_Encab(self, 3);
    for kfuenterres := 0 to high(fuentes) do
      fuentes[kfuenterres].sim_PrintResultados_Encab(self, 3);

    // poste
    sim_PrintResultados_Encab(self, 3);
    {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      intermediario.sim_PrintResultados_Encab(self, 3);
    {$ENDIF}
    writeln(fsal);
  end;
end;

procedure TSimPrint_text.ResultadosDelPaso;
var
  kactorres, kfuenterres: integer;
begin
  with sala as TSalaDeJuego do
  begin
    Write(fsal, IntToStr(globs.kPaso_Sim), #9, globs.FechaInicioDelPaso.AsISOStr);
    for kactorres := 0 to high(actores) do
      actores[kactorres].sim_PrintResultados(self);
    for kfuenterres := 0 to high(fuentes) do
      fuentes[kfuenterres].sim_PrintResultados(self);

    sim_PrintResultados(self);

    {$IFDEF INTERMEDIARIO_DE_COSTO_FUTURO}
    if intermediario <> nil then
      intermediario.sim_PrintResultados(self);
    {$ENDIF}
    writeln(fsal);
  end;
end;




destructor TSimPrint_text.Destroy;
begin
  system.writeln(fsal, 'Fin simulación:'#9, DateTimeToIsoStr(now()));
  closefile(fsal);
  inherited Destroy;
end;

procedure TSimPrint_text.WriteEncab(s: string);
begin
  system.Write(fsal, #9, s);
end;

procedure TSimPrint_text.WriteResultados(s: string);
begin
  system.Write(fsal, #9, s);
end;

{ TSimPrint }

constructor TSimPrint.Create(sala: TCosa; id_hilo, kCronicaIni, kCronicaFin: integer);
begin
  self.sala := sala;
  self.id_hilo := id_hilo;
  self.kCronicaIni := kCronicaIni;
  self.kCronicaFin := kCronicaFin;

end;


destructor TSimPrint.Destroy;
begin
  inherited Destroy;
end;

end.
