//----------------------------------------------------------------------------//
//- CaoPersonenListe.pas -----------------------------------------------------//
//----------------------------------------------------------------------------//

//- Beschreibung -------------------------------------------------------------//
// Die Unit CaoPersonenListe stellt zwei Klassen zur Verfügung:               //
// - Die Klasse TCaoPersonen, die einen Artikel kapselt                       //
// - Die Klasse TCaoPersonenListe, die eine Liste von TCaoPersonen kapselt     //
//----------------------------------------------------------------------------//

unit CaoPersonenListe;

//------------------------------------------------------------------------------

interface

//------------------------------------------------------------------------------

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, Contnrs, CaoBaseClass, CaoArtikelListe;


//------------------------------------------------------------------------------
//- TCaoPersonen ---------------------------------------------------------------
//------------------------------------------------------------------------------


type
  TCaoPersonen = class (TObject)

  //----------------------------------------------------------------------------

  private 
    m_iPersonenNummer   : Integer;
    m_sInitialen        : string;
    m_sName             : string;
    m_sOrt              : string;
    m_sPlz              : string;
    m_sStrasse          : string;
    m_sVorname          : string;
    m_iStatus           : Integer;
    m_obArtikelListe    : TCaoArtikelListe;

  //----------------------------------------------------------------------------

  public
    constructor Create; reintroduce;
    destructor  Destroy; override;

    procedure   CopyPerson(const obSourcePerson: TCaoPersonen);
    //procedure   AddArtikel(obArtikel: TCaoArtikel);

    //--------------------------------------------------------------------------

    property iPersonenNummer     : Integer
      read m_iPersonenNummer   write m_iPersonenNummer;
    property sInitialen          : string
      read m_sInitialen        write m_sInitialen;
    property sName               : string
      read m_sName             write m_sName;
    property sOrt                : string
      read m_sOrt              write m_sOrt;
    property sPlz                : string
      read m_sPlz              write m_sPlz;
    property sStrasse            : string
      read m_sStrasse          write m_sStrasse;
    property sVorname            : string
      read m_sVorname          write m_sVorname;
    property iStatus             : Integer
      read m_iStatus           write m_iStatus;
    property obArtikelListe      : TCaoArtikelListe
      read m_obArtikelListe    write m_obArtikelListe;

  //----------------------------------------------------------------------------

  end; //  TCaoPersonen

//------------------------------------------------------------------------------
//- TCaoPersonenListe ----------------------------------------------------------
//------------------------------------------------------------------------------

  TCaoPersonenListe = class (TCaoBaseClass)

  //----------------------------------------------------------------------------

  private
    m_obListe     : TObjectList;

    //--------------------------------------------------------------------------

    function  PrvGetCount: Integer;
    function  PrvGetItem(iIndex: Integer): TCaoPersonen;

  //----------------------------------------------------------------------------

  public
    constructor Create;
    destructor  Destroy; override;
    procedure   Free            (fFreeAllItems: Boolean); reintroduce;
    procedure   FreeAllItems;
    procedure   AddPerson       (obPerson     : TCaoPersonen);
    function    CopyAndAddPerson(obPerson     : TCaoPersonen): TCaoPersonen;
    function    CreatePerson: TCaoPersonen;
    procedure   DeletePerson    (obPerson     : TCaoPersonen);
    function    InitialenExists (obPerson     : TCaoPersonen;
                                 fErrorMessage: Boolean): Boolean;
    function    GetMaxPersonenNr: Integer;
    procedure   Sort            (Compare: TListSortCompare);

    procedure   SortByInitialen;
    procedure   SortByVorname;
    procedure   SortByName;
    procedure   SortByPlz;
    procedure   SortByOrt;

    procedure   SaveToDb;
    procedure   LoadFromDb;
    function    Locate          (iPersonenNummer: Integer): TCaoPersonen;
    function    IsPersonInListe (obPerson       : TCaoPersonen): Boolean;

    //--------------------------------------------------------------------------

    property    Count                 : Integer
                  read PrvGetCount;
    property    Items[iIndex: Integer]: TCaoPersonen
                  read PrvGetItem;
  end; // TCaoPersonenListe
  
//------------------------------------------------------------------------------

implementation

//------------------------------------------------------------------------------

uses
  CamConst, CaoDatenBank, CadAnbieter;

//------------------------------------------------------------------------------

var
  obDatenBank: TCaoDatenBank;

//------------------------------------------------------------------------------

function LocCompareInitialen(obItem1, obItem2: Pointer): Integer;
begin
  Result := CompareText(TCaoPersonen(obItem1).sInitialen, TCaoPersonen(obItem2).sInitialen);
end; // LocCompareInitialen

//------------------------------------------------------------------------------
function LocCompareName(obItem1, obItem2: Pointer): Integer;
begin
  Result := CompareText(TCaoPersonen(obItem1).sName, TCaoPersonen(obItem2).sName);
