unit ucosanubeseable;

{$mode delphi}

interface

uses
  Classes, SysUtils, ucosa, uConstantesSimSEE,
  unubeseable, u_uploadarchi;

type

  TListaDeArchiRef_Nubeseable = class;

  { TCosaNubeseable }

  TCosaNubeseable = class(TCosa)

    nid: integer;
    nid_version: integer;
    flg_nubeseable: boolean;

    //lstRefdeCosa: TListaDeCosas;

    constructor Create(capa: integer); override;

    constructor Create_ReadFromText(f: TArchiTexto); override;


    procedure WriteToText_(f: TArchiTexto); override;

    procedure WriteToText_BEGIN(f: TArchiTexto; const nombre: string); override;
    procedure WriteToText_END(f: TArchiTexto; const nombre: string); override;

    function Rec: TCosa_RecLnk; override;

    //inserta un nuevo elemento a la nube. si acualizar_version es true actualiza
    // la versión del nid_data ya existente, de lo contrario (false) inserta un nuevo
    //ni_data con versión=1 y devuelve en el nid_data el nid del elemento subido
    //La función devuelve el nid_version del elemento subido
    function NubesearCosa(acualizar_version: boolean; var nid_data: integer;
      idHilo: integer; permiso: string; nubesearReferencias: boolean;
      CatalogoReferencias: TCatalogo; listaDeCosasEnSala: TListaDeCosas;
      lstRefdeCosa: TListaDeCosas): integer;

    function getArchiRefLst: TListaDeArchiRef_Nubeseable; virtual;
  end;


  { TRec_nubeseable }

  TRec_nubeseable = class(TCosa)

    nid: integer;
    nid_version: integer;
    flg_nubeseable: boolean;

    constructor Create(capa, nid, nid_version: integer; flg_nubeseable: boolean);

    constructor Create_ReadFromText(f: TArchiTexto); override;
    procedure WriteToText_(f: TArchiTexto); override;

    procedure WriteToText_BEGIN(f: TArchiTexto; const nombre: string); override;
    procedure WriteToText_END(f: TArchiTexto; const nombre: string); override;

    function Rec: TCosa_RecLnk; override;

    function CosaFromNube(nid, nid_version: Integer;
      CatalogoReferencias: TCatalogo; idHilo: Integer; crearCache: Boolean=false ): TCosa;

  end;

  { TArchiRef_Nubeseable }

  TArchiRef_Nubeseable = class(TCosa)

    nid: integer;
    nid_version: integer;
    flg_nubeseable: boolean;

    ArchiRef: TArchiRef_;

    constructor Create(capa, nid, nid_version: integer; flg_nubeseable: boolean;
      ArchiRef: TArchiRef_);
    class function DescClase: string; override;


    constructor Create_ReadFromText(f: TArchiTexto); override;

    function Rec: TCosa_RecLnk; override;

    procedure AfterRead(f: TArchiTexto); override;

    //Inserta el achivo a la base, devuelve el nid_version y en en nid_data
    //el nid asignado.
    function NubesearArchi(acualizar_version: boolean; var nid_data: integer;
      idHilo: integer; permiso: string): integer;

    //Calcula la ruta y el nombre del archivo nubeseado
    //ruta_cache\nombreOriginal_nid_nidVersion.extOriginal
    function GetArchi: string;

    //Calcula el nombre del archivo segun nis y nid_version
    function Calc_nombre_archi: string;

    function testearYResolver: boolean;
  end;

  { TCosas_Nube }

  TCosas_Nube_ = class
    cosa: TCosa;

    nid: integer;
    nid_version: integer;
    dt_creacion: TDateTime;
    comentarios: string;
    usuario: integer;
    grupo: integer;

    constructor Create(cosa: Tcosa; nid, nid_version, usuario, grupo: integer;
      dt_creacion: TDateTime; comentarios: string);

  end;

  { TListaDeArchiRef_Nubeseable }

  TListaDeArchiRef_Nubeseable = class(TListaDeCosas)
  protected
    function getItem(i: integer): TArchiRef_Nubeseable;
    procedure setItem(i: integer; cosa: TArchiRef_Nubeseable);
  public
    nombre: string;
    constructor Create(capa: integer; nombre: string);

    constructor Create_ReadFromText(f: TArchiTexto); override;
    procedure WriteToText_(f: TArchiTexto); override;

    function Add(cosa: TCosa): integer; override;
    procedure insert(indice: integer; cosa: TCosa); override;
    function archivos_strCosas: TStringList;

    function getNextId(clase: TArchiRef_Nubeseable): string;
    function listaDeCosasDeClase(clases: TList): TListaDeArchiRef_Nubeseable;

    function find(const nombre: string): TArchiRef_Nubeseable; overload;
    function find(const clase, nombre: string): TArchiRef_Nubeseable; overload;
    function find(const nombre: string; out ipos: integer): boolean; overload;
    function find(const clase, nombre: string; var ipos: integer): boolean; overload;

    property items[i: integer]: TArchiRef_Nubeseable read getItem write setItem; default;

  end;

