unit cyberspinne_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, CheckLst, ExtCtrls, ComCtrls,css,csm,types;

type
  TfrmCyberspinne = class(TForm)
    //----------------------------Strukturverwaltung----------------------------
    structureFileName: TComboBox; //Combobox zum Eingeben des Dateinamens einer Struktur
    loadStructure: TButton;       //Lädt die ausgewählte Struktur 
    structureList: TListView;     //Zeigt alle geladenen Strukturen an
    deleteStructure: TButton;     //löscht eine geladenen Struktur

    //-----------------------------------CSS------------------------------------
    loadSites: TButton;
    startFileName: TEdit;    //Gibt den Namen der Startseite an
    filesInSite: TListBox;   //Zeigt alle gelesenen Seiten an
    linksInFile: TListBox;   //Zeigt alle Seiten, die von einer ausgewählten aus
                             //erreicht werden können.
    LinksAreNotOriented: TCheckBox; //Gibt an, ob Links in beide Richtungen zeigend
                                    //interpretiert werden sollen
    searchSelectedStructure: TButton; //Sucht die ausgewählte Struktur in den Seiten
    searchAllStructures: TButton;     //Sucht alle geladenen Strukturen in den Seiten-

    //-----------------------------------CSM------------------------------------
    createSelectedStructure: TButton; //Erzeugt eine Website mit der angegebenen Struktur
    aimDirectory: TEdit;     //Bestimmt das Zielverzeichnis für die Dateien
    siteCount: TEdit;        //Gibt an wieviele Dateien erzeugt werden sollen
    donotCreateOtherStructures: TCheckBox; //Gibt an, ob das Erzeugen der anderen
                                           //Strukturen verhindert werden soll

    //--------------------------Unwichtige Designelemente-----------------------
    Label5: TLabel;    Label2: TLabel;    Label3: TLabel;    Label4: TLabel;
    Label1: TLabel;    Label6: TLabel;    Label7: TLabel;    Label8: TLabel;
    Label9: TLabel;    Splitter1: TSplitter;    Splitter2: TSplitter;
    Panel1: TPanel;    Panel2: TPanel;    Panel3: TPanel;

    //-----------------------------Strukturverwaltung---------------------------
    //Lädt die angegebene Struktur
    procedure loadStructureClick(Sender: TObject);
    //Entlädt die angegebene Struktur
    procedure deleteStructureClick(Sender: TObject);
    //Schreibt den Dateinamen der ausgewählten Struktur in die Combobox
    procedure structureListSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);

    //------------------------------------CSS-----------------------------------
    //Lädt die Seiten
    procedure loadSitesClick(Sender: TObject);
    //Zeigt die Links in einer ausgewählteb Datei an
    procedure filesInSiteClick(Sender: TObject);
    //Sucht die ausgewählte Struktur
    procedure searchSelectedStructureClick(Sender: TObject);
    //Sucht alle Strukturen
    procedure searchAllStructuresClick(Sender: TObject);

    //------------------------------------CSM-----------------------------------
    //Erzeugt die ausgewählte Struktur
    procedure createSelectedStructureClick(Sender: TObject);

    //----------------------------Gemischt/Sonstige-----------------------------
    //Initialisiert alles
    procedure FormCreate(Sender: TObject);
    //Löscht alles
    procedure FormDestroy(Sender: TObject);
    //Skaliert die Listboxen neu
    procedure Panel2Resize(Sender: TObject);
  private
    { Private-Deklarationen}
  public
    { Public-Deklarationen}
    currentSites:TSites; //Die aktuell geladene Seitenstruktur
    procedure FreeSites; //Löscht die Seitenstruktur
  end;

var
  frmCyberspinne: TfrmCyberspinne;
implementation

{$R *.DFM}

//==============================================================================
//                                 Strukturverwaltung
//==============================================================================
//Bei der Auswahl einer Struktur den Dateinamen in die ComboBox schreiben
procedure TfrmCyberspinne.structureListSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  if Selected then
    StructureFileName.Text:=item.SubItems[0];
end;

