unit Mod_EDialer;

interface

uses
  Windows, SysUtils, Classes, Mod_Common, xBase;

type
  PEDialerItem = ^TEDialerItem;
  TEDialerItem = record
    Name: String;
    Login: String;
    Password: String;
    Phones: TStringList;
  end;

  TModuleEDialer = class(TModule)
  private
    procedure FreeRASList;
    function DecryptPass(const Password: String): String;
  protected
    class function GetModuleName: String; override;
    class function GetModuleVersion: Integer; override;
    class function GetModuleID: Integer; override;
    function GetIsEmpty: Boolean; override;        
  public
    RASList: TList;

    procedure Run; override;
    destructor Destroy; override;

    function GetAsText: String; override;
    procedure GetAsTree; override;

    procedure ExportModule(DBStream: TMemoryStream); override;
    procedure ImportModule(DBStream: TMemoryStream); override;    
  end;

implementation

const
  TYPE_EDIALER_ENTRY	= 0;
  TYPE_EDIALER_PHONE	= 1;
  TYPE_EDIALER_LOGIN	= 2;
  TYPE_EDIALER_PASS	= 3;

{ TModuleEDialer }

function TModuleEDialer.DecryptPass(const Password: String): String;
var
  i: Integer;
begin
  Result := '';
  for i := 1 to Length(Password) do
    Result := Result + Chr(Ord(Password[i])-i+1);
end;

destructor TModuleEDialer.Destroy;
begin
  FreeRASList;
  inherited;
end;

procedure TModuleEDialer.ExportModule(DBStream: TMemoryStream);
var
  i: Integer;
begin
  inherited;

  ExportData([RASList.Count]);
  for i := 0 to RASList.Count-1 do
    with PEdialerItem(RASList.Items[i])^ do begin
      ExportData([Name, Login, Password]);
      ExportData([Phones.Text]);
    end;
end;

procedure TModuleEDialer.ImportModule(DBStream: TMemoryStream);
var
  i: Integer;
  P: PEdialerItem;
begin
  inherited;

  RASList := TList.Create;
  for i := 0 to ImportData-1 do begin
    New(P); RASList.Add(P);
    with P^ do begin
      Name := ImportData;
      Login := ImportData;
      Password := ImportData;
      Phones := TStringList.Create;
      Phones.Text := ImportData;
    end;
  end;

end;

procedure TModuleEDialer.FreeRASList;
var
  i: Integer;
begin
  if RASList = nil then Exit;

  for i := 0 to RASList.Count-1 do begin
    with PEdialerItem(RASList.Items[i])^ do begin
      Name := '';
      Login := '';
      Password := '';
      Phones.Free;
    end;
    Dispose(RASList.Items[i]);
  end;

  RASList.Free;
end;

function TModuleEDialer.GetAsText: String;
var
  i, j: Integer;
begin
  Result := '';
  for i := 0 to RASList.Count-1 do begin
    Result := Result + 'Name: ' + PEDialerItem(RASList.Items[i]).Name + #13#10;
    Result := Result + 'Login: ' + PEDialerItem(RASList.Items[i]).Login + #13#10;
    Result := Result + 'Password: ' + PEDialerItem(RASList.Items[i]).Password + #13#10;
    for j := 0 to PEDialerItem(RASList.Items[i]).Phones.Count-1 do
      Result := Result + 'Phone' + IntToStr(j) + ': ' + PEDialerItem(RASList.Items[i]).Phones.Strings[j] + #13#10;
    Result := Result + #13#10;
  end;
end;

procedure TModuleEDialer.GetAsTree;
var
  i, j: Integer;
  S: String;
begin
  inherited;
  
  Append(ModuleName, 'Этот модуль содержит dialup пароли E-Dialer''а', ICON_FOLDER);
  MoveIn;
  for i := 0 to RASList.Count-1 do begin
    S := '<ul>';
    for j := 0 to PEDialerItem(RASList.Items[i]).Phones.Count-1 do
      S := S + '<li>Номер<sub>' + IntToStr(j) + '</sub>: ' + HTMLSafe(PEDialerItem(RASList.Items[i]).Phones.Strings[j]);
    if PEDialerItem(RASList.Items[i]).Login <> '' then S := S + '<li>Логин: ' + HTMLSafe(PEDialerItem(RASList.Items[i]).Login);
    if PEDialerItem(RASList.Items[i]).Password <> '' then S := S + '<li>Пароль: ' + HTMLSafe(PEDialerItem(RASList.Items[i]).Password);
    S := S + '</ul>';
    Append(PEDialerItem(RASList.Items[i]).Name, S, ICON_EDIALER);
  end;
  MoveOut;
end;

function TModuleEDialer.GetIsEmpty: Boolean;
begin
  Result := RASList.Count = 0; 
end;

class function TModuleEDialer.GetModuleID: Integer;
begin
  Result := MODULE_EDIALER;
end;

class function TModuleEDialer.GetModuleName: String;
begin
  Result := 'E-Dialer';
end;

class function TModuleEDialer.GetModuleVersion: Integer;
begin
  Result := 0;
end;

procedure TModuleEDialer.Run;
var
  DataItem: TDataItem;
  P: PEDialerItem;
begin
  inherited;

  RASList := TList.Create;

  P := nil;
  while HasMoreData do begin
    DataItem := ReadData;

    case DataItem.cType of
      TYPE_EDIALER_ENTRY: if DataItem.Data <> 'EType_Dialer' then begin
        New(P); RASList.Add(P);
        if Pos('RAS_Entry_', DataItem.Data) > 0 then
          Delete(DataItem.Data, Pos('RAS_Entry_', DataItem.Data), 10);
        P.Name := DataItem.Data;
        P.Phones := TStringList.Create;
      end;
      TYPE_EDIALER_PHONE: if P <> nil then
        P.Phones.Add(DataItem.Data);
      TYPE_EDIALER_LOGIN: if P <> nil then
        P.Login := DataItem.Data;
      TYPE_EDIALER_PASS: if P <> nil then begin
        if DataItem.Data <> 'PaSsWoRd' then
          P.Password := DecryptPass(DataItem.Data);
      end;
    else begin
        FError := ERR_UNK_ITEM;
        Exit;
      end;
    end;
  end;
end;

end.