procedure AlInicio;
procedure AlFinal;


implementation

uses ucosaconnombre;


{ TCosas_Nube }

constructor TCosas_Nube_.Create(cosa: Tcosa; nid, nid_version, usuario, grupo: integer;
  dt_creacion: TDateTime; comentarios: string);
begin
  if cosa is TCosaNubeseable then
  begin
    TCosaNubeseable(cosa).nid := nid;
    TCosaNubeseable(cosa).nid_version := nid_version;
    TCosaNubeseable(cosa).flg_nubeseable := True;
  end
  else
  if cosa is TArchiRef_Nubeseable then
  begin
    TArchiRef_Nubeseable(cosa).nid := nid;
    TArchiRef_Nubeseable(cosa).nid_version := nid_version;
    TArchiRef_Nubeseable(cosa).flg_nubeseable := True;
  end;
  self.cosa := cosa;
  self.nid := nid;
  self.nid_version := nid_version;
  self.usuario := usuario;
  self.grupo := grupo;
  self.dt_creacion := dt_creacion;
  self.comentarios := comentarios;
end;

{ TArchiRef_Nubeseable }

constructor TArchiRef_Nubeseable.Create(capa, nid, nid_version: integer;
  flg_nubeseable: boolean; ArchiRef: TArchiRef_);
begin
  inherited Create(capa);
  self.nid := nid;
  self.nid_version := nid_version;
  self.flg_nubeseable := flg_nubeseable;
  self.ArchiRef := ArchiRef;
end;


class function TArchiRef_Nubeseable.DescClase: string;
begin
  Result := 'ArchiRef';
end;

constructor TArchiRef_Nubeseable.Create_ReadFromText(f: TArchiTexto);

begin
  inherited Create_ReadFromText(f);
end;



function TArchiRef_Nubeseable.Rec: TCosa_RecLnk;
var
  res: TCosa_RecLnk;
begin
  res := inherited Rec;
  res.addCampoDef_archRef('nb_ArchiDatos', ArchiRef, 176);
  res.addCampoDef('nb_nid', nid, 176); //identificador de la cosa en la BD
  res.addCampoDef('nb_nid_version', nid_version, 176);
  //identificador de la version de la cosa en la BD
  res.addCampoDef('nb_flg_nubeseable', flg_nubeseable, 176);
  //bandera que indica si la cosa es nubeseable
  Result := res;
end;

procedure TArchiRef_Nubeseable.AfterRead(f: TArchiTexto);
begin
  inherited AfterRead(f);

  if f.Version < 180 then
    f.add_ArchiRefNubeseable_(self);

  if self.flg_nubeseable and (not (self.testearYResolver)) then
    raise ExceptionFileNotFound.Create(self.ArchiRef.get_archi,
      'No se encontro el archivo');
end;

function TArchiRef_Nubeseable.NubesearArchi(acualizar_version: boolean;
  var nid_data: integer; idHilo: integer; permiso: string): integer;
var
  errCod: integer;
  memo: TStrings;
  memo_str, errCod_str: string;
  k: integer;
  archi_origen: string;
