unit uMonitorArchivo;
{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface

uses
  uMonitores, uEventosOptSim,
  uVarDefs, SysUtils, Classes, uSalasDeJuego, ucosa, xmatdefs;

type

  TDAofMsgs = array[TEventoOptSim] of string;

  { TEventoOptSimMsgs }

  TEventoOptSimMsgs = class(TCosa)
  private
    function GetMsg(ev: TEventoOptSim): string;
    procedure SetMsg(ev: TEventoOptSim; AValue: string);
  protected
    // Eventos durante una optimización
    Opt_Inicio: string;
    Opt_InicioCalculosEtapa: string;
    Opt_InicioCronicaSorteos: string;
    Opt_PrepararPaso_ps: string;
    Opt_FinCronicaSorteos: string;
    Opt_FinCalculosEtapa: string;
    Opt_Fin: string;

    // Eventos durante una simulación
    Sim_Inicio: string;
    Sim_InicioCronica: string;
    Sim_InicioPaso: string;
    Sim_FinPaso: string;
    Sim_FinCronica: string;
    Sim_Fin: string;

    constructor Create;
    property msg[ev: TEventoOptSim]: string read GetMsg write SetMsg; default;
  end;

  TMonArchivo = class(TMonitores)
  private
    abierto: boolean; //indica si el archivo esta abierto
    defVars: TDAOfVarDef;
    f: TextFile;
    filename: string;
  public

    mensajes: TDAofMsgs;
    constructor Create(defVars: TList{of TVarDef}; filename: string; msgs: TDAofMsgs);




    function resolverRefProc(refProc: integer): TProcWrapper; override;
    class function darRefProc(nombreProc: string; evento: TEventoOptSim): integer;
      override;

    procedure AbrirArchivo;
    procedure CerrarArchivo;
    procedure Escribir;

    procedure EscribirMsgInicioSimulacion;
    procedure EscribirMsgInicioCronica;
    procedure EscribirMsgInicioPaso;
    procedure EscribirMsgFinPaso;
    procedure EscribirMsgFinCronica;
    procedure EscribirMsgFinSimulacion;

    procedure EscribirMsgInicioOptimizacion;
    procedure EscribirMsgInicioCronicaOptimizacion;
    procedure EscribirMsgInicioPasoOptimizacion;
    procedure EscribirMsgFinPasoOptimizacion;
    procedure EscribirMsgFinCronicaOptimizacion;
    procedure EscribirMsgFinOptimizacion;

    procedure Free; override;
  end;

procedure AlInicio;
procedure AlFinal;

implementation

procedure AlInicio;
begin
  registrarClaseDeCosa(TEventoOptSimMsgs.ClassName, TEventoOptSimMsgs);
end;

procedure AlFinal;
begin

end;

{ TEventoOptSimMsgs }

function TEventoOptSimMsgs.GetMsg(ev: TEventoOptSim): string;
begin
  case ev of
    // Eventos durante una optimización
    E_Opt_Inicio: Result := Opt_Inicio;
    E_Opt_InicioCalculosEtapa: Result := Opt_InicioCalculosEtapa;
    E_Opt_InicioCronicaSorteos: Result := Opt_InicioCronicaSorteos;
    E_Opt_PrepararPaso_ps: Result := Opt_PrepararPaso_ps;
    E_Opt_FinCronicaSorteos: Result := Opt_FinCronicaSorteos;
    E_Opt_FinCalculosEtapa: Result := Opt_FinCalculosEtapa;
    E_Opt_Fin: Result := Opt_Fin;

    // Eventos durante una simulación
    E_Sim_Inicio: Result := Sim_Inicio;
    E_Sim_InicioCronica: Result := Sim_InicioCronica;
    E_Sim_InicioPaso: Result := Sim_InicioPaso;
    E_Sim_FinPaso: Result := Sim_FinPaso;
    E_Sim_FinCronica: Result := Sim_FinCronica;
    E_Sim_Fin: Result := Sim_Fin;
  end;
end;

procedure TEventoOptSimMsgs.SetMsg(ev: TEventoOptSim; AValue: string);
begin
  case ev of
    // Eventos durante una optimización
    E_Opt_Inicio: Opt_Inicio := AValue;
    E_Opt_InicioCalculosEtapa: Opt_InicioCalculosEtapa := AValue;
    E_Opt_InicioCronicaSorteos: Opt_InicioCronicaSorteos := AValue;
    E_Opt_PrepararPaso_ps: Opt_PrepararPaso_ps := AValue;
    E_Opt_FinCronicaSorteos: Opt_FinCronicaSorteos := AValue;
    E_Opt_FinCalculosEtapa: Opt_FinCalculosEtapa := AValue;
    E_Opt_Fin: Opt_Fin := AValue;

    // Eventos durante una simulación
    E_Sim_Inicio: Sim_Inicio := AValue;
    E_Sim_InicioCronica: Sim_InicioCronica := AValue;
    E_Sim_InicioPaso: Sim_InicioPaso := AValue;
    E_Sim_FinPaso: Sim_FinPaso := AValue;
    E_Sim_FinCronica: Sim_FinCronica := AValue;
    E_Sim_Fin: Sim_Fin := AValue;
  end;

end;

constructor TEventoOptSimMsgs.Create;
var
  i: TEventoOptSim;
begin
  inherited Create;
  // La capa no se utiliza
  capa := -1;

  //Inicializa con strings vacios
  for i := low(TEventoOptSim) to High(TEventoOptSim) do
    self[i] := '';

end;




//-----------------------
// Métodos de TMonArchivo
//=======================


constructor TMonArchivo.Create(defVars: TList{of TVarDef}; filename: string;
  msgs: TDAofMsgs);

var
  i: integer;
  j: TEventoOptSim;
begin
  inherited Create;
  abierto := False;
  self.filename := filename;

  for j := low(TEventoOptSim) to high(TEventoOptSim) do
    mensajes[j] := msgs[j];




  SetLength(Self.defVars, defVars.Count);
  for i := 0 to defVars.Count - 1 do
    self.defVars[i] := defVars[i];
end;

function TMonArchivo.resolverRefProc(refProc: integer): TProcWrapper;
var
  aux: TProcWrapper;
begin
  case refProc of
    //los procedimientos deben estar en el orden en que se quieren ejecutar
    //abrir archivo debe ser siempre el primero y cerrar el ultimo, luego
    //se escriben los mensajes de inicio, los valores y los mensajes de fin
    1: aux := TProcWrapper.Create(self, self.AbrirArchivo);
    2: aux := TProcWrapper.Create(self, self.EscribirMsgInicioSimulacion);
    3: aux := TProcWrapper.Create(self, self.EscribirMsgInicioCronica);
    4: aux := TProcWrapper.Create(self, self.EscribirMsgInicioPaso);
    5: aux := TProcWrapper.Create(self, self.EscribirMsgInicioOptimizacion);
    6: aux := TProcWrapper.Create(self, self.EscribirMsgInicioPasoOptimizacion);
    7: aux := TProcWrapper.Create(self, self.EscribirMsgInicioCronicaOptimizacion);
    8: aux := TProcWrapper.Create(self, self.Escribir);
    9: aux := TProcWrapper.Create(self, self.EscribirMsgFinPaso);
    10: aux := TProcWrapper.Create(self, self.EscribirMsgFinCronica);
    11: aux := TProcWrapper.Create(self, self.EscribirMsgFinSimulacion);
    12: aux := TProcWrapper.Create(self, self.EscribirMsgFinCronicaOptimizacion);
    13: aux := TProcWrapper.Create(self, self.EscribirMsgFinPasoOptimizacion);
    14: aux := TProcWrapper.Create(self, self.EscribirMsgFinOptimizacion);
    15: aux := TProcWrapper.Create(self, self.CerrarArchivo);
    else
      raise Exception.Create('TMonArchivo.resolverRefProc: Metodo no registrado para ' +
        self.ClassName + IntToStr(refProc));
  end;
  Result := aux;
end;

class function TMonArchivo.darRefProc(nombreProc: string;
  evento: TEventoOptSim): integer;
begin
  if nombreProc = 'AbrirArchivo' then
    Result := 1
  else if nombreProc = 'EscribirArchivo' then
    Result := 8
  else if nombreProc = 'CerrarArchivo' then
    Result := 15
  else if nombreProc = 'EscribirMsg' then
  begin
    case evento of
      E_Sim_Inicio: Result := 2;
      E_Sim_InicioCronica: Result := 3;
      E_Sim_InicioPaso: Result := 4;
      E_Opt_Inicio: Result := 5;
      E_Opt_InicioCalculosEtapa: Result := 6;
      E_Opt_InicioCronicaSorteos: Result := 7;
      E_Sim_FinPaso: Result := 9;
      E_Sim_FinCronica: Result := 10;
      E_Sim_Fin: Result := 11;
      E_Opt_FinCronicaSorteos: Result := 12;
      E_Opt_FinCalculosEtapa: Result := 13;
      E_Opt_Fin: Result := 14;
      else
        raise Exception.Create('TMonArchivo.darRefProc: Procedimiento no registrado ' +
          nombreProc + ' ' + EventoToStr(evento));
    end;
  end
  else
    raise Exception.Create('TMonArchivo.darRefProc: Procedimiento no registrado ' +
      nombreProc);
end;

procedure TMonArchivo.AbrirArchivo;
var
  i: integer;
begin
  AssignFile(f, filename);
  rewrite(f);

  abierto := True;
  for i := 0 to high(defVars) - 1 do
    Write(f, defVars[i].getNombreCosa, uVarDefs.vectorSeparator);
  WriteLn(f, defVars[high(defVars)].getNombreCosa);
  for i := 0 to high(defVars) - 1 do
    Write(f, defVars[i].getNombreVar, uVarDefs.vectorSeparator);
  WriteLn(f, defVars[high(defVars)].getNombreVar);
end;

procedure TMonArchivo.CerrarArchivo;
begin
  closefile(f);
  abierto := False;
end;

procedure TMonArchivo.Escribir;
var
  i: integer;
begin
  for i := 0 to high(defVars) - 1 do
    Write(f, defVars[i].asS, uVarDefs.vectorSeparator);
  WriteLn(f, defVars[high(defVars)].asS);
end;

procedure TMonArchivo.EscribirMsgInicioSimulacion;
begin
  WriteLn(f, mensajes[E_Sim_Inicio]);
end;

procedure TMonArchivo.EscribirMsgInicioCronica;
begin
  WriteLn(f, mensajes[E_Sim_InicioCronica]);
end;

procedure TMonArchivo.EscribirMsgInicioPaso;
begin
  WriteLn(f, mensajes[E_Sim_InicioPaso]);
end;

procedure TMonArchivo.EscribirMsgFinPaso;
begin
  WriteLn(f, mensajes[E_Sim_FinPaso]);
end;

procedure TMonArchivo.EscribirMsgFinCronica;
begin
  WriteLn(f, mensajes[E_Sim_FinCronica]);
end;

procedure TMonArchivo.EscribirMsgFinSimulacion;
begin
  WriteLn(f, mensajes[E_Sim_Fin]);
end;

procedure TMonArchivo.EscribirMsgInicioOptimizacion;
begin
  WriteLn(f, mensajes[E_Opt_Inicio]);
end;

procedure TMonArchivo.EscribirMsgInicioCronicaOptimizacion;
begin
  WriteLn(f, mensajes[E_Opt_InicioCronicaSorteos]);
end;

procedure TMonArchivo.EscribirMsgInicioPasoOptimizacion;
begin
  WriteLn(f, mensajes[E_Opt_InicioCalculosEtapa]);
end;

procedure TMonArchivo.EscribirMsgFinPasoOptimizacion;
begin
  WriteLn(f, mensajes[E_Opt_FinCalculosEtapa]);
end;

procedure TMonArchivo.EscribirMsgFinCronicaOptimizacion;
begin
  WriteLn(f, mensajes[E_Opt_FinCronicaSorteos]);
end;

procedure TMonArchivo.EscribirMsgFinOptimizacion;
begin
  WriteLn(f, mensajes[E_Opt_Fin]);
end;

procedure TMonArchivo.Free;
begin
  SetLength(defVars, 0);
  if abierto then
  begin
    closefile(f);
    abierto := False;
  end;
  inherited Free;
end;

end.