end; // LocCompareName

//------------------------------------------------------------------------------

function LocCompareOrt(obItem1, obItem2: Pointer): Integer;
begin
  Result := CompareText(TCaoPersonen(obItem1).sOrt, TCaoPersonen(obItem2).sOrt);
end; // LocCompareOrt

//------------------------------------------------------------------------------

function LocComparePlz(obItem1, obItem2: Pointer): Integer;
begin
  Result := CompareText(TCaoPersonen(obItem1).sPlz, TCaoPersonen(obItem2).sPlz);
end; // LocComparePlz

//------------------------------------------------------------------------------

function LocCompareVorname(obItem1, obItem2: Pointer): Integer;
begin
  Result := CompareText(TCaoPersonen(obItem1).sVorname, TCaoPersonen(obItem2).sVorname);
end; // LocCompareVorname

//------------------------------------------------------------------------------

constructor TCaoPersonenListe.Create;
(*
  Überschriebener Konstruktor der Personenliste
*)
begin
  inherited;
  m_obListe   := TObjectList.Create(False);
  obDatenBank := TCaoDatenbank.Create;  
end; // TCaoPersonenListe.Create

//------------------------------------------------------------------------------

destructor TCaoPersonenListe.Destroy; 
(*
  Überschribener Destruktor von TCaoPersonenListe
*)
begin
  obDatenBank.Free;
  m_obListe.Free;
  inherited Destroy;
end; // TCaoPersonenListe.Destroy

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.AddPerson(obPerson: TCaoPersonen);
begin
  m_obListe.Add(obPerson);
end; // TCaoPersonenListe.AddPerson

//------------------------------------------------------------------------------

function TCaoPersonenListe.CopyAndAddPerson(obPerson: TCaoPersonen): TCaoPersonen;
var
  obPersonCopy: TCaoPersonen;
  
  (*
    Kopiert die unter obPerson mitgegebene Person, und fügt sie der PersonenListe an
  *)
  
begin
  // neue Person erzeugen
  obPersonCopy := TCaoPersonen.Create;
  // Personendaten kopieren
  obPersonCopy.CopyPerson(obPerson);
  // Ein kopierter Datensatz wird gleich wie ein Neuer behandelt
  obPersonCopy.iStatus := c_iModusNeu;
  // Kopier der Personenliste hinzufügen
  Self.AddPerson(obPersonCopy);
  // Den Pointer des neuen Personenobjekts zurückgeben
  Result := obPersonCopy;
end; //  TCaoPersonenListe.CopyAndAddPerson(

//------------------------------------------------------------------------------

function TCaoPersonenListe.CreatePerson: TCaoPersonen;
(*
  Erzeugen eines neuen Anbieter-Objekts. Das Objekt wird gleichzeitig m_obListe
  hinzugefügt.
*)
  
begin
  Result         := TCaoPersonen.Create;
  Result.iStatus := c_iModusNeu;
  m_obListe.Add(Result);
end; // TCaoPersonenListe.CreatePerson

//------------------------------------------------------------------------------

function TCaoPersonenListe.PrvGetCount: Integer;
begin
  Result := m_obListe.Count;
end; // TCaoPersonenListe.PrvGetCount

//------------------------------------------------------------------------------

procedure TCaoPersonen.CopyPerson(const obSourcePerson: TCaoPersonen);

(*
  Kopiert die Daten von ObSourcePerson in das PersonenObjekt
*)
  
begin
  Self.iPersonenNummer     := obSourcePerson.iPersonenNummer;
  Self.sInitialen          := obSourcePerson.sInitialen;
  Self.sName               := obSourcePerson.sName;
  Self.sOrt                := obSourcePerson.sOrt;
  Self.sPlz                := obSourcePerson.sPlz;
  Self.sStrasse            := obSourcePerson.sStrasse;
  Self.sVorname            := obSourcePerson.sVorname;
end; // TCaoPersonen.CopyPerson(const obSourcePerson: TCaoPersonen)

//------------------------------------------------------------------------------

constructor TCaoPersonen.Create;
begin
  inherited;
  m_obArtikelListe := TCaoArtikelListe.Create;
end; // TCaoPersonen.Create

//------------------------------------------------------------------------------

destructor TCaoPersonen.Destroy;
begin
  m_obArtikelListe.Free(False);
  inherited;
end; //  TCaoPersonen.Destroy

//------------------------------------------------------------------------------

function TCaoPersonenListe.PrvGetItem(iIndex: Integer): TCaoPersonen;
begin
  Result := TCaoPersonen(m_obListe.Items[iIndex]);
end; // TCaoPersonenListe.PrvGetItem

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.DeletePerson(obPerson: TCaoPersonen);
begin
  m_obListe.Extract(obPerson);
  obPerson.Free; 
end; // TCaoPersonenListe.DeletePerson

//------------------------------------------------------------------------------

