(*
    Tux Commander - UConnectionProperties - Connection properties dialog
    Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
    Check for updates on tuxcmd.sourceforge.net

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*)
unit UConnectionProperties;

interface

uses
  SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKMenus;

type
  TFConnectionProperties = class(TGTKDialog)
    Label1, Label2, Label3, Label4, Label5, Label6, Label7, Label8, Label9: TGTKLabel;
    Box: TGTKVBox;
    Table1, Table2: TGTKTable;
    PluginOptionMenu, ServiceTypeOptionMenu: TGTKOptionMenu;
    URIEntry, NameEntry, ServerEntry, UserNameEntry, PasswordEntry, TargetDirEntry: TGTKEntry;
    MaskPasswordCheckButton: TGTKCheckButton;
    procedure FormCreate(Sender: TObject); override;
    procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
    procedure NameEntryChanged(Sender: TObject);
    procedure URIEntryChanged(Sender: TObject);
    procedure ServiceTypeOptionMenuChanged(Sender: TObject);
    procedure MaskPasswordCheckButtonToggled(Sender: TObject);
  private
    CurrentURI: string;
    Lock: boolean;
    function ValidSettings: boolean;
  public
    function MakeURI(Hidden: boolean): string;
    function GetService: string;
  end;

var
  FConnectionProperties: TFConnectionProperties;



implementation

uses ULocale, UVFSCore, UCoreUtils;

const ServiceTypeTable_Count = 6;
var ServiceTypeTable: array[1..ServiceTypeTable_Count, 0..1] of string;



procedure TFConnectionProperties.FormCreate(Sender: TObject);
var i: integer;
    MenuItem: TGTKMenuItem;
