unit ulectorVMARGO;

{$mode Delphi}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    btDem: TButton;
    OpenDialog1: TOpenDialog;
    procedure btDemClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

type

  { TVMargo_RecData }

  TVMargo_DataRec = class
    caso: integer;
    anio: integer;
    izz: integer; // crónica
    tipo: string;
    id1, id2, id3: string;
    var_: string;
    uni: string;
    rcal: string;
    Banda: integer;
    valores: array[1..52] of double;
    recLst: TList;
    constructor ReadFromText(var f: textfile);
    constructor CreateFiltro(sFiltro: string);
    procedure Free; virtual;
    function machea(aRec: TVMargo_DataRec): boolean;
  end;


function compare_VMargo_DataRecs(pa, pb: pointer): integer;
var
  a, b: TVMargo_DataRec;
begin
  a := pa;
  b := pb;
  if a.izz > b.izz then
    Result := 1
  else if a.izz < b.izz then
    Result := -1
  else
  if a.anio > b.anio then
    Result := 1
  else if a.anio < b.anio then
    Result := -1
  else
    Result := 0;
end;


// Caso;        Anio;        Izz;Tipo;Id1;Id2;Id3; VAR;UNI;RCAL;Banda;01
// 001;        2018;           1;SYS; MER;--;--;  CMO;$/MWh;MER;           1;
function nextVal(var s: string): string;
var
  i: integer;
  res: string;
begin
  s := trim(s);
  i := pos(';', s);
  if i > 0 then
  begin
    res := copy(s, 1, i - 1);
    Delete(s, 1, i);
    Result := trim(res);
    s := trim(s);
  end
  else
  begin
    Result := s;
    s := '';
  end;
end;


constructor TVMargo_DataRec.ReadFromText(var f: textfile);
var
  kSem: integer;
  r: string;
begin
  readln(f, r);
  recLst := nil;
  try
    inherited Create;
    caso := StrToInt(nextVal(r));
    anio := StrToInt(nextVal(r));
    izz := StrToInt(nextVal(r));
    tipo := nextVal(r);
    id1 := nextVal(r);
    id2 := nextVal(r);
    id3 := nextVal(r);
    var_ := nextVal(r);
    uni := nextVal(r);
    rcal := nextVal(r);
    Banda := StrToInt(nextVal(r));
    for kSem := 1 to 52 do
      valores[kSem] := StrToFloat(nextVal(r));
  except
    self := nil;
  end;
end;

constructor TVMargo_DataRec.CreateFiltro(sFiltro: string);
var
  r: string;
begin
  inherited Create;
  r := sFiltro;
  self.tipo := nextVal(r);
  self.id1 := nextVal(r);
  self.id2 := nextVal(r);
  self.id3 := nextVal(r);
  self.var_ := nextVal(r);
  self.uni := nextVal(r);
  self.rcal := nextVal(r);
  self.Banda := StrToInt(nextVal(r));
  recLst := TList.Create;
end;

procedure TVMargo_DataRec.Free;
var
  k: integer;
begin
  if recLst <> nil then
    for k := 0 to recLst.Count - 1 do
      TVMargo_DataRec(recLst[k]).Free;
  recLst.Free;
  inherited Free;
end;



function smachea(const s1, s2: string): boolean;
begin
  Result := (s1 = '*') or (s1 = s2);
end;

function TVMargo_DataRec.machea(aRec: TVMargo_DataRec): boolean;
begin
  Result := smachea(tipo, aRec.tipo) and smachea(
    id1, aRec.id1) and smachea(id2, aRec.id2) and
    smachea(id3, aRec.id3) and smachea(var_, aRec.var_) and
    smachea(uni, aRec.uni) and (Banda = aRec.Banda);

end;


procedure TForm1.Button1Click(Sender: TObject);
var
  f: textfile;
  archi: string;
  aRec, bRec: TVMargo_DataRec;

  k, j, kRec: integer;
  filtros: TList;
  NRecs: integer;
  r: string;

