unit uejecutor;

{$mode delphi}

interface

uses
  Classes, SysUtils, ueditorsalacmd;

type
    { TEjecutorDeOrden }
    TEjecutorDeOrden = class
      idOrden: string;
      nParMin: integer; // >= 0
      nParMax: integer; // -1 = cualquier cantidad

      constructor Create( idOrden: string; nParMin, nParMax: integer);

      // chequea si el primer parámetro coincide co idOrden y si la cantidad
      // de parámetros es la adecuada y retorna TRUE si este ejecutor es apto
      // para procesar la orden y FALSE en caso contrario.
      function FirmaOk(orden: string; paramLst: TStrings): boolean;
      function ejecutar( rbt: TRbtEditorSala_cmd;  paramLst: TStrings): TStrings; virtual;
      function ayuda: TStrings; virtual;
      class procedure Registrarse( EjecutoresLst: TList ); virtual; abstract;
    end;

    { TEjecutoresDeOrdenes }

    TEjecutoresDeOrdenes = class( TList )
      function find( idOrden: string ): TEjecutorDeOrden;
      function findFirmaOk(idOrden: string; paramLst: TStrings ): TEjecutorDeOrden;
    end;

var
   EjecutoresDeOrdenes: TEjecutoresDeOrdenes;

implementation

{ TEjecutoresDeOrdenes }

function TEjecutoresDeOrdenes.find(idOrden: string): TEjecutorDeOrden;
var
   k: integer;
   res: TEjecutorDeOrden;
   buscando: boolean;
begin
  buscando:= true;
  for k:= 0 to self.Count-1 do
  begin
    res:=TEjecutorDeOrden( items[k] );
    if res.idOrden = idOrden then
    begin
      buscando:= false;
      break;
    end;
  end;
  if buscando then
    result:= nil
  else
    result:= res;
end;

function TEjecutoresDeOrdenes.findFirmaOk(idOrden: string; paramLst: TStrings ): TEjecutorDeOrden;
var
   k: integer;
   res: TEjecutorDeOrden;
   buscando: boolean;
begin


buscando:= true;
for k:= 0 to self.Count-1 do
begin
  res:=TEjecutorDeOrden( items[k] );
  if res.FirmaOk( idOrden, paramLst ) then
  begin
    buscando:= false;
    break;
  end;
end;
if buscando then
  result:= nil
else
  result:= res;

end;


{ TEjecutorDeOrden }

constructor TEjecutorDeOrden.Create( idOrden: string;
  nParMin, nParMax: integer);
begin
  inherited Create;
  self.idOrden := idOrden;
  self.nParMin:= nParMin;
  self.nParMax:= nParMax;
end;

function TEjecutorDeOrden.FirmaOk(orden: string; paramLst: TStrings): boolean;
begin
  Result := (idOrden = orden) and (nParMin <= paramLst.Count) and
    ((nParMax < 0) or (paramLst.Count <= nParMax));
end;

function TEjecutorDeOrden.ejecutar(rbt: TRbtEditorSala_cmd; paramLst: TStrings): TStrings;
var
  res: TStringList;
begin
  res := TStringList.Create;
end;

function TEjecutorDeOrden.ayuda: TStrings;
var
  res: TStringList;
  s, auxs: string;
  k: integer;
begin
  res := TStringList.Create;
  s := 'Sintaxis: ' + idOrden;
  if nParMax = nParMin then
  begin
    if nParMax = 1 then
      s := s + ' p1'
    else if nParMax > 0 then
    begin
      for k := 1 to nParMax do
        s := s + ' p' + IntToStr(k);
    end;
  end
  else
  begin
    for k := 1 to nParMin do
      s := s + ' p' + IntToStr(k);
    if nParMax < 0 then
      s := s + '[... [p' + IntToStr(nParMin + 1) + '] ... pN]'
    else
    begin
      auxs := '';
      for k := nParMin + 1 to nParMax do
        auxs := '[' + auxs + ' p' + IntToStr(k) + ']';
      s := s + auxs;
    end;
  end;
  res.add(s);
  Result := res;
end;



procedure AlFinal;
var
  k: integer;
  aEjecutor: TEjecutorDeOrden;
begin
  if EjecutoresDeOrdenes <> nil then
  begin
    for k:= 0 to EjecutoresDeOrdenes.count-1 do
    begin
      aEjecutor:= EjecutoresDeOrdenes[k];
      aEjecutor.Free;
    end;
    EjecutoresDeOrdenes.Free;
    EjecutoresDeOrdenes:= nil;
  end;
end;



initialization
  EjecutoresDeOrdenes:= TEjecutoresDeOrdenes.Create;

finalization
  AlFinal;

end.

