//---------------------------------------------------------------------------

#include <vcl.h>
#include <inifiles.hpp>
#pragma hdrstop

#include "LogIn_Form.h"
#include "Environment.h"
#include "Message_Form.h"
#include "Keyboard_Form.h"
#include "UserRegister_Form.h"
#include "RequestPasswordChange_Form.h"
#include "MultiLanguage.h"

#include <stdio.h>
#include <io.h>
#include "Main_Form.h"
#include "InputText_Dialog.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntExtCtrls"
#pragma link "TntGrids"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"
TLogInForm *LogInForm;
//---------------------------------------------------------------------------
__fastcall TLogInForm::TLogInForm(TComponent* Owner)
	: TTntForm(Owner)
{
	if (DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
		ComponentSetFontName(this, "SimSun");
	else if (DefaultLCID == 1041)
		ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

	StaticText1->Caption = LOGINFORM_TEXT_CAPTION_02;
	StaticText2->Caption = LOGINFORM_TEXT_CAPTION_01;
	CurrentUserName = "";
	CurrentUserWrongPWCount = 0;

  LoginMsgList[0] = LOGINFORM_TEXT_CAPTION_03;
  LoginMsgList[1] = LOGINFORM_TEXT_CAPTION_04;
  LoginMsgList[2] = LOGINFORM_TEXT_CAPTION_05;
  LoginMsgList[3] = LOGINFORM_TEXT_CAPTION_06;

}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::LogInBtnClick(TObject *Sender)
{
	bool bUserNameExist = true;
	bool bPWCorrect = false;
	bool bSystemLogOn = false;

	bool bUserLogOn = false;
	int PWLockCount = 0; // 아이디 Lock을 걸기위해서 레지스트리의 저장값을 담아놓는 변수

	if (PWEdit->Text == "nfauserunlockpw")
	{
		// nfauserunlockpw를 입력하면 시스템 계정의 락이 풀린다.
		_DeleteReg("SOFTWARE\\NFA", "system");
		PWEdit->Text = "";
		return;
	}

	if (CurrentUserName != UserNameEdit->Text.LowerCase())
	{
		//CSV_WriteLogInAttemptCount();
		CurrentUserName = UserNameEdit->Text.LowerCase();
	}

	// 2019-08-22
	// 권한 변경 관련 최초 시스템에 프로그램 적용 시 기존의 ID가 존재한다면 system 계정으로 로그인해서 기존 ID의 권한을 설정해야 장비 사용이 가능
	if (bRequestSystemIDLogIn)
	{
		if (UserNameEdit->Text.LowerCase() != "system")
		{
			MessageDlgFA(SYSTEM_AUTHORITY_LOGIN_ERROR_MSG_01, mtConfirmation, TMsgDlgButtons() << mbOK);
			return;
		}
	}

	if (UserNameEdit->Text.LowerCase() == "system")
	{
		AnsiString fileName = ProgramPath.Env + "\\systemUser.dat";

		if (FileExists(fileName))
		{
			TFileStream *pFileStream = new TFileStream(fileName, fmOpenRead);

			int passwordLength;
			pFileStream->Read(&passwordLength, sizeof(int));

			char *existPW = new char[passwordLength];
			memset(existPW, 0, sizeof(char) * passwordLength);

			for (int i = 0; i < passwordLength; i++)
			{
				pFileStream->Read(&existPW[i], sizeof(char));
			}

			char tempLoadPassword[100];
			memset(tempLoadPassword, 0, sizeof(char) * 100);
			memcpy(tempLoadPassword, existPW, passwordLength);

			AnsiString tempPW = AnsiString(tempLoadPassword);

			if (PWEdit->Text == tempPW)
			{
				UserInfo.AccessLevel = SYSTEM_HIGHEST_ACCESS_LEVEL;
				UserInfo.Name = "system";
				bPWCorrect = true;
				bSystemLogOn = true;
			}

			delete existPW;
			delete pFileStream;
		}
		else
		{
			if (PWEdit->Text == "111111")
			{
				UserInfo.AccessLevel = SYSTEM_HIGHEST_ACCESS_LEVEL;
				UserInfo.Name = "system";
				bPWCorrect = true;
				bSystemLogOn = true;
			}
		}
	}
	else // 기본 사용 유저 접근
	{
		if (UserNameEdit->Text != "")
		{
			int logInResult = 0;

			if(PCProgramOption.CareUpperLowCasePasswordEnabled)
			{
				logInResult = CheckUserNameAndPassword(UserNameEdit->Text.LowerCase(), PWEdit->Text);
			}
			else
			{
				logInResult = CheckUserNameAndPassword(UserNameEdit->Text.LowerCase(), PWEdit->Text.LowerCase());
			}      

			if (logInResult == 0)
			{
				bUserNameExist = true;
				bPWCorrect = true;
			}
			else if (logInResult == -2 || logInResult == -1)
			{
				bUserNameExist = false;
			}
			else if (logInResult == -3)
			{
				bPWCorrect = false;
			}

			if (bUserNameExist)
			{
				TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\user.ini");
				int AccessLevel;

        UserInfo.Name = UserNameEdit->Text;

				if (iniFile)
				{
					AccessLevel = iniFile->ReadInteger(UserNameEdit->Text.LowerCase(), "Access Level", SYSTEM_ACCESS_LEVEL_ANONYMOUS);
          UserInfo.AccessLevel = AccessLevel;
				}
				delete iniFile;

				if (AccessLevel == SYSTEM_ACCESS_LEVEL_ANONYMOUS)
				{
					MessageDlgFA(SYSTEM_AUTHORITY_LOGIN_ERROR_MSG_02, mtError, TMsgDlgButtons() << mbOK);
					return;
				}
			}
		}
		else
		{
			bUserNameExist = false;
		}

		if (bUserNameExist && bPWCorrect)
			bUserLogOn = true;
	}

	// 가장 우선순위로 Active의 상태를 체크한다. (아젠타만)
	if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
	{
		//if (bUserNameExist && bPWCorrect)
		if(bUserNameExist)		
		{
			TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\user.ini");
			bool Status = iniFile->ReadBool(UserNameEdit->Text.LowerCase().c_str(), "AcDeactive", false);
			if (Status)
			{
				MessageDlgFA(LoginMsgList[3], mtError, TMsgDlgButtons() << mbOK);
				delete iniFile;
				return;
			}
		}
	}


	if (bUserNameExist || bSystemLogOn)
	{
		if (_IDUnlockCheckReg("SOFTWARE\\NFA", UserNameEdit->Text.LowerCase().c_str()) != 1)
		{
			PWLockCount = _ReadReg("SOFTWARE\\NFA", UserNameEdit->Text.LowerCase().c_str());
			if (CurrentUserWrongPWCount >= ComputerSystemInfo.PasswordFailAvailableCount)
			{
				// 비밀번호 연속 오입력으로 인한 계정 비활성화
				MessageDlgFA(LoginMsgList[0], mtError, TMsgDlgButtons() << mbOK);
				AddCSVActionLog(ECSV_ACTION_EXPIRATION_LOCK_USER, UserNameEdit->Text.LowerCase(), "", NULL, 0);
				return;
			}
		}
		else if (UserNameEdit->Text != "system")
		{
			TRequestPasswordChangeForm *requestPasswordChangeForm = new TRequestPasswordChangeForm(this, UserNameEdit->Text.LowerCase(), 1);
			if (requestPasswordChangeForm->ShowModal() == mrOk)
			{
				if (LoadUserInfo(UserNameEdit->Text.LowerCase()))
				{
					WriteRecentLogOn();
					ModalResult = mrOk;

					_DeleteReg("SOFTWARE\\NFA", UserNameEdit->Text.LowerCase().c_str());

					bPWCorrect = true;
					bUserLogOn = true;

					if (ComputerSystemInfo.FirstLoginChangePW)
					{
						TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\user.ini");
						iniFile->WriteBool(UserNameEdit->Text, "FirstLogin", true);
						delete iniFile;
					}
				}
				else
				{
					ModalResult = mrCancel;
					return;
				}
			}
			else
			{
				ModalResult = mrCancel;
				return;
			}
		}
	}

	if (!bSystemLogOn)
	{
		TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\user.ini");
		if (ComputerSystemInfo.FirstLoginChangePW && bPWCorrect)
		{
			if (iniFile)
			{
				bool FirstLogin;
				FirstLogin = iniFile->ReadBool(UserNameEdit->Text, "FirstLogin", "");
				if (FirstLogin == false)
				{
					MessageDlgFA(LoginMsgList[1], mtError, TMsgDlgButtons() << mbOK);

					TRequestPasswordChangeForm *requestPasswordChangeForm = new TRequestPasswordChangeForm(this, UserNameEdit->Text.LowerCase(), 1);
					if (requestPasswordChangeForm->ShowModal() == mrOk)
					{
						if (LoadUserInfo(UserNameEdit->Text.LowerCase()))
						{
							iniFile->WriteBool(UserNameEdit->Text, "FirstLogin", true);

							WriteRecentLogOn();
							ModalResult = mrOk;
						}
						else
						{
							delete iniFile;
							ModalResult = mrCancel;

							return;
						}
					}
				}
			}
		}

		delete iniFile;
	}

	if (bSystemLogOn)
	{
		//CSV_WriteLogInAttemptCount();
		WriteRecentLogOn();
		ModalResult = mrOk;
	}
	else if (bUserNameExist && bPWCorrect)
	{
		//CSV_WriteLogInAttemptCount();

		if (!ComputerSystemInfo.PasswordExpirationEnabled || bSystemLogOn)
		{
			if (LoadUserInfo(UserNameEdit->Text.LowerCase()))
			{
				WriteRecentLogOn();
				ModalResult = mrOk;
			}
			else
			{
				ModalResult = mrCancel;
			}
		}
		else
		{
			if (CheckPasswordExpiration(UserNameEdit->Text.LowerCase(), ComputerSystemInfo.PasswordExpirationTime))
			{
				// 비밀번호 기간 만료
				AddCSVActionLog(ECSV_ACTION_EXPIRATION_LOCK_USER, UserNameEdit->Text.LowerCase(), "", NULL, 0);
				TRequestPasswordChangeForm *requestPasswordChangeForm = new TRequestPasswordChangeForm(this, UserNameEdit->Text.LowerCase(), 1);
				if (requestPasswordChangeForm->ShowModal() == mrOk)
				{
					if (LoadUserInfo(UserNameEdit->Text.LowerCase()))
					{
						WriteRecentLogOn();
						ModalResult = mrOk;
					}
					else
					{
						ModalResult = mrCancel;
					}
				}
			}
			else
			{
				if (LoadUserInfo(UserNameEdit->Text.LowerCase()))
				{
					WriteRecentLogOn();
					ModalResult = mrOk;
				}
				else
				{
					ModalResult = mrCancel;
				}
			}
		}
	}
	else if (!bUserNameExist)
	{
		CSV_WriteUnpermittedUser(UserNameEdit->Text.LowerCase());
		MessageDlgFA(LOGINFORM_MSG_02, mtError, TMsgDlgButtons() << mbOK);
	}
	else if (!bPWCorrect)
	{
		CurrentUserWrongPWCount++;
		CSV_WriteLogInAttemptCount();
		if (PWLockCount == 0)
		{
			_CreateReg("SOFTWARE\\NFA", UserNameEdit->Text.LowerCase().c_str());
		}
		else
		{
			int Error = _SetValueReg("SOFTWARE\\NFA", UserNameEdit->Text.LowerCase().c_str(), ++PWLockCount);
		}

		MessageDlgFA(LOGINFORM_MSG_01, mtError, TMsgDlgButtons() << mbOK);
	}

	if (bSystemLogOn || bUserLogOn)
	{
		// log in에 성공하면 비밀번호 기입 오류 초기화
		_DeleteReg("SOFTWARE\\NFA", UserInfo.Name.LowerCase().c_str());
	}

  KeyMonitorActive();
}
//---------------------------------------------------------------------------

void __fastcall TLogInForm::PWEditClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	TKeyboardForm *logInKeyboardForm = new TKeyboardForm(this);	// 키보드 입력 중 자동 로그아웃 되는 상황에 대처하기 위하여 키보드를 새로 만든다.
	logInKeyboardForm->IsHangulMode = KeyboardForm->IsHangulMode;
	logInKeyboardForm->CapsLockState = KeyboardForm->CapsLockState;
	logInKeyboardForm->Text = theEdit->Text;
	if (logInKeyboardForm->ShowPasswordKeyboard() == mrOk)
	{
		theEdit->Text = logInKeyboardForm->Text;
	}
	KeyboardForm->IsHangulMode = logInKeyboardForm->IsHangulMode;
	KeyboardForm->CapsLockState = logInKeyboardForm->CapsLockState;
	delete logInKeyboardForm;
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::UserNameEditClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	TKeyboardForm *logInKeyboardForm = new TKeyboardForm(this);	// 키보드 입력 중 자동 로그아웃 되는 상황에 대처하기 위하여 키보드를 새로 만든다.
	logInKeyboardForm->IsHangulMode = KeyboardForm->IsHangulMode;
	logInKeyboardForm->CapsLockState = KeyboardForm->CapsLockState;
  logInKeyboardForm->JP_IDInputKeyBoard = true;
	logInKeyboardForm->Text = theEdit->Text;
  if (logInKeyboardForm->ShowKeyboard() == mrOk)
  {
    theEdit->Text = logInKeyboardForm->Text;
  }

	KeyboardForm->IsHangulMode = logInKeyboardForm->IsHangulMode;
	KeyboardForm->CapsLockState = logInKeyboardForm->CapsLockState;
	delete logInKeyboardForm;
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::FormCreate(TObject *Sender)
{
    LogInBtn->Caption = LOGINFORM_TEXT_CAPTION_07;
    
	ReadRecentLogOn();

	bRequestSystemIDLogIn = false;


}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::WriteRecentLogOn(void)
{
	TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
	if (iniFile)
	{
		iniFile->WriteString("Recent Log On", "User Name", UserNameEdit->Text);
		delete iniFile;
	}
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::ReadRecentLogOn(void)
{
	TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
	if (iniFile)
	{
		UserNameEdit->Text = iniFile->ReadString("Recent Log On", "User Name", "");
		delete iniFile;
	}
}
//---------------------------------------------------------------------------
bool __fastcall CheckPassword(AnsiString ID, AnsiString password)
{
	bool bUserNameExist = true;
	bool bPWCorrect = false;
	bool bSystemLogOn = false;
	if (ID.LowerCase() == "system")
	{
		if (password == "111111")
		{
			UserInfo.AccessLevel = SYSTEM_HIGHEST_ACCESS_LEVEL;
			UserInfo.Name = "system";
			bPWCorrect = true;
			bSystemLogOn = true;
		}
	}
	else
	{
		if (ID != "")
		{
			int logInResult = CheckUserNameAndPassword(ID.LowerCase(), password.LowerCase());
			if (logInResult == 0)
			{
				bUserNameExist = true;
				bPWCorrect = true;
			}
			else if (logInResult == -2 || logInResult == -1)
			{
				bUserNameExist = false;
			}
			else if (logInResult == -3)
			{
				bPWCorrect = false;
			}
		}
		else
		{
			bUserNameExist = false;
		}
	}
	if (bSystemLogOn)
	{
		return true;
	}
	else if (bUserNameExist && bPWCorrect)
	{
		return true;
	}
	else if (!bUserNameExist)
	{
		return false;
	}
	else if (!bPWCorrect)
	{
		return false;
	}
}
//---------------------------------------------------------------------------


void __fastcall TLogInForm::FormDestroy(TObject *Sender)
{
	//CSV_WriteLogInAttemptCount();
	CurrentUserWrongPWCount = 0;
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::CSV_WriteLogInAttemptCount(void)
{
	if (CurrentUserWrongPWCount != 0)
	{
		AddCSVActionLog(ECSV_ACTION_WRONG_PASSWORD, CurrentUserName, "", (unsigned char *)&CurrentUserWrongPWCount, sizeof(int));
	}
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::CSV_WriteUnpermittedUser(AnsiString userName)
{
	AddCSVActionLog(ECSV_ACTION_UNPERMITTED_USER, userName, "", NULL, 0);
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::TntFormShow(TObject *Sender)
{
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if(!MachineSetupData.InterlockInfo.ACdomesticMode)
    {
      if(UserInfo.Status == USER_STATUS_LOGOUT)
      {
        MainForm->SetLastSafetyMode(0);
        Comm_Request(COMM_HCB, CMD_SAFETY_REVERT);
      }
    }
    else
    {
      MainForm->SetLastSafetyMode(1);
      Comm_Request(COMM_HCB, CMD_SAFETY_MAINTAENACE);
      MachineSetupData.SafetyCircuitMode = 1;
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TLogInForm::UserNameEditChange(TObject *Sender)
{
  CurrentUserWrongPWCount = 0;
}
//---------------------------------------------------------------------------

