unit ASWSMain;

interface

uses
  Windows, Forms, WSocket, StdCtrls, Buttons, Controls, ExtCtrls, ComCtrls,
  Classes, Menus, Dialogs, RxTray, Mover, LCDate;

const
  MyVer	= $00004000;	// server version! (0.4)

type
  tsState = (ssStopped, ssWorking, ssIdle);

  TF_ASWSMain = class(TForm)
    SS: TWSocket;
    SB1: TStatusBar;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    OD1: TOpenDialog;
    TabSheet3: TTabSheet;
    pgLB: TListBox;
    TabSheet4: TTabSheet;
    Memo1: TMemo;
    Memo2: TMemo;
    RxTray1: TRxTray;
    Button8: TButton;
    Panel2: TPanel;
    Label9: TLabel;
    Edit7: TEdit;
    Label10: TLabel;
    Edit8: TEdit;
    Label11: TLabel;
    Edit9: TEdit;
    Button7: TButton;
    Button9: TButton;
    Mover1: TMover;
    Button10: TButton;
    Panel1: TPanel;
    StopBtn: TButton;
    ListenBtn: TButton;
    Button6: TButton;
    PM2: TPopupMenu;
    Start1: TMenuItem;
    Stop1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    PageControl2: TPageControl;
    TabSheet5: TTabSheet;
    TabSheet6: TTabSheet;
    AddBtn: TButton;
    DropBtn: TButton;
    LB: TListBox;
    Edit5: TEdit;
    ChangeBtn: TButton;
    GroupBox1: TGroupBox;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox4: TCheckBox;
    GroupBox2: TGroupBox;
    Label8: TLabel;
    Edit6: TEdit;
    SpeedButton4: TSpeedButton;
    SpeedButton2: TSpeedButton;
    Edit3: TEdit;
    Label5: TLabel;
    Label4: TLabel;
    Edit2: TEdit;
    SpeedButton3: TSpeedButton;
    SpeedButton1: TSpeedButton;
    Edit1: TEdit;
    Label3: TLabel;
    Label6: TLabel;
    Edit4: TEdit;
    GroupBox3: TGroupBox;
    Label12: TLabel;
    Edit10: TEdit;
    Edit11: TEdit;
    Label13: TLabel;
    CSock: TWSocket;
    Edit12: TEdit;
    CheckBox5: TCheckBox;
    SpeedButton5: TSpeedButton;
    LCDate1: TLCDate;
    Button11: TButton;
    Button4: TButton;
    Edit13: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit14: TEdit;
    Label14: TLabel;
    SpeedButton6: TSpeedButton;
    Edit15: TEdit;
    Label15: TLabel;
    Label7: TLabel;
    procedure ListenBtnClick(Sender: TObject);
    procedure SSChangeState(Sender: TObject; OldState,
      NewState: TSocketState);
    procedure SSSessionAvailable(Sender: TObject; Error: Word);
    procedure StopBtnClick(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure LBClick(Sender: TObject);
    procedure Edit5Change(Sender: TObject);
    procedure DropBtnClick(Sender: TObject);
    procedure AddBtnClick(Sender: TObject);
    procedure ChangeBtnClick(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    function GetMIME: string;
    procedure SpeedButton3Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure RxTray1Click(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button9Click(Sender: TObject);
    procedure CSockChangeState(Sender: TObject; OldState,
      NewState: TSocketState);
    procedure Button7Click(Sender: TObject);
    procedure Button10Click(Sender: TObject);
    procedure CSockDataAvailable(Sender: TObject; Error: Word);
    procedure Start1Click(Sender: TObject);
    procedure Stop1Click(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure NotYet;
    procedure SaveSettings;
    procedure RestoreSettings;
    procedure Button11Click(Sender: TObject);
    procedure SpeedButton5Click(Sender: TObject);
    procedure ServLVDblClick(Sender: TObject);
    procedure SpeedButton6Click(Sender: TObject);
  private
    { Private declarations }
    fState : tsState;
    fExts,
    fStrs  : tStrings;
    wasInit: Boolean;
    fRequests: Integer;
    function GetDoNotShow: Boolean;
    function GetAutoClose: Boolean;
    function GetBasePath: string;
    function GetBaseFile: string;
    //function GetTempPath: string;
    procedure SetStatus(const aValue: string);
    procedure SetClientsNum(aValue: Integer);
    procedure SetState(aValue: tsState);
    function GetExt(const aExt: string): string;
    procedure SetExt(const aExt, aValue: string);
    procedure DropExt(const aExt: string);
    procedure ParseExts(aStr: string);
    function SelectPath(aEdit: tEdit; const aTitle: string): Boolean;
    function GetHeader: string;
    function GetFooter: string;
  public
    { Public declarations }
    property DoNotShow: Boolean read GetDoNotShow;
    property AutoClose: Boolean read GetAutoClose;
    //function AddOperation(const aValue: string; aClient: tObject): Integer;
    //procedure AddResult(aIndex: Integer; const aMsg: string);
    //procedure UpdateResult(aIndex, aColumn: Integer; const aMsg: string);
    //procedure DropClient(aIndex: Integer);
    //procedure AddToLog(aIndex: Integer);
    procedure DoStop;
    procedure DoStart;
    procedure LoadPlugins;
    procedure FreePlugins(aCloseInfo: Integer);
    //
    property BasePath: string read GetBasePath;
    property BaseFile: string read GetBaseFile;
    //property TempPath: string read GetTempPath;
    property Status: string write SetStatus;
    property ClientsNum: Integer write SetClientsNum;
    property State: tsState read fState write SetState;
    property Ext2Str[const aExt: string]: string read GetExt write SetExt;
    property Footer: string read GetFooter;
    property Header: string read GetHeader;
  end;

var
  F_ASWSMain: TF_ASWSMain;

implementation

uses
  SysUtils, ASWSMClient, HomeTool, ASWSPlugin;

{$R *.DFM}

const
  regAppName = 'ASWS';	// App name for registry keys
  regSettings= '\Settings';
  regAppSet  = regAppName + regSettings;	
  regCBoxes  = 'CBoxes';
  regEditx   = 'Edit';
  regMIME    = 'MIME';
  
resourcestring
  DefMIME    = '"ai"="application/postscript"' +
	       '"aif"="audio/x-aiff"' +
	       '"aifc"="audio/x-aiff"' +
	       '"aiff"="audio/x-aiff"' +
	       '"au"="audio/basic"' +
	       '"avi"="video/x-msvideo"' +
	       '"bin"="application/octet-stream"' +
	       '"bmp"="image/x-MS-bmp"' +
	       '"cpio"="application/x-cpio"' +
	       '"csh"="application/x-csh"' +
	       '"doc"="application/x-doc/Wordpad"' +
	       '"dvi"="application/x-dvi"' +
	       '"eps"="application/postscript"' +
	       '"exe"="application/octet-stream"' +
	       '"gif"="image/gif"' +
	       '"gtar"="application/x-gtar"' +
	       '"gz"="application/x-gzip"' +
	       '"hpx"="application/mac-binhex40"' +
	       '"htm"="text/html"' +
	       '"html"="text/html"' +
	       '"ief"="image/ief"' +
	       '"jpe"="image/jpg"' +
	       '"jpeg"="image/jpg"' +
	       '"jpg"="image/jpg"' +
	       '"js"="bws-internal/intrasrv-javascript"' +
	       '"latex"="application/x-latex"' +
	       '"ls"="application/x-javascript"' +
	       '"mocha"="application/x-javascript"' +
	       '"mov"="video/quicktime"' +
	       '"mpe"="video/mpeg"' +
	       '"mpeg"="video/mpeg"' +
	       '"mpg"="video/mpeg"' +
	       '"pac"="application/x-ns-proxy-autoconfig"' +
	       '"pbm"="image/x-portable-bitmap"@' +
	       '"pgm"="image/x-portable-graymap"@' +
	       '"pnm"="image/x-portable-anymap"@' +
	       '"ppm"="image/x-portable-pixmap"@' +
	       '"ps"="application/postscript"@' +
	       '"qt"="video/quicktime"@' +
	       '"ras"="image/x-cmu-raster"@' +
	       '"rgb"="image/x-rgb"@' +
	       '"rtf"="application/rtf"@' +
	       '"sh"="application/x-sh"@' +
	       '"shar"="application/x-shar"@' +
	       '"sit"="application/x-stiffit"@' +
	       '"snd"="audio/basic"@' +
	       '"tar"="application/x-tar"@' +
	       '"tcl"="application/x-tcl"@' +
	       '"tex"="application/x-tex"@' +
	       '"texi"="application/x-textinfo"@' +
	       '"texinfo"="application/x-textinfo"@' +
	       '"text"="text/plain"@' +
	       '"tif"="image/tiff"@' +
	       '"tiff"="image/tiff"@' +
	       '"txt"="text/plain"@' +
	       '"wav"="audio/x-wav"@' +
	       '"xbm"="image/x-xbitmap"@' +
	       '"xpm"="image/x-xpixmap"@' +
	       '"xwd"="image/x-xwindowdump"@' +
	       '"zip"="application/x-zip-compressed"@' +
	       '"jfm"="bws-internal/intrasrv-form"@' +
	       '"jrp"="bws-internal/intrasrv-report"@' +
	       '"isv"="bws-internal/intrasrv-urlencoded"@';

procedure tF_ASWSMAin.DoStart;
begin
  with SS do begin
    Port := Edit4.Text;
    Addr := '0.0.0.0';
    Listen;
  end;
end;

procedure TF_ASWSMain.ListenBtnClick(Sender: TObject);
begin
  DoStart;
end;

const
  ss2Str: array[TSocketState] of string = (
    'InvalidState', 'Opened', 'Bound', 'Connecting', 'Connected',
    'Accepting', 'Listening', 'Stopped');

procedure TF_ASWSMain.SSChangeState(Sender: TObject; OldState, NewState: TSocketState);
begin
  if not (csDestroying in ComponentState) then begin
    Caption := 'Server: ' + ss2Str[NewState];
    RxTray1.Hint := Caption;
    case NewState of
      wsInvalidState	: State := ssStopped;
      wsOpened,
      wsBound,
      wsConnecting,
      wsConnected,
      wsAccepting	: State := ssWorking;
      wsListening	: begin
	State := ssIdle;
	RxTray1.Hint := RxTray1.Hint + ' on port ' + Edit4.Text;
      end;
      wsClosed		: State := ssStopped;
    end;
  end;
  case NewState of
    wsListening: LoadPlugins;
    wsOpened,
    wsBound,
    wsConnecting,
    wsConnected,
    wsAccepting: ;
    else FreePlugins(ciClosed);
  end;
end;

procedure TF_ASWSMain.SSSessionAvailable(Sender: TObject; Error: Word);
begin
  // We need to accept the client connection
  NewPeer(SS.Accept, BasePath, BaseFile);
  Inc(fRequests);
  SB1.Panels[1].Text := 'Requests: ' + IntToStr(fRequests);
end;

function tF_ASWSMain.GetDoNotShow: Boolean;
begin
  Result := not CheckBox1.Checked;
end;

function tF_ASWSMain.GetAutoClose: Boolean;
begin
  Result := CheckBox2.Checked;
end;

{function tF_ASWSMain.AddOperation(const aValue: string; aClient: tObject): Integer;
begin
  with ServLV.Items.Add do begin
    Caption := aValue;
    Data    := aClient;
  end;
  Result := ServLV.Items.Count - 1;
end;}

{procedure tF_ASWSMain.AddResult(aIndex: Integer; const aMsg: string);
begin
  if (aIndex >= 0) and (aIndex < ServLV.Items.Count) then ServLV.Items[aIndex].SubItems.Add(aMsg);
end;}

{procedure tF_ASWSMain.UpdateResult(aIndex, aColumn: Integer; const aMsg: string);
var
  lI: tListItem;
begin
  if (aIndex >= 0) and (aIndex < ServLV.Items.Count) then begin
    lI := ServLV.Items[aIndex];
    while (lI.SubItems.Count <= aColumn) do lI.SubItems.Add('');
    lI.SubItems[aColumn] := aMsg;
  end;
end;}

{procedure tF_ASWSMain.AddToLog(aIndex: Integer);
var
  lS: string;
  li: Integer;
  lF: Integer;
begin
  with ServLV.Items[aIndex] do begin
    lS := DateTimeToStr(Now) + '=> ' + Caption;
    for li := 0 to SubItems.Count - 1 do lS := lS + #9' | ' + SubItems[li];
    if FileExists(Edit12.Text) then lF := FileOpen(Edit12.Text, fmOpenWrite + fmShareDenyNone)
			       else lF := FileCreate(Edit12.Text);
    try
      FileSeek(lF, 0, 2);
      lS := lS + #13#10;
      FileWrite(lF, lS[1], Length(lS));
    finally
      FileClose(lF);
    end;
  end;
end;}

{procedure tF_ASWSMain.DropClient(aIndex: Integer);
var
  i: Integer;
  lAllDied: Boolean;
begin
  if (aIndex >= 0) and (aIndex < ServLV.Items.Count) then begin
    if CheckBox5.Checked then AddToLog(aIndex);
    ServLV.Items[aIndex].Data := nil;
    lAllDied := True;
    for i := 0 to ServLV.Items.Count - 1 do
      if (ServLV.Items[i].Data <> nil) then begin
	lAllDied := False;
	Break;
      end;
    if lAllDied then ServLV.Items.Clear;
  end;
end;}

function tF_ASWSMain.GetBasePath: string;
begin
  Result := AddBackSlash(Edit1.Text);
end;

function tF_ASWSMain.GetBaseFile: string;
begin
  Result := Edit2.Text;
end;

{function tF_ASWSMain.GetTempPath: string;
begin
  Result := AddBackSlash(Edit3.Text);
end;}

procedure tF_ASWSMain.SetStatus(const aValue: string);
begin
  SB1.Panels[2].Text := aValue;
end;

procedure tF_ASWSMain.SetClientsNum(aValue: Integer);
begin
  SB1.Panels[0].Text := 'Clients: ' + IntToStr(aValue);
end;

procedure tF_ASWSMain.ParseExts(aStr: string);

  function NextStr: string;
  var
    i: Integer;
    L: Integer;
  begin
    i := 1;
    L := Length(aStr);
    Result := '';
    if (L > 0) then begin
      while (aStr[i] <> '"') and (i < L - 1) do Inc(i);	// skip to "
      Inc(i);
      while (aStr[i] <> '"') and (i < L) do begin
	Result := Result + aStr[i];
	Inc(i);
      end;
      Delete(aStr, 1, i);
    end;  
  end;

var
  lExt,
  lVal: string;
begin
  fExts.Clear;
  fStrs.Clear;
  LB.Items.Clear;
  repeat
    lExt := NextStr;
    lVal := NextStr;
    if (lExt <> '') and (lVal <> '') then Ext2Str[lExt] := lVal;
  until (lExt = '') or (lVal = '');
  if (LB.Items.Count > 0) then begin
    LB.ItemIndex := 0;
    LBClick(Self);
  end
  else begin
    DropBtn.Enabled := False;
    ChangeBtn.Enabled := False;
    Edit5.Text := '';
  end;
end;

procedure tF_ASWSMain.DoStop;
begin
  SS.Close;
end;

procedure TF_ASWSMain.StopBtnClick(Sender: TObject);
begin
  DoStop;
end;

procedure tF_ASWSMain.SetState(aValue: tsState);
begin
  if (fState <> aValue) then begin
    fState := aValue;
    StopBtn.Enabled := False;
    ListenBtn.Enabled := False;
    case aValue of
      ssWorking	: ;
      ssStopped	: ListenBtn.Enabled := True;
      ssIdle	: StopBtn.Enabled := True;
    end;
    Start1.Enabled := ListenBtn.Enabled;
    Stop1.Enabled  := StopBtn.Enabled;
  end;
end;

function GetName(const aDefName, aNewName: string): string;
begin
  if (aNewName = '') then Result := AddBackSlash(aDefName)
		     else Result := AddBackSlash(aNewName);
end;

procedure TF_ASWSMain.SpeedButton1Click(Sender: TObject);
begin
  SelectPath(Edit1, 'Select base folder');
end;

procedure TF_ASWSMain.SpeedButton2Click(Sender: TObject);
begin
  SelectPath(Edit3, 'Select temporary folder');
end;

function tF_ASWSMain.GetExt(const aExt: string): string;
var
  i: Integer;
begin
  i := fExts.IndexOf(aExt);
  if (i >= 0) then Result := fStrs[i]
	      else Result := '';
end;

procedure tF_ASWSMain.SetExt(const aExt, aValue: string);
var
  i: Integer;
begin
  i := fExts.IndexOf(aExt);
  if (i < 0) then begin
    fExts.Add(aExt);
    fStrs.Add(aValue);
    lB.Items.Add(aExt + ' --> ' + aValue);
    DropBtn.Enabled := True;
    LB.ItemIndex := lB.Items.Count - 1;
  end
  else begin
    fStrs[i] := aValue;
    LB.Items[i] := aExt + ' --> ' + aValue;
    lB.ItemIndex := i;
  end;
  LBClick(Self);
end;

procedure tF_ASWSMain.DropExt(const aExt: string);
var
  i: Integer;
begin
  i := fExts.IndexOf(aExt);
  if (i >= 0) then begin
    fExts.Delete(i);
    fStrs.Delete(i);
    LB.Items.Delete(i);
    if (i >= LB.Items.Count) then i := lB.Items.Count - 1;
    if (i < 0) then DropBtn.Enabled := False
	       else lB.ItemIndex := i;
    LBClick(Self);
  end;
end;
 
procedure TF_ASWSMain.FormCreate(Sender: TObject);
begin
  regRootKey := HKEY_LOCAL_MACHINE;
  RxTray1.Icon.Assign(Application.Icon);
  Label7.Caption := 'ASWSm - Multithreaded Personal Web Server by Alek Shamrai (alexsh@adm.univd.kharkov.ua)'#13#10'WSocket component by François PIETTE (francois.piette@ping.be  http://www.rtfm.be/fpiette)'#13#10'Version ' + IntToStr(myVer shr 16) + '.' + IntToStr(myVer shr 12) + ' (Last compilation: ' + DateTimeToStr(LCDate1.LCDate) + ')' + #13#10'Plugins level: 2';
  fExts := tStringList.Create;
  fStrs := tStringList.Create;
  //ServLV.Items.Clear;
  RestoreSettings;
  wasInit := False;
//  SS.Listen; NO NO NO!!!
end;

procedure TF_ASWSMain.FormDestroy(Sender: TObject);
begin
  FreePlugins(ciDestroy);
  fExts.Free;
  fStrs.Free;
end;

procedure TF_ASWSMain.LBClick(Sender: TObject);
begin
  if (Lb.Items.Count > 0) then Edit5.Text := fStrs[LB.ItemIndex]
			  else Edit5.Text := 'Click Add to add some items...';
  ChangeBtn.Enabled := False;
end;

procedure TF_ASWSMain.Edit5Change(Sender: TObject);
begin
  ChangeBtn.Enabled := (Edit5.Text <> '') and (LB.Items.Count > 0);
end;

procedure TF_ASWSMain.DropBtnClick(Sender: TObject);
begin
  DropExt(fExts[LB.ItemIndex]);
end;

procedure TF_ASWSMain.AddBtnClick(Sender: TObject);
var
  ls: string;
begin
  ls := 'ext';
  if InputQuery('Enter value', 'New extention', ls) then Ext2Str[lS] := 'type/info';
end;

procedure TF_ASWSMain.ChangeBtnClick(Sender: TObject);
begin
  Ext2Str[fExts[LB.ItemIndex]] := Edit5.Text;
end;

function tF_ASWSMain.GetMIME: string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to fExts.Count - 1 do
    Result := Result + '"' + fExts[i] + '"="' + fStrs[i] + '"@';
end;

procedure tF_ASWSMain.SaveSettings;
var
  lS: string;
begin
  lS := '0000';
  if CheckBox1.Checked then lS[1] := '1';
  if CheckBox2.Checked then lS[2] := '1';
  if CheckBox5.Checked then lS[3] := '1';
  if CheckBox4.Checked then lS[4] := '1';
  SetRegStr(regAppSet, regCBoxes, lS);
  //
  SetRegStr(regAppSet, regEditx + '1',  Edit1.Text);
  SetRegStr(regAppSet, regEditx + '2',  Edit2.Text);
  SetRegStr(regAppSet, regEditx + '3',  Edit3.Text);
  SetRegStr(regAppSet, regEditx + '4',  Edit4.Text);
  SetRegStr(regAppSet, regEditx + '6',  Edit6.Text);
  SetRegStr(regAppSet, regEditx + '10', Edit10.Text);
  SetRegStr(regAppSet, regEditx + '11', Edit11.Text);
  SetRegStr(regAppSet, regEditx + '12', Edit12.Text);
  SetRegStr(regAppSet, regEditx + '13', Edit13.Text);
  SetRegStr(regAppSet, regEditx + '14', Edit14.Text);
  SetRegStr(regAppSet, regEditx + '15', Edit15.Text);
  //
  SetRegStr(regAppSet, regMIME, GetMime);
end;

procedure tF_ASWSMain.RestoreSettings;
var
  lS: string;
begin
  lS := GetRegStr(regAppSet, regCBoxes, '0111');
  if (Length(lS) < 4) then lS := lS + '1111';
  CheckBox1.Checked := (lS[1] = '1');
  CheckBox2.Checked := (lS[2] = '1');
  CheckBox5.Checked := (lS[3] = '1');
  CheckBox4.Checked := (lS[4] = '1');
  Edit1.Text  := GetRegStr(regAppSet, regEditx +  '1', 'C:\Webbase\');
  Edit2.Text  := GetRegStr(regAppSet, regEditx +  '2', 'Index.Htm');
  Edit3.Text  := GetRegStr(regAppSet, regEditx +  '3', 'C:\Windows\Temp\');
  Edit4.Text  := GetRegStr(regAppSet, regEditx +  '4', '80');
  Edit6.Text  := GetRegStr(regAppSet, regEditx +  '6', 'C:\Webbase\Plugins\');
  Edit10.Text := GetRegStr(regAppSet, regEditx + '10', '<html><body bgcolor=#c0c0c0>');
  Edit11.Text := GetRegStr(regAppSet, regEditx + '11', '<center><hr>Home page of <a href=http://192.168.2.22>Alek</a></body></center></html>');
  Edit12.Text := GetRegStr(regAppSet, regEditx + '12', 'C:\Webbase\ASWS.Log');
  Edit13.Text := GetRegStr(regAppSet, regEditx + '13', '40');
  Edit14.Text := GetRegStr(regAppSet, regEditx + '14', 'C:\Webbase\Uploads\');
  Edit15.Text := GetRegStr(regAppSet, regEditx + '15', 'I_Am_The_Master');
  ParseExts(GetRegStr(regAppSet, regMIME, DefMime));
end;

procedure TF_ASWSMain.Button4Click(Sender: TObject);
begin
  SaveSettings;
end;

procedure TF_ASWSMain.SpeedButton3Click(Sender: TObject);
begin
  OD1.InitialDir := BasePath;
  if OD1.Execute then begin
    if (Pos(BasePath, OD1.FileName) <> 1) then ShowMessage('Invalid path')
					  else Edit2.Text := Copy(OD1.FileName, Length(BasePath) + 1, 256);
  end;
end;

procedure TF_ASWSMain.Button6Click(Sender: TObject);
begin
  Hide;
end;

procedure tF_ASWSMain.NotYet;
begin
  ShowMessage('Not done.');
end;

function tF_ASWSMain.SelectPath(aEdit: tEdit; const aTitle: string): Boolean;
var
  lS: string;
begin
  lS :=  SelectFolder(Handle, '', aTitle);
  if (lS <> '') then begin
    aEdit.Text := GetName(aEdit.Text, lS);
    Result := True;
  end
  else Result := False;
end;

procedure TF_ASWSMain.SpeedButton4Click(Sender: TObject);
begin
  SelectPath(Edit6, 'Select folder for plugins')
end;

procedure TF_ASWSMain.LoadPlugins;
var
  lF : Integer;
  lSR: tSearchRec;
  lST: string;
  lSN: string;
begin
  if not wasInit then begin
    StartupServer(myVer);
    lF := FindFirst(AddBackSlash(Edit6.Text) + '*.DLL', faReadOnly + faArchive, lSR);
    try
      while (lF = 0) do begin
	if (InitPlugin(AddBackSlash(Edit6.Text) + lSR.Name, lSN, lST) >= 0) then pgLB.Items.Add(lSN + ' ==> ' + lST);
	lF := FindNext(lSR);
      end;
    finally
      FindClose(lSR);
    end;
    wasInit := True;
  end;
end;

procedure TF_ASWSMain.FreePlugins(aCloseInfo: Integer);
begin
  if wasInit then begin
    ShutdownServer(aCloseInfo);
    wasInit := False;
    pgLB.Clear;
  end;
end;

procedure TF_ASWSMain.RxTray1Click(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Show;
  Application.BringToFront;
end;

procedure TF_ASWSMain.Button9Click(Sender: TObject);
begin
  CSock.Abort;
end;

procedure TF_ASWSMain.CSockChangeState(Sender: TObject; OldState, NewState: TSocketState);
begin
  case NewState of
    wsClosed,
    wsInvalidState: begin
      Button7.Enabled := True;
      Button10.Enabled := False;
    end;
    else begin
      Button7.Enabled := False;
      Button10.Enabled := (NewState = wsConnected);
    end;
  end;
  Button9.Enabled := not Button7.Enabled;
end;

procedure TF_ASWSMain.Button7Click(Sender: TObject);
begin
  with CSock do begin
    Addr := Edit7.Text;
    Port := Edit8.Text;
    FlushTimeout := StrToInt(Edit9.Text);
    Connect;
  end;
end;

procedure TF_ASWSMain.Button10Click(Sender: TObject);
begin
  if (Memo1.Text <> '') then CSock.Send(@Memo1.Text[1], Length(Memo1.Text));
end;

procedure TF_ASWSMain.CSockDataAvailable(Sender: TObject; Error: Word);
const
  BufSize = $10000;
var
  Buf: Pointer;
  lSz: Integer;
  lS : string;
begin
  GetMem(Buf, BufSize);
  lSz := CSock.Receive(Buf, BufSize);
  if (lSz > 1) then begin
    SetLength(lS, lSz);
    Move(Buf^, lS[1], lSz);
    Memo2.Text := Memo2.Text + #13#10'===== From Server ===='#13#10 + lS;
  end;
  FreeMem(Buf, BufSize);
end;

procedure TF_ASWSMain.Start1Click(Sender: TObject);
begin
  DoStart;
end;

procedure TF_ASWSMain.Stop1Click(Sender: TObject);
begin
  DoStop;
end;

procedure TF_ASWSMain.Exit1Click(Sender: TObject);
begin
  Close;
end;

procedure TF_ASWSMain.Button11Click(Sender: TObject);
begin
  RestoreSettings;
end;

function tF_ASWSMain.GetHeader: string;
begin
  Result := Edit10.Text;
end;

function tF_ASWSMain.GetFooter: string;
begin
  Result := Edit11.Text;
end;

procedure TF_ASWSMain.SpeedButton5Click(Sender: TObject);
begin
  if SelectPath(Edit12, 'Select .log file folder') then Edit12.Text := Edit12.Text + 'ASWS.LOG';
end;

procedure TF_ASWSMain.ServLVDblClick(Sender: TObject);
begin
  //if Assigned(ServLV.Selected) and Assigned(ServLV.Selected.Data) then tForm(ServLV.Selected.Data).Show;
end;

procedure TF_ASWSMain.SpeedButton6Click(Sender: TObject);
begin
  SelectPath(Edit14, 'Select folder for uploads');
end;


end.