function TCaoPersonenListe.InitialenExists(obPerson: TCaoPersonen;
                                           fErrorMessage: Boolean): Boolean;
(*
  Überprüft, ob die Initialen des neuen Eintrags bereits existieren
*)
var
  iIndex,
  iCount : Integer;
begin
  Result := False;
  iCount := 0;
  // Alle Einträge der Liste durchgehen und nach den Initialen suchen
  for iIndex := 0 to m_obListe.Count - 1 do begin
    // Überprüfen, ob die Initialen gefunden werden
    if CompareText(self.Items[iIndex].sInitialen, obPerson.sInitialen) = 0 then begin
      // Überprüfen, ob es sich bei den gefundenen Initialen nicht um das
      // gleiche Objekt handelt oder das Objekt bereits als gelöscht markiert
      // wurde.
      if self.Items[iIndex].iStatus <> c_iModusDelete then begin
        inc(iCount);
      end; // if
      if iCount > 1 then begin
        Result := True;
        if fErrorMessage then begin
          MessageDlg(c_sMeldungInitialenExistieren, mtError, [mbOk], 0);
        end; // if
        Exit;
      end; // if
    end; // if
  end; // for
end; // TCaoPersonenListe.InitialenExists

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.Sort(Compare: TListSortCompare);
begin
  m_obListe.Sort(Compare);
end; // TCaoPersonenListe.Sort

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.SortByInitialen;
begin
  Self.Sort(@LocCompareInitialen);
end; // TCaoPersonenListe.SortByInitialen

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.SortByName;
begin
  Self.Sort(@LocCompareName);
end; // TCaoPersonenListe.SortByName

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.SortByOrt;
begin
  Self.Sort(@LocCompareOrt);
end; // TCaoPersonenListe.SortByOrt

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.SortByPlz;
begin
  Self.Sort(@LocComparePlz);
end; // TCaoPersonenListe.SortByPlz

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.SortByVorname;
begin
  Self.Sort(@LocCompareVorname);
end; // TCaoPersonenListe.SortByVorname

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.SaveToDb;
begin
  obDatenbank.SavePersonenListe(Self);
end; // TCaoPersonenListe.SaveToDb

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.LoadFromDb;
begin
  obDatenbank.LoadPersonenListe(Self);
end; // TCaoPersonenListe.LoadFromDb

//------------------------------------------------------------------------------

function TCaoPersonenListe.GetMaxPersonenNr: Integer;
(*
  Gibt die grösste Personsen-Nummer zurück. Wird zum generiern neuer Nummern
  verwendet
*)
var
  iIndex: Integer;
begin
  Result := 0;
  for iIndex := 0 to Self.Count -1 do begin
    if Self.Items[iIndex].m_iPersonenNummer > Result then begin
      Result := Self.Items[iIndex].m_iPersonenNummer;
    end; // if
  end; // for
end; // TCaoPersonenListe.GetMaxPersonenNr

//------------------------------------------------------------------------------

function TCaoPersonenListe.Locate(iPersonenNummer: Integer): TCaoPersonen;
(*
  Sucht eine Person in der PersonenListe, und gibt diese zurück
*)
var
  iIndex: Integer;
begin
  Result := nil;
  for iIndex := 0 to m_obListe.Count -1 do begin
    if TCaoPersonen(m_obListe.Items[iIndex]).iPersonenNummer = iPersonenNummer then begin
      Result := TCaoPersonen(m_obListe.Items[iIndex]);
    end;// if
  end; // for
end; // TCaoPersonenListe.Locate

//------------------------------------------------------------------------------

function TCaoPersonenListe.IsPersonInListe(obPerson: TCaoPersonen): Boolean;
(*
  Gibt an, ob die Person die als Parameter mitgegeben wurde in der Liste
  existiert
*)
var
  iIndex: Integer;
begin
  Result := False;
  for iIndex := 0 to Count -1 do begin
    if Self.Items[iIndex] = obPerson then begin
      Result := True;
      Exit;
    end; // if
  end; // for
end; // TCaoPersonenListe.IsPersonInListe

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.Free(fFreeAllItems: Boolean);
(*
  Überschriebene Prozedur, die den Destruktor aufruft
*)
begin
  if fFreeAllItems then begin
    FreeAllItems;
  end; // if
  m_obListe.Clear;
  inherited Free;
end; // TCaoPersonenListe.Free

//------------------------------------------------------------------------------

procedure TCaoPersonenListe.FreeAllItems;
(*
  Freigeben aller Elemente der Liste
*)
var
  iIndex: Integer;
begin
  for iIndex := 0 to m_obListe.Count - 1 do begin
    TCaoPersonen(m_obListe[iIndex]).Free;
  end; // for
  m_obListe.Clear;
end; // TCaoPersonenListe.FreeAllItems

//------------------------------------------------------------------------------

end. // CaoPersonenListe