begin
  //  Set the constants
  ServiceTypeTable[1, 0] := LANGConnProp_FTP;   ServiceTypeTable[1, 1] := 'ftp';
  ServiceTypeTable[2, 0] := LANGConnProp_SFTP;  ServiceTypeTable[2, 1] := 'sftp';
  ServiceTypeTable[3, 0] := LANGConnProp_SMB;   ServiceTypeTable[3, 1] := 'smb';
  ServiceTypeTable[4, 0] := LANGConnProp_HTTP;  ServiceTypeTable[4, 1] := 'http';
  ServiceTypeTable[5, 0] := LANGConnProp_HTTPS; ServiceTypeTable[5, 1] := 'https';
  ServiceTypeTable[6, 0] := LANGConnProp_Other; ServiceTypeTable[6, 1] := 'unknown';

  //  Initialization
  SetDefaultSize(350, -1);
  Caption := LANGConnProp_Caption;
  Buttons := [mbOK, mbCancel];
  Box := TGTKVBox.Create(Self);
  Box.BorderWidth := 8;
  ClientArea.AddControlEx(Box, True, True, 0);
  Label1 := TGTKLabel.Create(Self);
  Label1.XAlign := 0;
  Label1.XPadding := 0;
  Label1.Caption := LANGConnProp_VFSModule;
  PluginOptionMenu := TGTKOptionMenu.Create(Self);
  Label1.FocusControl := PluginOptionMenu;
  Label1.UseMarkup := True;
  Label1.UseUnderline := True;
  Label2 := TGTKLabel.Create(Self);
  Label2.XAlign := 0;
  Label2.XPadding := 0;
  Label2.Caption := Format('<span weight="ultrabold">%s</span>', [LANGConnProp_URI]);
  URIEntry := TGTKEntry.Create(Self);
  URIEntry.Tooltip := LANGConnProp_URIEntryTooltip;
  Label2.FocusControl := URIEntry;
  Label2.UseMarkup := True;
  Label2.UseUnderline := True;
  Label3 := TGTKLabel.Create(Self);
  Label3.XAlign := 0;
  Label3.XPadding := 0;
  Label3.Caption := Format('<span weight="ultrabold">%s</span>', [LANGConnProp_DetailedInformations]);
  Label3.UseMarkup := True;
  Label4 := TGTKLabel.Create(Self);
  Label4.XAlign := 0;
  Label4.XPadding := 0;
  Label4.Caption := Format('<span weight="ultrabold">%s</span>', [LANGConnProp_Name]);
  NameEntry := TGTKEntry.Create(Self);
  Label4.FocusControl := NameEntry;
  Label4.UseMarkup := True;
  Label4.UseUnderline := True;


  Label5 := TGTKLabel.Create(Self);
  Label5.XAlign := 0;
  Label5.XPadding := 0;
  Label5.Caption := LANGConnProp_Server;
  ServerEntry := TGTKEntry.Create(Self);
  Label5.FocusControl := ServerEntry;
  Label5.UseMarkup := True;
  Label5.UseUnderline := True;
  Label6 := TGTKLabel.Create(Self);
  Label6.XAlign := 0;
  Label6.XPadding := 0;
  Label6.Caption := LANGConnProp_Username;
  UserNameEntry := TGTKEntry.Create(Self);
  UserNameEntry.Tooltip := LANGConnProp_UserNameEntryTooltip;
  Label6.FocusControl := UserNameEntry;
  Label6.UseMarkup := True;
  Label6.UseUnderline := True;
  Label7 := TGTKLabel.Create(Self);
  Label7.XAlign := 0;
  Label7.XPadding := 0;
  Label7.Caption := LANGConnProp_Password;
  PasswordEntry := TGTKEntry.Create(Self);
  PasswordEntry.Visibility := False;
  Label7.FocusControl := PasswordEntry;
  Label7.UseMarkup := True;
  Label7.UseUnderline := True;
  Label8 := TGTKLabel.Create(Self);
  Label8.XAlign := 0;
  Label8.XPadding := 0;
  Label8.Caption := LANGConnProp_TargetDirectory;
  TargetDirEntry := TGTKEntry.Create(Self);
  Label8.FocusControl := TargetDirEntry;
  Label8.UseMarkup := True;
  Label8.UseUnderline := True;
  Label9 := TGTKLabel.Create(Self);
  Label9.XAlign := 0;
  Label9.XPadding := 0;
  Label9.Caption := LANGConnProp_ServiceType;
  ServiceTypeOptionMenu := TGTKOptionMenu.Create(Self);
  Label9.FocusControl := PluginOptionMenu;
  Label9.UseMarkup := True;
  Label9.UseUnderline := True;
  MaskPasswordCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGConnProp_MaskPassword);
  MaskPasswordCheckButton.Checked := True;

  Table1 := TGTKTable.Create(Self);
  Box.AddControlEx(Table1, True, True, 5);
  Table1.AddControlEx(0, 0, 1, 1, Label4, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table1.AddControlEx(1, 0, 1, 1, NameEntry, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table1.AddControlEx(0, 1, 1, 1, Label2, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table1.AddControlEx(1, 1, 1, 1, URIEntry, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table1.AddControlEx(0, 2, 1, 1, Label1, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table1.AddControlEx(1, 2, 1, 1, PluginOptionMenu, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table1.AddControlEx(0, 3, 2, 1, TGTKVBox.Create(Self), [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 10);
  Table1.AddControlEx(0, 4, 2, 1, Label3, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);


  Table2 := TGTKTable.Create(Self);
  Box.AddControlEx(Table2, True, True, 5);
  Table2.AddControlEx(0, 0, 1, 1, TGTKHBox.Create(Self), [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 10, 2);
  Table2.AddControlEx(1, 0, 1, 1, Label9, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(2, 0, 1, 1, ServiceTypeOptionMenu, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(1, 1, 1, 1, Label5, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(2, 1, 1, 1, ServerEntry, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(1, 2, 1, 1, Label6, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(2, 2, 1, 1, UserNameEntry, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(1, 3, 1, 1, Label7, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(2, 3, 1, 1, PasswordEntry, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(2, 4, 1, 1, MaskPasswordCheckButton, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 0);
  Table2.AddControlEx(1, 5, 1, 1, Label8, [taoShrink, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);
  Table2.AddControlEx(2, 5, 1, 1, TargetDirEntry, [taoExpand, taoFill], [taoShrink, taoExpand, taoFill], 5, 2);


  //  Fill the plugins menu
  MenuItem := TGTKMenuItem.CreateTyped(Self, itLabel);
  MenuItem.Caption := LANGConnProp_MenuItemCaption;
  PluginOptionMenu.Items.Add(MenuItem);
  for i := 0 to PluginList.Count - 1 do
    if TVFSPlugin(PluginList[i]).HandlesNetwork then begin
      MenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
      MenuItem.Data := PluginList[i];
      MenuItem.SetCaptionPlain(Format('%s [%s]', [TVFSPlugin(PluginList[i]).ModuleName,
                                                  ExtractFileName(TVFSPlugin(PluginList[i]).FullModulePath)]));
      PluginOptionMenu.Items.Add(MenuItem);
    end;

  //  Fill the protocol menu
  for i := 1 to ServiceTypeTable_Count do begin
    MenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
    MenuItem.Caption := ServiceTypeTable[i, 0];                                  
    ServiceTypeOptionMenu.Items.Add(MenuItem);
  end;


  Lock := True;
  OnKeyDown := FormKeyDown;
  NameEntry.OnChanged := NameEntryChanged;
  URIEntry.OnChanged := URIEntryChanged;
  ServiceTypeOptionMenu.OnChanged := ServiceTypeOptionMenuChanged;
  ServerEntry.OnChanged := ServiceTypeOptionMenuChanged;
  UserNameEntry.OnChanged := ServiceTypeOptionMenuChanged;
  PasswordEntry.OnChanged := ServiceTypeOptionMenuChanged;
  TargetDirEntry.OnChanged := ServiceTypeOptionMenuChanged;
  MaskPasswordCheckButton.OnToggled := MaskPasswordCheckButtonToggled;

  
  NameEntry.SetFocus;
  NameEntryChanged(Self);
  Lock := False;
end;

procedure TFConnectionProperties.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
begin
  case Key of
    GDK_RETURN, GDK_KP_ENTER: if ValidSettings then ModalResult := mbOK;
    GDK_ESCAPE: ModalResult := mbCancel;
  end;
end;

procedure TFConnectionProperties.MaskPasswordCheckButtonToggled(Sender: TObject);
begin
  PasswordEntry.Visibility := not MaskPasswordCheckButton.Checked;
  ServiceTypeOptionMenuChanged(Self);
end;

(********************************************************************************************************************************)
function TFConnectionProperties.ValidSettings: boolean;
begin
  Result := (Length(Trim(NameEntry.Text)) > 0) and (Length(Trim(URIEntry.Text)) > 0);
  if Result then Result := (Pos('://', URIEntry.Text) > 1) and (Pos('://', URIEntry.Text) < Length(URIEntry.Text) - 2) and
                           (Pos(ServiceTypeTable[ServiceTypeTable_Count, 1] + '://', URIEntry.Text) <= 0);
end;

procedure TFConnectionProperties.NameEntryChanged(Sender: TObject);
begin
  SetResponseSensitive(integer(mbOK), ValidSettings);
end;

procedure TFConnectionProperties.URIEntryChanged(Sender: TObject);
var i, j: integer;
    s, s2: string;
begin
  NameEntryChanged(Sender);
  s2 := URIEntry.Text;
  Lock := True;

  //  Find the service type
  if Pos('://', s2) > 1 then begin
    s := Trim(Copy(s2, 1, Pos('://', s2) - 1));
    j := ServiceTypeTable_Count;
    for i := 1 to ServiceTypeTable_Count - 1 do
      if AnsiCompareText(s, ServiceTypeTable[i, 1]) = 0 then begin
        j := i;
        Break;
      end;
    ServiceTypeOptionMenu.ItemIndex := j - 1;
    Delete(s2, 1, Pos('://', s2) + 2);
  end;

  //  Get the target directory
  if Pos('/', s2) > 0 then begin
    s := Copy(s2, Pos('/', s2), Length(s2) - Pos('/', s2) + 1);
    if (s = '') or (s = '/') then TargetDirEntry.Text := ''
                             else TargetDirEntry.Text := s;
    Delete(s2, Pos('/', s2), Length(s2) - Pos('/', s2) + 1);
  end else TargetDirEntry.Text := '';

  //  Get the server string
  if Pos('@', s2) > 0 then begin
    s := Copy(s2, Pos('@', s2) + 1, Length(s2) - Pos('@', s2));
    if s <> '' then ServerEntry.Text := s;
    Delete(s2, Pos('@', s2), Length(s2) - Pos('@', s2) + 1);

    //  Get the user/pass
    if Pos(':', s2) > 0 then begin
      s := Copy(s2, Pos(':', s2) + 1, Length(s2) - Pos(':', s2));
      if s = '' then PasswordEntry.Text := '' else
      if Pos('*', s) <= 0 then PasswordEntry.Text := UnEscapeURI(s);
      Delete(s2, Pos(':', s2), Length(s2) - Pos(':', s2) + 1);
    end else PasswordEntry.Text := '';
    UserNameEntry.Text := UnEscapeURI(s2);
  end else ServerEntry.Text := s2;

  CurrentURI := MakeURI(False);
  Lock := False;
end;

function TFConnectionProperties.MakeURI(Hidden: boolean): string;
begin
  Result := ConstructURI(True, Hidden, GetService, ServerEntry.Text, UserNameEntry.Text, PasswordEntry.Text, TargetDirEntry.Text);
end;

procedure TFConnectionProperties.ServiceTypeOptionMenuChanged(Sender: TObject);
begin
  if Lock then Exit;
  CurrentURI := MakeURI(False);
  URIEntry.OnChanged := nil;
  URIEntry.Text := MakeURI(MaskPasswordCheckButton.Checked);
  URIEntry.OnChanged := URIEntryChanged;
  NameEntryChanged(Sender);
end;

function TFConnectionProperties.GetService: string;
begin
  Result := ServiceTypeTable[ServiceTypeTable_Count, 1];
  if ServiceTypeOptionMenu.ItemIndex < ServiceTypeTable_Count - 1
    then Result := ServiceTypeTable[ServiceTypeOptionMenu.ItemIndex + 1, 1] else
    if Pos('://', URIEntry.Text) > 1 then Result := Copy(URIEntry.Text, 1, Pos('://', URIEntry.Text) - 1);
end;



end.