//Lädt die Datei mit dem angegebenen Dateinamen
procedure TfrmCyberspinne.loadStructureClick(Sender: TObject);
var i:integer;
begin
  //Abbrechen, wenn es sie gar nicht gibt
  if not FileExists(StructureFileName.Text) then begin
    showmessage('Struktur nicht vorhanden');
    exit;
  end;
  //Auch abbrechen, wenn sie schon geladen ist
  for i:=0 to structureList.Items.count-1 do
    if lowercase(structureList.Items[i].subitems[0])=lowercase(StructureFileName.Text) then begin
      ShowMessage('Struktur schon in der Liste enthalten');
      exit;
    end;
  //Neuer Eintrag in die Liste
  with structureList.Items.Add do begin
    SubItems.add(StructureFileName.Text); //Zweite ": Dateiname
    Data:=TStructure.Create(StructureFileName.Text); //Struktur laden
    Caption:=TStructure(Data).description; //Erste Spalte: Beschreibung
    SubItems.add('');
  end;
end;

//Ausgewählte Struktur entladen
procedure TfrmCyberspinne.deleteStructureClick(Sender: TObject);
var i:integer;
begin
  //Die Struktur mit dem selben Dateinamen suchen
  for i:=0 to structureList.Items.count-1 do
    if lowercase(structureList.Items[i].subitems[0])=lowercase(StructureFileName.Text) then begin
      structureList.items[i].Delete; //Und nach dem Finden löschen
      exit;
    end;
end;

//==============================================================================
//                                    CSS
//==============================================================================
//Die geladenen Seiten freigeben
procedure TfrmCyberspinne.FreeSites;
begin
  //Es muss nur die StringList mit den Dateinamen freigegeben werden, alles
  //andere übernimmt Delphi
  if currentSites.fileNames<>nil then begin
    currentSites.fileNames.free;
    currentSites.fileNames:=nil;
  end;
end;

//Lädt alle Seiten von einer Startseite aus
procedure TfrmCyberspinne.loadSitesClick(Sender: TObject);
var i:integer;
begin
  FreeSites; //Alte Seiten freigeben
  //Seiten einlesen
  currentSites:=css.readSites(startfilename.text,LinksAreNotOriented.Checked);
  //Seiten in die Listbox schreiben
  filesInSite.Items:=currentSites.fileNames;
  for i:=0 to filesInSite.Items.Count-1 do
    filesInSite.Items[i]:=filesInSite.Items[i]+' ('+IntToStr(i)+')';

  //Status der Strukturen zurück setzen
  for i:=0 to structureList.Items.Count-1 do
    structureList.Items[i].SubItems[1]:='';
end;

//Alle von der aktuell ausgewählten Seite erreichbaren Seiten in die andere
//Listbox schreiben
procedure TfrmCyberspinne.filesInSiteClick(Sender: TObject);
var i:integer;
begin
  linksInFile.Clear;
  for i:=0 to high(currentSites.links[filesInSite.ItemIndex]) do
    linksInFile.items.add(currentSites.fileNames[currentSites.links[filesInSite.ItemIndex][i]]);
end;

//Eine Struktur soll in den Seiten gesucht werden
procedure TfrmCyberspinne.searchSelectedStructureClick(Sender: TObject);
begin
  if structureList.Selected=nil then structureList.Selected:=structureList.items[0];
  //Status ändern
  structureList.Selected.SubItems[1]:='wird getestet';
  application.processMessages;
  //Suchfunktion aufrufen
  if css.existsStructure(structureList.Selected.data,currentSites) then
    structureList.Selected.SubItems[1]:='enthalten' //Bekannt geben, ob sie gefunden wurde
   else
    structureList.Selected.SubItems[1]:='nicht enthalten';
end;

