unit uParseSimRes;

interface

uses
  uAuxiliares, xMatDefs, sysutils, windows, controls,ufechas;

const
  sep = #9;

type
  procsIniNot = procedure(nAvisos : Integer);
  procsNot = procedure;

//Retorna el texto que haya hasta el proximo tab o el final de linea
function nextTab(var s : String) : String;

procedure promediarCronicas(archEntrada, archSalida : String);
procedure agruparAnios(archEntrada, archSalida : String);

procedure asignarProcIniNot(proc : procsIniNot);
procedure asignarProcNot(proc : procsNot);
procedure asignarProcFinNot(proc : procsNot);

implementation

var
  assignedProcIniNot, assignedProcNot, assignedProcFinNot : boolean;
  procIniNot: procsIniNot;
  procNot, procFinNot: procsNot;

function nextTab(var s : String) : String;
var
  posTab: Integer;
  res: String;
begin
  posTab:= Pos(#9, s);
  if posTab = 0 then
  begin
    res:= copy(s, 0, length(s));
    s:= '';
  end
  else
  begin
    res:= Copy(s, 0, posTab -1);
    s:= Copy(s, posTab + 1, length(s) - posTab);
  end;
  result:= res;
end;

procedure promediarCronicas(archEntrada, archSalida : String);
var
  matrMin, matrMax, matrProm : array of TDAofNReal;
  NPasos, NCronicas, nVars, {nActores, nPostes,} iCron, iPaso, iVar{, iActores, nVarsActorI} : Integer;
  posTab: Integer;
  val, invNCronicas: NReal;
  entrada, salida : TextFile;
  linea, {actor, actorAnt,} encabActores, encabVariables: String;
  fechas: array of String;
  filaMin, filaMax, filaProm: TDAofNReal;
//  actoresYVariables: array of TVariablesDeActor;
begin
try
  AssignFile(entrada, archEntrada);
  Reset(entrada);
  try
    AssignFile(salida, archSalida);
    Rewrite(salida);

    //Inicio simulación:
    Readln(entrada, linea);
  //  Writeln(salida, linea);
    //FechaIni FechaFin
    Readln(entrada, linea);
    Writeln(salida, linea);
    //NActores
    Readln(entrada, linea);
    Writeln(salida, linea);
    NextPal(linea);
  //  nActores:= NextInt(linea);
    //NCronicas
    Readln(entrada, linea);
    Writeln(salida, linea);
    NextPal(linea);
    NCronicas:= NextInt(linea);
    invNCronicas:= 1/NCronicas;

    //NPasos
    Readln(entrada, linea);
    Writeln(salida, linea);
    NextPal(linea);
    NPasos:= NextInt(linea);
    SetLength(fechas, NPasos);
    SetLength(matrMin, NPasos);
    SetLength(matrMax, NPasos);
    SetLength(matrProm, NPasos);
    //NPostes
    Readln(entrada, linea);
    Writeln(salida, linea);
  {  NextPal(linea);
    nPostes:= NextInt(linea);}
    //Durpos
    Readln(entrada, linea);
    Writeln(salida, linea);

    readln(entrada, linea);
    Writeln(salida, linea);

    //Cronica RandSeed
    Readln(entrada, linea);
  //    Writeln(salida, linea);
    //Actores
    Readln(entrada, linea);
  //  Writeln(salida, linea);
    encabActores:= copy(linea, 0, MAXINT);
    //Como los -
    NextPal(linea);  NextPal(linea);

{    SetLength(actoresYVariables, nActores);
    nVars:= 0;
    actorAnt:= NextPal(linea);
    actor:= NextPal(linea);
    for iActores:= 0 to nActores - 1 do
    begin
      nVarsActorI:= 1;
      inc(nVars);
      while (actor = actorAnt) do
        begin
        inc(nVarsActorI);
        inc(nVars);
        actor:= NextPal(linea);
        end;
      actoresYVariables[iActores].nombreActor:= actorAnt;
      SetLength(actoresYVariables[iActores].variables, nVarsActorI);
      actorAnt:= actor;
      actor:= NextPal(linea);
    end;}

    if assignedProcIniNot then procIniNot(NCronicas + 3);

    nVars:= 0;
    posTab:= Pos(sep, linea);
    while ((posTab <> 0) and (trim(linea) <> '')) do
    begin
      inc(nVars);
      linea:= copy(linea, posTab +1, length(linea) - posTab);
      posTab:= Pos(sep, linea);
    end;
    //Si la ultima columna no tiene un tab al final
    if (posTab = 0) and (trim(linea) <> '') then
      inc(nVars);

    readln(entrada, linea);
    encabVariables:= copy(linea, 0, MAXINT);
  {  //Paso Fecha de Inicio del Paso
    NextPal(linea);NextPal(linea);
    for iActores:= 0 to nActores -1 do
      for nVarsActorI:= 0 to high(actoresYVariables[iActores].variables) do
        actoresYVariables[iActores].variables[nVarsActorI]:= nextPal(linea);}
    for iPaso:= 0 to NPasos -1 do
    begin
      SetLength(matrMin[iPaso], nVars);
      SetLength(matrMax[iPaso], nVars);
      SetLength(matrProm[iPaso], nVars);

      readln(entrada, linea);
      //Como el paso
      NextPal(linea);
      //Fecha
      fechas[iPaso]:= NextPal(linea);
      filaMin:= matrMin[iPaso];
      filaMax:= matrMax[iPaso];
      filaProm:= matrProm[iPaso];
      for iVar:= 0 to nVars -1 do
      begin
        val:= NextFloat(linea);
        filaMin[iVar]:= val;
        filaMax[iVar]:= val;
        filaProm[iVar]:= val * invNCronicas
      end;
    end;
    if assignedProcNot then procNot;

    for iCron:= 2 to NCronicas do
    begin
      Readln(entrada, linea);
      //Cronica RandSeed
      Readln(entrada, linea);
      //Actores
      Readln(entrada, linea);
      //Variables
      Readln(entrada, linea);
      for iPaso:= 0 to NPasos -1 do
      begin
        Readln(entrada, linea);
        //Paso FechaInicioDelPaso
        NextPal(linea); NextPal(linea);

        filaMin:= matrMin[iPaso];
        filaMax:= matrMax[iPaso];
        filaProm:= matrProm[iPaso];
        for iVar:= 0 to nVars -1 do
        begin
          val:= NextFloat(linea);
          if val < filaMin[iVar] then
            filaMin[iVar]:= val
          else if val > filaMax[iVar] then
            filaMax[iVar]:= val;
          filaProm[iVar]:= filaProm[iVar] + val * invNCronicas;
        end;
      end;
      if assignedProcNot then procNot;
    end;

  //Hasta aca lo ultimo que escribi en la salida fue DurPos
    Writeln(salida, 'Promedio');
    Writeln(salida, encabActores);
    Writeln(salida, encabVariables);
    for iPaso:= 0 to NPasos -1 do
    begin
      filaProm:= matrProm[ipaso];
      write(salida, iPaso + 1, sep, fechas[iPaso], sep);
      for iVar:= 0 to nVars -2 do
        write(salida, filaProm[iVar]:1:1, sep);
      Writeln(salida, filaProm[nVars-1]:1:1);
    end;
    if assignedProcNot then procNot;

    writeln(salida);
    Writeln(salida, 'Mínimos');
    Writeln(salida, encabActores);
    Writeln(salida, encabVariables);
    for iPaso:= 0 to NPasos -1 do
    begin
      filaMin:= matrMin[ipaso];
      write(salida, iPaso + 1, sep, fechas[iPaso], sep);
      for iVar:= 0 to nVars -2 do
        write(salida, filaMin[iVar]:1:1, sep);
      Writeln(salida, filaMin[nVars-1]:1:1);
    end;
    if assignedProcNot then procNot;    

    writeln(salida);
    Writeln(salida, 'Máximos');
    Writeln(salida, encabActores);
    Writeln(salida, encabVariables);
    for iPaso:= 0 to NPasos -1 do
    begin
      filaMax:= matrMax[ipaso];
      write(salida, iPaso + 1, sep, fechas[iPaso], sep);
      for iVar:= 0 to nVars -2 do
        write(salida, filaMax[iVar]:1:1, sep);
      Writeln(salida, filaMax[nVars-1]:1:1);
    end;
    if assignedProcNot then procNot;

    if assignedProcFinNot then procFinNot;       
  finally
    closefile(salida);
  end;
finally
  CloseFile(entrada);
end;
end;

procedure agruparAnios(archEntrada, archSalida : String);
var
  entrada, salida : TextFile;
  linea, fecha, fechaAnt, encabActores, encabVariables : String;
  iVar, nVars, nLineasEnElAnio, NCronicas : Integer;
  anio, anioAnt, mes, dia : Word;
  dtFecha : TDate;
  val: NReal;
  fila: TDAofNReal;
begin
try
  AssignFile(entrada, archEntrada);
  Reset(entrada);
  try
    AssignFile(salida, archSalida);
    Rewrite(salida);
    //FechaIni FechaFin
    Readln(entrada, linea);
    Writeln(salida, linea);
    //NActores
    Readln(entrada, linea);
    Writeln(salida, linea);
    //NCronicas
    Readln(entrada, linea);
    Writeln(salida, linea);
    NextPal(linea);
    NCronicas:= NextInt(linea);
    //NPasos
    Readln(entrada, linea);
    Writeln(salida, linea);
    //NPostes
    Readln(entrada, linea);
    Writeln(salida, linea);
    //Durpos
    Readln(entrada, linea);
    Writeln(salida, linea);

    Readln(entrada, linea);
    Writeln(salida, linea);

    //Promedio
    readln(entrada, linea);
    Writeln(salida, linea);

    //Actores
    Readln(entrada, linea);
    //Como los - -
    NextPal(linea); NextPal(linea);

//    if assignedProcIniNot then procIniNot(NCronicas);

    encabActores:= sep + copy(linea, 0, MAXINT);
    Writeln(salida, encabActores);
    nVars:= 0;
    while (trim(NextPal(linea)) <> '') do
      inc(nVars);
    readln(entrada, linea);
    //Como el Paso y el FechaInicioDelPaso
    NextPal(linea);  NextPal(linea);
    encabVariables:= 'Año' + sep + copy(linea, 0, MAXINT);
    Writeln(salida, encabVariables);
    SetLength(fila, nVars);

    readln(entrada, linea);
    //paso
    NextPal(linea);
    fechaAnt:= NextPal(linea);
    dtFecha:= IsoStrToDateTime(fechaAnt);
    DecodeDate(dtFecha, anioAnt, mes, dia);
    nLineasEnElAnio:= 1;
    for iVar:= 0 to nVars -1 do
      fila[iVar]:= NextFloat(linea);

    readln(entrada, linea);
    repeat
    begin
      //Paso
      NextPal(linea);
      fecha:= NextPal(linea);
      dtFecha:= IsoStrToDateTime(fecha);
      DecodeDate(dtFecha, anio, mes, dia);
      while (anioAnt = anio) and (linea <> '') do
      begin
        Inc(nLineasEnElAnio);
        for iVar:= 0 to nVars -1 do
          fila[iVar]:= fila[iVar] + NextFloat(linea);
        readln(entrada, linea);
        if linea <> '' then
        begin
          //Paso
          NextPal(linea);
          fecha:= NextPal(linea);
          dtFecha:= IsoStrToDateTime(fecha);
          DecodeDate(dtFecha, anio, mes, dia);
        end
      end;
      Write(salida, anioAnt, sep);
      for iVar:= 0 to nVars -2 do
        Write(salida, fila[iVar]/nLineasEnElAnio:1:2, sep);
      WriteLn(salida, fila[nVars -1]/nLineasEnElAnio:1:2);

      if linea <> '' then
      begin
        anioAnt:= anio;
        nLineasEnElAnio:= 1;
        for iVar:= 0 to nVars -1 do
          fila[iVar]:= NextFloat(linea);
        readln(entrada, linea);
      end;
    end
    until linea = '';

    Writeln(salida);
    Writeln(salida, 'Mínimos');
    //Minimos, encabActores, encabVariables
    readln(entrada, linea); readln(entrada, linea); readln(entrada, linea);
    Writeln(salida, encabActores);
    Writeln(salida, encabVariables);
    //Primera linea
    Readln(entrada, linea);
    //paso
    NextPal(linea);
    fechaAnt:= NextPal(linea);
    dtFecha:= IsoStrToDateTime(fechaAnt);
    DecodeDate(dtFecha, anioAnt, mes, dia);
    for iVar:= 0 to nVars -1 do
      fila[iVar]:= NextFloat(linea);

    readln(entrada, linea);
    repeat
    begin
      //Paso
      NextPal(linea);
      fecha:= NextPal(linea);
      dtFecha:= IsoStrToDateTime(fecha);
      DecodeDate(dtFecha, anio, mes, dia);
      while (anioAnt = anio) and (linea <> '') do
      begin
        for iVar:= 0 to nVars -1 do
          begin
          val:= NextFloat(linea);
          if fila[iVar] > val then
            fila[iVar]:= val;
          end;
        readln(entrada, linea);
        if linea <> '' then
        begin
          //Paso
          NextPal(linea);
          fecha:= NextPal(linea);
          dtFecha:= IsoStrToDateTime(fecha);
          DecodeDate(dtFecha, anio, mes, dia);
        end
      end;
      Write(salida, anioAnt, sep);
      for iVar:= 0 to nVars -2 do
        Write(salida, fila[iVar]:1:2, sep);
      WriteLn(salida, fila[nVars -1]:1:2);

      if linea <> '' then
      begin
        anioAnt:= anio;
        for iVar:= 0 to nVars -1 do
          fila[iVar]:= NextFloat(linea);
        readln(entrada, linea);
      end;
    end
    until linea = '';

    Writeln(salida);
    Writeln(salida, 'Máximos');
    //Maximos, encabActores, encabVariables
    readln(entrada, linea); readln(entrada, linea); readln(entrada, linea);
    Writeln(salida, encabActores);
    Writeln(salida, encabVariables);
    //Primera linea
    Readln(entrada, linea);
    //paso
    NextPal(linea);
    fechaAnt:= NextPal(linea);
    dtFecha:= IsoStrToDateTime(fechaAnt);
    DecodeDate(dtFecha, anioAnt, mes, dia);
    for iVar:= 0 to nVars -1 do
      fila[iVar]:= NextFloat(linea);

    readln(entrada, linea);
    repeat
    begin
      //Paso
      NextPal(linea);
      fecha:= NextPal(linea);
      dtFecha:= IsoStrToDateTime(fecha);
      DecodeDate(dtFecha, anio, mes, dia);
      while (anioAnt = anio) and (linea <> '') and (not eof(entrada)) do
      begin
        for iVar:= 0 to nVars -1 do
        begin
          val:= NextFloat(linea);
          if fila[iVar] < val then
            fila[iVar]:= val;
        end;
        if not eof(entrada) then
          readln(entrada, linea);
        if (linea <> '') and (not eof(entrada)) then
        begin
          //Paso
          NextPal(linea);
          fecha:= NextPal(linea);
          dtFecha:= IsoStrToDateTime(fecha);
          DecodeDate(dtFecha, anio, mes, dia);
        end
      end;
      Write(salida, anioAnt, sep);
      for iVar:= 0 to nVars -2 do
        Write(salida, fila[iVar]:1:2, sep);
      WriteLn(salida, fila[nVars -1]:1:2, sep);

      if (linea <> '') and (not eof(entrada)) then
      begin
        anioAnt:= anio;
        for iVar:= 0 to nVars -1 do
          fila[iVar]:= NextFloat(linea);
        readln(entrada, linea);
      end;
    end
    until (linea = '') or eof(entrada);
 
  finally
    closefile(salida);
  end;
finally
  closefile(entrada);
end
end;

procedure setDecimalSeparator;
{var
  MyDecimal: PChar;}
begin
{  MyDecimal:=StrAlloc(10);
  GetLocaleInfo(
    LOCALE_SYSTEM_DEFAULT,
    LOCALE_SDECIMAL,
    MyDecimal,
    10);}
  sysutils.DecimalSeparator:= '.';
end;

procedure asignarProcIniNot(proc : procsIniNot);
begin
  assignedProcIniNot:= true;
  procIniNot:= proc;
end;

procedure asignarProcNot(proc : procsNot);
begin
  assignedProcNot:= true;
  procNot:= proc;
end;

procedure asignarProcFinNot(proc : procsNot);
begin
  assignedProcFinNot:= true;
  procFinNot:= proc;
end;

initialization
begin
  setDecimalSeparator;
  assignedProcIniNot:= false;
  assignedProcNot:= false;
  assignedProcFinNot:= false;
end;

finalization
begin
end;

end.