begin
  nid_data := -1;
  errCod_str := ''; // rch solo para que esté definida ¿XC, qué quisiste poner?
  if nubeAdmin.PASAPORTE <> '' then
  begin
    self.flg_nubeseable := True;
    if not acualizar_version then
    begin
      self.nid_version := 1; //como se incerta en nuevo elemento, la versión es 1
      self.nid := -1;
      self.nid := dbcon_rosx.sql_nextnid_pass('nube_simsee', nubeAdmin.PASAPORTE);
      if self.nid < 0 then
      begin
        raise Exception.Create('Error' + unubeseable.ecToMsg(
          EC_fallo_conexion_url_nube) + errCod_str);
        Exit;
      end;
      nid_data := self.nid;
      nid_version := self.nid_version;
    end
    else
    begin
      nid_version := nubeAdmin.UltimaVersionFromNube(nid_data);
      nid_version := nid_version + 1; //uno mas de la que había
    end;

    memo_str := '';
    memo := self.asMemo(idHilo);
    for k := 0 to memo.Count - 1 do
      memo_str := memo_str + memo[k] + #13;


    errCod_str := nubeAdmin.uploadArchi(nid_data, nid_version,
      self.ArchiRef.get_archi, memo_str, permiso);
    if nid_data < 0 then
      raise Exception.Create('Error' + unubeseable.ecToMsg(
        EC_fallo_conexion_url_nube) + errCod_str);

    //    ext_str:= ExtractFileExt( self.ArchiRef.archi );

    self.flg_nubeseable := True;
    self.nid := nid_data;
    self.nid_version := nid_version;
    archi_origen := self.ArchiRef.get_archi;
    self.ArchiRef.set_archi(Self.GetArchi);

    errCod := nubeAdmin.WriteToCacheArchi(archi_origen, self.ArchiRef.get_archi,
      self.nid, self.nid_version);
    if errCod <= 0 then
      Result := errCod
    else
      Result := nid_version;
  end
  else
    Result := EC_usuario_o_clave_no_validos;

end;

function TArchiRef_Nubeseable.GetArchi: string;
begin
  if self.flg_nubeseable then
    Result := uConstantesSimSEE.getDir_CacheNube + Calc_nombre_archi
  else
    Result := self.ArchiRef.get_archi;
end;

function TArchiRef_Nubeseable.Calc_nombre_archi: string;
begin
  Result := ChangeFileExt(ArchiRef.get_archi, '') + '_' + IntToStr(self.nid) +
    '_' + IntToStr(nid_version) + ExtractFileExt(ArchiRef.get_archi);
end;

function TArchiRef_Nubeseable.testearYResolver: boolean;
var
  archi, archi_cache: string;