//Alle Strukturen sollen in den Seiten gesucht werden
procedure TfrmCyberspinne.searchAllStructuresClick(Sender: TObject);
var i:integer;
begin
  //Alle Strukturen durchlaufen
  for i:=0 to structureList.Items.Count-1 do begin
    //Status ändern
    structureList.items[i].SubItems[1]:='wird getestet';
    application.processMessages;
    //Suchfunktion aufrufen
    if css.existsStructure(structureList.items[i].data,currentSites) then
      //Bekannt geben, ob die Struktur hier gefunden wurde
      structureList.items[i].SubItems[1]:='enthalten'
     else
      structureList.items[i].SubItems[1]:='nicht enthalten';
  end;
end;

//==============================================================================
//                                    CSM
//==============================================================================
//Erzeugt die ausgewählte Struktur
procedure TfrmCyberspinne.createSelectedStructureClick(Sender: TObject);
var notToCreate:array of TStructure;  //Die Strukturen die nicht erstellt werden sollen
    i,j:integer; //Schleifenvariablen
begin
  //Wurde keine Strukur ausgewählt, wird die erste genommen.
  if structureList.Selected=nil then structureList.Selected:=structureList.items[0];
  //Soll auf die anderen Strukturen geachtet werden?
  if donotCreateOtherStructures.Checked then begin
    //Strukturarray setzen
    SetLength(notToCreate,structureList.items.count-1);
    j:=0;
    //Alle Strukturen, abgesehen von der aussgewählten, in das Array kopieren
    for i:=0 to structureList.items.count-1 do
      if structureList.items[i].Data<>structureList.Selected.data then begin
        notToCreate[j]:=structureList.items[i].Data;
        inc(j);
      end;
  end else setlength(notToCreate,0);
  //Das Verzeichnis soll mit einem Backslash enden 
  if (aimDirectory.text<>'')and(aimDirectory.text[length(aimDirectory.text)]<>'\') then
    aimDirectory.text:=aimDirectory.text+'\';
  //Seiten erzeugen lassen
  csm.MakeSites(structureList.selected.data,notToCreate,aimDirectory.text,strToInt(siteCount.text));
end;


//==============================================================================
//                                   Sonstiges
//==============================================================================
//Alles initialisieren
procedure TfrmCyberspinne.FormCreate(Sender: TObject);
var searchRec:TSearchRec;
begin
  //Alle im Verzeichnis vorhandenen Strukturen suchen, und in die Auswahlliste
  //einfügen
  FindFirst('*.stf',faAnyFile,searchRec);
  repeat
    if searchRec.Name[1]<>'.' then
      structureFileName.Items.add(searchRec.Name);
  until findnext(searchRec)<>0;
  findclose(searchRec);
  //Sicherstellen, dass der Seitennamenzeiger nicht irgendwo hin zeigt
  currentSites.fileNames:=nil;
end;
//Freigabe
procedure TfrmCyberspinne.FormDestroy(Sender: TObject);
var i:integer;
begin
  FreeSites;  //Seiten freigeben
  //Alle geladenen Strukturen durchlaufen und freigeben
  for i:=0 to structureList.Items.Count-1 do
    TStructure(structureList.Items[i].Data).free;
end;
//Listboxen ausrichten
procedure TfrmCyberspinne.Panel2Resize(Sender: TObject);
var maxsize,i:integer;
begin
  //Halbe Panelbreite + Rahmen als Breite nehmen
  filesInSite.Width:=Panel2.Width div 2 - 10;
  //Andere Listbox in derselben Größe daneben
  linksInFile.width:=filesInSite.Width;
  linksInFile.Left:=filesInSite.left+filesInSite.Width+5;
  Label2.left:=linksInFile.left; //Listboxtitel ausrichten
  //Maximale Breite eines Listboxeintrages suchen
  maxsize:=0;
  for i:=0 to filesInSite.items.count-1 do
    if filesInSite.Canvas.TextWidth(filesInSite.Items[i])> maxsize then
      maxsize:=filesInSite.Canvas.TextWidth(filesInSite.Items[i]);
  //Feststellen wieviele Einträge neben einander rein passen
  if maxsize>0 then maxsize:=filesInSite.Width div (maxsize+5);
  //Spaltenanzahl entsprechend setzen
  filesInSite.Columns:=maxsize;
  linksInFile.Columns:=maxsize;
end;
end.
