unit U_LoginUser;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, RzButton, RzPanel, ExtCtrls, siComp, siLngLnk, Mask,
  RzEdit, RzCmboBx, RzRadChk,

  U_BaseCommon, U_BaseConstants, U_SCSComponent, U_SCSClasses, U_ProtectionCommon, U_ProtectionBase;

type
  TF_LoginUser = class(TForm)
    RzPanel1: TRzPanel;
    RzGroupBox1: TRzGroupBox;
    btOk: TRzBitBtn;
    btCancel: TRzBitBtn;
    lng_Forms: TsiLangLinked;
    RzPanel2: TRzPanel;
    Label1: TLabel;
    Label2: TLabel;
    cbUsers: TRzComboBox;
    edPass: TRzEdit;
    pnRememberPass: TRzPanel;
    cbRememberPass: TRzCheckBox;
    procedure btOkClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    GForm: TForm;
    FUsersInfo: TUsersInfo;
  public
    Constructor Create(AOwner: TComponent; AForm: TForm);
    Destructor Destroy; override;

    function Execute(AUsersInfo: TUsersInfo; ACanRememberPass, AReadFromRegistry: Boolean; ACaption: String): Boolean;

  end;

  function LogInUser(AUsersInfo: TUsersInfo; AFormOwner: TForm;
            ACanRememberPass, AReadFromRegistry: Boolean;
            ADefUser: TUserInfo; ACaption: String): Boolean;

//var
//  Form1: TForm1;

implementation

{$R *.dfm}

constructor TF_LoginUser.Create(AOwner: TComponent; AForm: TForm);
begin
  GForm := AForm;
  inherited Create(AOwner);
end;

destructor TF_LoginUser.Destroy;
begin
  inherited;
end;

function TF_LoginUser.Execute(AUsersInfo: TUsersInfo; ACanRememberPass, AReadFromRegistry: Boolean; ACaption: String): Boolean;
var
  i: Integer;
  UserInfo: TUserInfo;

  SavedLog: String;
  SavedLogU: String;
  SavedPass: String;
  LogIndexToSelect: Integer;

begin
  Result := false;
  try
    FUsersInfo := AUsersInfo;

    SavedLog := '';
    SavedPass := '';
    if AReadFromRegistry then
    begin
      SavedLog := XorStr(GetStrFromRegistry(pnUserLog));
      if SavedLog <> '' then
        SavedPass := XorStr(GetStrFromRegistry(pnUserPass));
      if ACanRememberPass then
        if SavedPass <> '' then
        begin
          UserInfo := FUsersInfo.GetUserInfoByName(SavedLog);
          if UserInfo <> nil then
            if UserInfo.Pass = SavedPass then
            begin
              Result := true;
              FUsersInfo.LoggedUserInfo := UserInfo;
            end
        end;
    end;

    if Not Result then
    begin
      LogIndexToSelect := -1;
      SavedLogU := AnsiUpperCase(SavedLog);

      cbUsers.Items.Clear;
      for i := 0 to AUsersInfo.UsersInfo.Count - 1 do
      begin
        UserInfo := TUserInfo(AUsersInfo.UsersInfo[i]);
        cbUsers.Items.Add(UserInfo.Name);
        if SavedLogU <> '' then
        begin
          if AnsiUpperCase(UserInfo.Name) = SavedLogU then
            LogIndexToSelect := i;
        end
        else
        if AUsersInfo.LoggedUserInfo <> nil then
          if AUsersInfo.LoggedUserInfo = UserInfo then
            LogIndexToSelect := i;
      end;
      if LogIndexToSelect <> -1 then
        cbUsers.ItemIndex := LogIndexToSelect;
      cbUsers.Sorted := true;
      cbUsers.Sorted := false;

      edPass.Text := '';
      pnRememberPass.Visible := ACanRememberPass;

      if ACaption = '' then
        Caption := cLoginUser3
      else
        Caption := ACaption;

      if ShowModal = mrOk then
      begin
        Result := true;

        if ACanRememberPass then
          if FUsersInfo.LoggedUserInfo <> nil then
          begin
            SaveStrToRegistry(pnUserLog, XorStr(FUsersInfo.LoggedUserInfo.Name));
            if cbRememberPass.Checked then
              SaveStrToRegistry(pnUserPass, XorStr(FUsersInfo.LoggedUserInfo.Pass))
            else
              SaveStrToRegistry(pnUserPass, '');
          end;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_LoginUser.Execute', E.Message);
  end;
end;

procedure TF_LoginUser.btOkClick(Sender: TObject);
var
  UserInfo: TUserInfo;
begin
  try
    UserInfo := FUsersInfo.GetUserInfoByName(cbUsers.Text);
    if UserInfo = nil then
    begin
      MessageModal(cLoginUser1, ApplicationName, MB_OK or MB_ICONINFORMATION);
      ModalResult := mrNone;
    end
    else
    begin
      if GetHash(edPass.Text) <> UserInfo.Pass then
      begin
        MessageModal(cLoginUser2, ApplicationName, MB_OK or MB_ICONINFORMATION);
        ModalResult := mrNone;
      end
      else
      begin
        FUsersInfo.LoggedUserInfo := UserInfo;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_LoginUser.btOkClick', E.Message);
  end;
end;

function LogInUser(AUsersInfo: TUsersInfo; AFormOwner: TForm; ACanRememberPass, AReadFromRegistry: Boolean;
  ADefUser: TUserInfo; ACaption: String): Boolean;
var
  UserInfoCmp: TUserInfo;
  DefUserNameU: String;
  i: Integer;
  F_LoginUser: TF_LoginUser;
begin
  Result := false;

  if ADefUser <> nil then
    // Если НЕ нажата клавиша Шифт
    if HiWord(GetKeyState(VK_SHIFT)) = 0 then
    begin
      DefUserNameU := AnsiUpperCase(ADefUser.Name);
      for i := 0 to AUsersInfo.UsersInfo.Count - 1 do
      begin
        UserInfoCmp := TUserInfo(AUsersInfo.UsersInfo[i]);
        if AnsiUpperCase(UserInfoCmp.Name) = DefUserNameU then
          if UserInfoCmp.Pass = ADefUser.Pass then
          begin
            AUsersInfo.LoggedUserInfo := UserInfoCmp;

            Result := true;
            Break; //// BREAK ////
          end;
      end;
    end;

  if Not Result then
  begin
    F_LoginUser := TF_LoginUser.Create(nil, AFormOwner);
    try
      Result := F_LoginUser.Execute(AUsersInfo, ACanRememberPass, AReadFromRegistry, ACaption);
    finally
      FreeAndNil(F_LoginUser);
    end;
  end;
end;


procedure TF_LoginUser.FormShow(Sender: TObject);
begin
  if cbUsers.Text = '' then
    cbUsers.SetFocus
  else
    edPass.SetFocus;
end;

end.