begin
  archi_cache := self.GetArchi;
  if self.flg_nubeseable then
  begin
    if (not (FileExists(ArchiRef.get_archi))) and
      (not (FileExists(archi_cache))) then
    begin
      nubeAdmin.Download('nube_archi_bloques', self.nid, self.nid_version,
        self.ArchiRef.get_archi, uConstantesSimSEE.getDir_CacheNube);
      if nubeAdmin.PASAPORTE <> '' then
        Result := True
      else
        Result := False;
    end
    else
      Result := True;
  end
  else
  begin
    archi := lista_caminos.Locate(self.ArchiRef.get_archi);
    if (archi <> '') and (archi <> '\') and (archi <> '/') then
    begin
      ArchiRef.set_archi(archi);
      Result := True;
    end
    else
      Result := False;
  end;
end;


{ TRec_nubeseable }

constructor TRec_nubeseable.Create(capa, nid, nid_version: integer;
  flg_nubeseable: boolean);
begin
  inherited Create(capa);

  self.nid := nid;
  self.nid_version := nid_version;
  self.flg_nubeseable := flg_nubeseable;

end;

constructor TRec_nubeseable.Create_ReadFromText(f: TArchiTexto);
var
  cosa: TCosa;
  nid, nid_version: integer;
begin

  Create_ReadFromText_BEGIN(f);

  LeerCampos(f, 0, self.rec_lnk.Count - 1);

  nid := self.nid;
  nid_version := self.nid_version;

  //Se crea g a partir de la nube o a partir de cache.
  cosa := CosaFromNube(nid, nid_version, f.CatalogoReferencias, f.idHilo,true); //self.Create_FromMemo(f.CatalogoReferencias, f.idHilo, memo);

  self := TRec_nubeseable(cosa);
  self.flg_nubeseable := True;
  self.nid := nid;
  self.nid_version := nid_version;



  //Create_ReadFromText_END(f);
end;

procedure TRec_nubeseable.WriteToText_(f: TArchiTexto);
begin
  inherited WriteToText_(f);
  //asi esta bien, que escriba nid, nidversion,flg y nombre del archivo.
end;

procedure TRec_nubeseable.WriteToText_BEGIN(f: TArchiTexto; const nombre: string);
begin
  inherited WriteToText_BEGIN(f, nombre);
end;

procedure TRec_nubeseable.WriteToText_END(f: TArchiTexto; const nombre: string);
begin
  inherited WriteToText_END(f, nombre);
end;

function TRec_nubeseable.Rec: TCosa_RecLnk;
var
  res: TCosa_RecLnk;
begin
  res := inherited Rec;
  res.addCampoDef('nb_nid', nid, 169); //identificador de la cosa en la BD
  res.addCampoDef('nb_nid_version', nid_version, 169);
  //identificador de la version de la cosa en la BD
  res.addCampoDef('nb_flg_nubeseable', flg_nubeseable, 169);
  //bandera que indica si la cosa es nubeseable
  Result := res;
end;

function TRec_nubeseable.CosaFromNube(nid, nid_version: Integer;
  CatalogoReferencias: TCatalogo; idHilo: Integer; crearCache: Boolean): TCosa;
var
  consulta, memo_str: String;
  memo: TStringList;
  errCod, k: Integer;
begin
  consulta := nubeAdmin.GetData(nid, nid_version, errCod);
  if errCod <> 0 then
    raise Exception.Create('Error' + unubeseable.ecToMsg(errCod));

  memo := TStringList.Create;
  memo.Delimiter := #13;
  memo.Text := consulta;

  Result := self.Create_FromMemo(CatalogoReferencias, idHilo, memo);

  if crearCache then
  begin
     memo_str := '';
     for k := 0 to memo.Count - 1 do
      memo_str := memo_str + memo[k] + #13;
     nubeAdmin.WriteToCache(nid, nid_version, memo_str); //cache local
  end;

end;


{ TCosaNubeseable }

constructor TCosaNubeseable.Create(capa: integer);
begin
  inherited Create(capa);
  self.nid := 0;
  self.nid_version := 0;
  self.flg_nubeseable := False;
end;


constructor TCosaNubeseable.Create_ReadFromText(f: TArchiTexto);
var
  g: TArchiTexto;
  memo: TStringList;
  cosa: TCosa;
  consulta: string;
  errCod: integer;

begin
  Create_ReadFromText_BEGIN(f);
  LeerCampos(f, 0, 4);
  if self.flg_nubeseable then
  begin
    //se crea g a partir de la nube o a partir de cache, si la cosa es
    //Nubeseable (flg_Nubeseable=true) no se lee la cosa de f si no de g.
    consulta := nubeAdmin.GetData(self.nid, self.nid_version, errCod);
    if errCod <> 0 then
      raise Exception.Create('Error' + unubeseable.ecToMsg(errCod));

    memo := TStringList.Create;
    memo.Delimiter := #13;
    memo.Text := consulta;

    cosa := self.Create_FromMemo(f.CatalogoReferencias, f.idHilo, memo);
    cosa.asMemo(f.idHilo);

    g := TArchiTexto.CreateForRead(f.idHilo, f.CatalogoReferencias,
      getDir_Tmp + 'aux_clonar' + IntToStr(f.idHilo) + '.tmp', f.abortarEnError);

    LeerCampos(g, 7, self.rec_lnk.Count - 1);
    g.Free;
  end
  else
    LeerCampos(f, 5, self.rec_lnk.Count - 1);
  Create_ReadFromText_END(f);
end;


procedure TCosaNubeseable.WriteToText_(f: TArchiTexto);
var
  rec_nubeseable: TRec_nubeseable;
begin

  if not flg_nubeseable then
    //   if rec_lnk <> nil then
    EscribirCampos(f, 0, rec_lnk.Count - 1)
  else
  begin
    // si es nubeseable, no escribo en f la cosanubeseable, si no que el recnubeseable
    rec_nubeseable := TRec_nubeseable.Create(self.capa, self.nid,
      self.nid_version, self.flg_nubeseable);
    rec_nubeseable.WriteToText_(f);

  end;
end;

procedure TCosaNubeseable.WriteToText_BEGIN(f: TArchiTexto; const nombre: string);
var
  rec_nubeseable: TRec_nubeseable;
begin
  if not flg_nubeseable then
    inherited WriteToText_BEGIN(f, nombre)
  else
  begin  // si es nubeseable, no escribo en f la cosanubeseable, si no que el recnubeseable
    rec_nubeseable := TRec_nubeseable.Create(self.capa, self.nid,
      self.nid_version, self.flg_nubeseable);
    rec_nubeseable.WriteToText_BEGIN(f, nombre);

  end;

end;

procedure TCosaNubeseable.WriteToText_END(f: TArchiTexto; const nombre: string);
var
  rec_nubeseable: TRec_nubeseable;
begin
  if not flg_nubeseable then
    inherited WriteToText_END(f, nombre)
  else
  begin  // si es nubeseable, no escribo en f la cosanubeseable, si no que el recnubeseable
    rec_nubeseable := TRec_nubeseable.Create(self.capa, self.nid,
      self.nid_version, self.flg_nubeseable);
    rec_nubeseable.WriteToText_END(f, nombre);

  end;
end;



function TCosaNubeseable.Rec: TCosa_RecLnk;
var
  res: TCosa_RecLnk;
begin
  res := inherited Rec;
  res.addCampoDef('nb_nid', nid, 169); //identificador de la cosa en la BD
  res.addCampoDef('nb_nid_version', nid_version, 169);
  //identificador de la version de la cosa en la BD
  res.addCampoDef('nb_flg_nubeseable', flg_nubeseable, 169);
  //bandera que indica si la cosa es nubeseable
  Result := res;
end;

function TCosaNubeseable.NubesearCosa(acualizar_version: boolean;
  var nid_data: integer; idHilo: integer; permiso: string;
  nubesearReferencias: boolean; CatalogoReferencias: TCatalogo;
  listaDeCosasEnSala: TListaDeCosas; lstRefdeCosa: TListaDeCosas): integer;
var
  memo: TStrings;
  memo_str: string;
  nid_version, k, nid_archivo, cantDeRef, kRef: integer;
  //lstRefdeCosa: TListaDeCosas;
  nid_dataRef: array of integer;
begin
  Result := -1;
  nid_version := -1;
  if nubeAdmin.PASAPORTE <> '' then
  begin
    //self.flg_nubeseable:=true;
    self.nid := -1;
    if not acualizar_version then
      self.nid := dbcon_rosx.sql_nextnid_pass('nube_simsee', nubeAdmin.PASAPORTE)
    else
      self.nid := nid_data;


    if self.nid < 0 then
    begin
      raise Exception.Create('Error' + unubeseable.ecToMsg(EC_fallo_conexion_url_nube));
      Exit;
    end;


    //Nubesear las referencias

    if nubesearReferencias then
    begin

      //lstRefdeCosa:=TListaDeCosas.Create(TCosaNubeseable(self).capa,'lstRefdeCosa');

      cantDeRef := TCatalogoReferencias(CatalogoReferencias).obtener_referenciasDeCosa
        (TCosaNubeseable(self), listaDeCosasEnSala, lstRefdeCosa);



      SetLength(nid_dataRef, cantDeRef);

      for kRef := (lstRefdeCosa.Count - cantDeRef + 1) to lstRefdeCosa.Count do
      begin
        k := kref - (lstRefdeCosa.Count - cantDeRef) - 1;
        //LAS REFERENCIAS PUEDEN TENER YA UN NID DE QUE YA ESTA NUBESEADA, EN ESTE CASO NO SE SUBIRÍA
        //A MENOS QUE TUVIESE CAMBIOS, EN ESTE CASO SE SUBE CON EL MISMO NID PERO CON OTRA VERSION.
        //POR AHORA SE SUBE IGUAL, CON UN NUEVO NID
        TCosaNubeseable(lstRefdeCosa[k]).NubesearCosa(False, nid_dataRef[k],
          idHilo, permiso, True, CatalogoReferencias, listaDeCosasEnSala, lstRefdeCosa);
      end;

    end;

    //Referencias:
    {
     No nubeseadas:
     <(TCosa.ClassName).nombre>
     Nubeseadas:
     <(TCosa.ClassName).nid.version>

     VER COMO CAMBIAMOS ESO EN EL MEMO.
    }

    if not acualizar_version then
      nid_version := 1;

    memo_str := '';
    memo := self.asMemo(idHilo);
    for k := 0 to memo.Count - 1 do
      memo_str := memo_str + memo[k] + #13;


    if not acualizar_version then
    begin
      nid_archivo := nubeAdmin.WriteToNube(memo_str, permiso, self.nid);
      if nid_archivo < 0 then
      begin
        Result := nid_archivo;
        exit;
      end;
      nid_data := self.nid;
    end
    else
    begin
      nid_data := self.nid;
      nid_version := nubeAdmin.WriteNewVersionToNube(nid_data, memo_str, permiso);
      if nid_version < 0 then
      begin
        Result := nid_version;
        exit;
      end;
    end;

    self.flg_nubeseable := True;
    self.nid_version := nid_version;

    nubeAdmin.WriteToCache(nid, nid_version, memo_str);

    Result := nid_version;

  end
  else
    Result := EC_No_tiene_los_permisos;
end;

function TCosaNubeseable.getArchiRefLst: TListaDeArchiRef_Nubeseable;
var
  res: TListaDeArchiRef_Nubeseable;
begin
  res := TListaDeArchiRef_Nubeseable.Create(capa, ''); // vacia
  Result := res;
end;

{TListaDeArchiRef_Nubeseable }

function TListaDeArchiRef_Nubeseable.getItem(i: integer): TArchiRef_Nubeseable;
begin
  Result := lst.items[i];
end;

procedure TListaDeArchiRef_Nubeseable.setItem(i: integer; cosa: TArchiRef_Nubeseable);
begin
  lst.items[i] := cosa;
end;

constructor TListaDeArchiRef_Nubeseable.Create(capa: integer; nombre: string);
begin
  inherited Create(capa, nombre);
  self.nombre := nombre;
end;


constructor TListaDeArchiRef_Nubeseable.Create_ReadFromText(f: TArchiTexto);
var
  cnt_ids_alp: integer;
begin
  // SI, OJO , va primero el NOMBRE y después llama el inherited ... con esto
  // queda diferente que el resto de las Cosas ... pero por ahora queda así.
  f.rd('Nombre', nombre);
  if f.Version < 2 then
    f.rd('cnt_ids', cnt_ids_alp);

  {%H-}f.aux_idCarpeta := nombre;

  inherited Create_ReadFromText(f);
end;


procedure TListaDeArchiRef_Nubeseable.WriteToText_(f: TArchiTexto);
begin
  f.wr('Nombre', nombre);
  inherited WriteToText_(f);
end;


function TListaDeArchiRef_Nubeseable.getNextId(clase: TArchiRef_Nubeseable): string;
begin
  Result := clase.ClassName + '_' + DateTimeToStr(now);
end;

function TListaDeArchiRef_Nubeseable.listaDeCosasDeClase(clases: TList):
TListaDeArchiRef_Nubeseable;
var
  i, j: integer;
  resultado: TListaDeArchiRef_Nubeseable;
  esDeClase: boolean;
begin
  resultado := TListaDeArchiRef_Nubeseable.Create(capa, 'Auxiliar');
  for i := 0 to lst.Count - 1 do
  begin
    esDeClase := False;
    for j := 0 to clases.Count - 1 do
    begin
      if TCosa(lst.items[i]).ClassType = TClass(clases[j]) then
      begin
        esDeClase := True;
        break;
      end;
    end;
    if esDeClase then
      resultado.lst.Add(lst.items[i]);
  end;
  Result := resultado;
end;

function TListaDeArchiRef_Nubeseable.find(const nombre: string): TArchiRef_Nubeseable;
var
  k: integer;
  res: TArchiRef_Nubeseable;
begin
  res := nil;
  for k := 0 to lst.Count - 1 do
  begin
    if TArchiRef_Nubeseable(lst.items[k]).ArchiRef.get_archi = nombre then
    begin
      res := lst.items[k];
      break;
    end;
  end;
  Result := res;
end;

function TListaDeArchiRef_Nubeseable.find(
  const clase, nombre: string): TArchiRef_Nubeseable;
var
  k: integer;
  res: TArchiRef_Nubeseable;
begin
  res := nil;
  for k := 0 to lst.Count - 1 do
  begin
    if (TArchiRef_Nubeseable(lst.items[k]).ArchiRef.get_archi = nombre) and
      (TArchiRef_Nubeseable(lst.Items[k]).ClassName = clase) then
    begin
      res := lst.items[k];
      break;
    end;
  end;
  Result := res;
end;



function TListaDeArchiRef_Nubeseable.find(const nombre: string;
  out ipos: integer): boolean;
var
  k: integer;
  buscando: boolean;
  aArchRef: TArchiRef_Nubeseable;
begin
  buscando := True;
  for k := 0 to lst.Count - 1 do
  begin
    aArchRef := lst.items[k];
    if aArchRef.ArchiRef.get_archi = nombre then
    begin
      buscando := False;
      ipos := k;
      break;
    end;
  end;
  Result := not buscando;
end;

function TListaDeArchiRef_Nubeseable.find(const clase, nombre: string;
  var ipos: integer): boolean;
var
  k: integer;
  buscando: boolean;
  cosa: TArchiRef_Nubeseable;
begin
  buscando := True;
  for k := 0 to lst.Count - 1 do
  begin
    cosa := TArchiRef_Nubeseable(lst.items[k]);
    if (cosa.ClassName = clase) and (cosa.ArchiRef.get_archi = nombre) then
    begin
      buscando := False;
      ipos := k;
      break;
    end;
  end;
  Result := not buscando;
end;

function TListaDeArchiRef_Nubeseable.Add(cosa: TCosa): integer;
var
  ipos: integer;
  xnombre: string;
begin
  xnombre := (cosa as TArchiRef_Nubeseable).ArchiRef.get_archi;
  if not find(xnombre, ipos) then
    inherited add(cosa)
  else
    Result := -1;
end;

procedure TListaDeArchiRef_Nubeseable.insert(indice: integer; cosa: TCosa);
var
  ipos: integer;
begin
  if not find((cosa as TArchiRef_Nubeseable).ArchiRef.get_archi, ipos) then
    inherited insert(indice, cosa)
  else
    raise Exception.Create('La lista ' + self.nombre +
      ' ya tiene un elemento de nombre ' +
      (cosa as TArchiRef_Nubeseable).ArchiRef.get_archi);
end;


function TListaDeArchiRef_Nubeseable.archivos_strCosas: TStringList;
var
  res: TStringList;
  i: integer;
begin
  res := TStringList.Create;
  res.Capacity := lst.Count;
  for i := 0 to lst.Count - 1 do
    res.Add(TArchiRef_Nubeseable(lst.items[i]).ArchiRef.get_archi);
  Result := res;
end;

procedure AlInicio;
var
  dir_cache: string;
begin
  registrarClaseDeCosa(TRec_nubeseable.ClassName, TRec_nubeseable);
  registrarClaseDeCosa(TArchiRef_Nubeseable.ClassName, TArchiRef_Nubeseable);
  ucosa.registrarClaseDeCosa(TListaDeArchiRef_Nubeseable.ClassName,
    TListaDeArchiRef_Nubeseable);
  dir_cache := uConstantesSimSEE.getDir_CacheNube;

  if not DirectoryExists(dir_cache) then
    CreateDir(dir_cache);

end;

procedure AlFinal;
begin
end;


end.
