unit uListaComentarioObjeto;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface

uses
  Classes;

const
  strComment = '//';
  abreComentarioGlobal= '(*';
  cierraComentarioGlobal= '*)';

type
  //El comentario esta asociado a un objeto. Se escribira directamente antes de
  //el en el archivo
  TComentarioDeObjeto = class
    public
      comentario: String;
      objeto: TObject;

      Constructor Create(comentario: String; objeto: TObject); overload;
  end;

  TListaComentarioObjeto = class(TList)
    private
      lastIObjeto: Integer;
    public
      Constructor Create;

      function addComentarioDelObjeto(objeto: TObject; comentario: String): Integer; overload;
      function addComentarioDelObjeto(objeto: TObject; comentario: TStringList): Integer; overload;
      procedure insertComentario(posicion: Integer; objeto: TObject; comentario: String);
      function insertComentarioDespuesDeObjeto(objeto, objetoComentario: TObject; comentario: String): Integer;
      function insertComentarioAntesDeObjeto(objeto, objetoComentario: TObject; comentario: String): Integer;

      function cambiarObjetoComentario(viejoObjeto, nuevoObjeto: TObject): boolean;
      function cambiarComentarioDelObjeto(objeto: TObject; nuevoComentario: String): boolean;

      function eliminarComentarioDelObjeto(objeto: TObject): Integer;

      function comentarioDelObjeto(objeto: TObject): String;
      function comentarioDelObjetoConSimbolos(objeto: TObject): String;
  end;

implementation

Constructor TComentarioDeObjeto.Create(comentario: String; objeto: TObject);
begin
  inherited Create;
  self.comentario:= comentario;
  self.objeto:= objeto;
end;

Constructor TListaComentarioObjeto.Create;
begin
  inherited Create;
  lastIObjeto:= -1;
end;

function TListaComentarioObjeto.addComentarioDelObjeto(objeto: TObject; comentario: String): Integer;
begin
  result:= Add(TComentarioDeObjeto.Create(comentario, objeto));
end;

function TListaComentarioObjeto.addComentarioDelObjeto(objeto: TObject; comentario: TStringList): Integer;
var
  ultimaLinea: string;
begin
  ultimaLinea:= comentario[comentario.Count - 1];
  comentario.Delete(comentario.Count - 1);
  result:= Add(TComentarioDeObjeto.Create(comentario.Text + ultimaLinea, objeto));
end;

procedure TListaComentarioObjeto.insertComentario(posicion: Integer; objeto: TObject; comentario: String);
begin
  Insert(posicion, TComentarioDeObjeto.Create(comentario, objeto));
end;

function TListaComentarioObjeto.insertComentarioDespuesDeObjeto(objeto, objetoComentario: TObject; comentario: String): Integer;
var
  i, res: Integer;
begin
  res:= -1;
  for i:= 0 to Count - 1 do
  begin
    if TComentarioDeObjeto(items[i]).objeto = objeto then
    begin
      res:= i + 1;
      insertComentario(res, objetoComentario, comentario);
      break;
    end;    
  end;
  result:= res;
end;

function TListaComentarioObjeto.insertComentarioAntesDeObjeto(objeto, objetoComentario: TObject; comentario: String): Integer;
var
  i, res: Integer;
begin
  res:= -1;
  for i:= 0 to Count - 1 do
  begin
    if TComentarioDeObjeto(items[i]).objeto = objeto then
    begin
      res:= i;
      insertComentario(res, objetoComentario, comentario);
      break;
    end;    
  end;
  result:= res;
end;

function TListaComentarioObjeto.cambiarObjetoComentario(viejoObjeto, nuevoObjeto: TObject): boolean;
var
  i: Integer;
  res: boolean;
begin
  res:= False;
  for i:= 0 to Count - 1 do
  begin
    if TComentarioDeObjeto(items[i]).objeto = viejoObjeto then
    begin
      res:= true;
      TComentarioDeObjeto(items[i]).objeto:= nuevoObjeto;
      break;
    end;
  end;
  result:= res;
end;

function TListaComentarioObjeto.cambiarComentarioDelObjeto(objeto: TObject; nuevoComentario: String): boolean;
var
  i: Integer;
  res: boolean;
begin
  res:= False;
  for i:= 0 to Count - 1 do
  begin
    if TComentarioDeObjeto(items[i]).objeto = objeto then
    begin
      res:= true;
      TComentarioDeObjeto(items[i]).comentario:= nuevoComentario;
      break;
    end;
  end;
  result:= res;
end;

function TListaComentarioObjeto.eliminarComentarioDelObjeto(objeto: TObject): Integer;
var
  i,res: Integer;
begin
  res:= -1;
  for i:= 0 to Count - 1 do
  begin
    if TComentarioDeObjeto(items[i]).objeto = objeto then
    begin
      res:= i;
      Delete(i);
      break;
    end;
  end;
  result:= res;
end;

function TListaComentarioObjeto.comentarioDelObjeto(objeto: TObject): String;
var
  i: Integer;
  encontre: boolean;
begin
  encontre:= false;
  for i:= lastIObjeto + 1 to Count - 1 do
  begin
    encontre:= objeto = TComentarioDeObjeto(items[i]).objeto;
    if encontre then
    begin
      lastIObjeto:= i;
      break;
    end;
  end;

  if not encontre then
  begin
    for i:= 0 to lastIObjeto do
    begin
      encontre:= objeto = TComentarioDeObjeto(items[i]).objeto;
      if encontre then
      begin
        lastIObjeto:= i;
        break;
      end;
    end;      
  end;

  if encontre then
    result:= TComentarioDeObjeto(items[i]).comentario
  else
    result:= '';
end;

function TListaComentarioObjeto.comentarioDelObjetoConSimbolos(objeto: TObject): String;
var
  res: String;
begin
  res:= comentarioDelObjeto(objeto);
  if res <> '' then
    if Pos(#13#10, res) > 0 then
      result:= abreComentarioGlobal + #13#10 + res + #13#10 + cierraComentarioGlobal
    else
      Result:= strComment + res
  else
    Result:= '';
end;

end.