begin
  if OpenDialog1.Execute then
  begin
    filtros := TList.Create;

    aRec := TVMargo_DataRec.CreateFiltro('SYS;MER;--;--;CMO;$/MWh;MER;1');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('SYS;MER;--;--;CMO;$/MWh;MER;2');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('SYS;MER;--;--;CMO;$/MWh;MER;3');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('SYS;MER;--;--;CMO;$/MWh;MER;4');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('HID;SGD;--;--;APORTE;m3/seg;LIT;0');
    filtros.add(aRec);




    archi := OpenDialog1.FileName;
    filemode := fmOpenRead;
    assignfile(f, archi);
    reset(f);
    readln(f, r);
    while not EOF(f) do
    begin
      aRec := TVMargo_DataRec.ReadFromText(f);
      if aRec <> nil then
      begin
        for j := 0 to filtros.Count - 1 do
        begin
          bRec := filtros[j];
          if bRec.machea(aRec) then
            bRec.recLst.add(aRec);
        end;
      end;
    end;
    closefile(f);

    // Ahora ordeno los records por orden cronica y por año económico.
    for j := 0 to filtros.Count - 1 do
    begin
      bRec := filtros[j];
      bRec.recLst.Sort(Compare_VMargo_DataRecs);
    end;

    NRecs := bRec.recLst.Count;
    assignfile(f, 'c:\basura\lectorvmargo_sal.xlt');
    filemode := fmOpenWrite;
    rewrite(f);

    for j := 0 to filtros.Count - 1 do
    begin
      bRec := filtros[j];
      for k:= 1 to 52 do
        bRec.valores[k]:= 0;
    end;

    for kRec := 0 to NRecs - 1 do
    begin
      for k := 1 to 52 do
      begin
        for j := 0 to filtros.Count - 1 do
        begin
          bRec := filtros[j];
          aRec := bRec.recLst[kRec];
          if j = 0 then
          begin
            Write(f, aRec.izz, #9, aRec.anio);
          end;
           bRec.valores[k]:=  bRec.valores[k] + aRec.valores[k];
          Write(f, #9, aRec.valores[k]);
        end;
        writeln(f);
      end;
    end;
    closefile(f);

    assignfile( f , 'c:\basura\resumen_sal.xlt' );
    rewrite( f );
    for k:= 1 to 52 do
    begin
      for j := 0 to filtros.Count - 1 do
      begin
        bRec := filtros[j];
        if j > 1 then write( f, #9 );
        write( f, bRec.valores[k]/ NRecs:12:2 );
      end;
      writeln( f );
    end;
    closefile( f );
  end;
end;

procedure TForm1.btDemClick(Sender: TObject);
  var
  f: textfile;
  archi: string;
  aRec, bRec: TVMargo_DataRec;

  k, j, kRec: integer;
  filtros: TList;
  NRecs: integer;
  r: string;

begin
  if OpenDialog1.Execute then
  begin
    filtros := TList.Create;

    aRec := TVMargo_DataRec.CreateFiltro('DEM;TOT;--;--;POT;MW;MER;1');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('DEM;TOT;--;--;POT;MW;MER;2');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('DEM;TOT;--;--;POT;MW;MER;3');
    filtros.add(aRec);
    aRec := TVMargo_DataRec.CreateFiltro('DEM;TOT;--;--;POT;MW;MER;4');
    filtros.add(aRec);

    archi := OpenDialog1.FileName;
    filemode := fmOpenRead;
    assignfile(f, archi);
    reset(f);
    readln(f, r);
    while not EOF(f) do
    begin
      aRec := TVMargo_DataRec.ReadFromText(f);
      if aRec <> nil then
      begin
        for j := 0 to filtros.Count - 1 do
        begin
          bRec := filtros[j];
          if bRec.machea(aRec) then
            bRec.recLst.add(aRec);
        end;
      end;
    end;
    closefile(f);

    // Ahora ordeno los records por orden cronica y por año económico.
    for j := 0 to filtros.Count - 1 do
    begin
      bRec := filtros[j];
      bRec.recLst.Sort(Compare_VMargo_DataRecs);
    end;

    NRecs := bRec.recLst.Count;
    assignfile(f, 'c:\basura\lectorvmargo_DemTmpsal.xlt');
    filemode := fmOpenWrite;
    rewrite(f);

    for j := 0 to filtros.Count - 1 do
    begin
      bRec := filtros[j];
      for k:= 1 to 52 do
        bRec.valores[k]:= 0;
    end;

    for kRec := 0 to NRecs - 1 do
    begin
      for k := 1 to 52 do
      begin
        for j := 0 to filtros.Count - 1 do
        begin
          bRec := filtros[j];
          aRec := bRec.recLst[kRec];
          if j = 0 then
          begin
            Write(f, aRec.izz, #9, aRec.anio);
          end;
           bRec.valores[k]:=  bRec.valores[k] + aRec.valores[k];
          Write(f, #9, aRec.valores[k]);
        end;
        writeln(f);
      end;
    end;
    closefile(f);

    assignfile( f , 'c:\basura\resumen_DemTemp_sal.xlt' );
    rewrite( f );
    for k:= 1 to 52 do
    begin
      for j := 0 to filtros.Count - 1 do
      begin
        bRec := filtros[j];
        if j > 1 then write( f, #9 );
        write( f, bRec.valores[k]/ NRecs:12:2 );
      end;
      writeln( f );
    end;
    closefile( f );
  end;
end;

end.

