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

#include <vcl.h>
#include "AppGlobalF.h"
#include "ITSUtilF.h"
#include "ITSDbF.h"
#include "EncryptionF.h"
#pragma hdrstop

#include <ADODB.hpp>
#include <DB.hpp>
#include <winsock.h>

#include "FrmLoginF.h"
#include "FrmPswdChngeF.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "cxButtons"
#pragma link "cxContainer"
#pragma link "cxControls"
#pragma link "cxEdit"
#pragma link "cxGraphics"
#pragma link "cxLabel"
#pragma link "cxLookAndFeelPainters"
#pragma link "cxLookAndFeels"
#pragma link "dxSkinBlack"
#pragma link "dxSkinBlue"
#pragma link "dxSkinsCore"
#pragma link "dxGDIPlusClasses"
#pragma resource "*.dfm"

TFRMLogin *FRMLogin = NULL;
//---------------------------------------------------------------------------
__fastcall TFRMLogin::TFRMLogin(TComponent* Owner)
    : TForm(Owner)
{
    //ITSSkin_Load(this);

    m_nLoginTryCnt = 0;

    m_sUserName      = "";  //사용자 명
    m_sUserID        = "";  //사용자 ID
    m_sUserRightID   = "";  //사용자 권한 ID
    m_sUserRightName = "";  //사용자 권한 명
    m_sLoginTime     = "";

    m_bLogin         = false;

    LbMessage->Caption = "";
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::BtnCloseClick(TObject *Sender)
{
    ModalResult = mrCancel;
    Close();
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::BtnPswdChngeClick(TObject *Sender)
{
    try
    {
        FRMPswdChnge = new TFRMPswdChnge(this);

        FRMPswdChnge->EdUserID->Text = EdUserID->Text;

        FRMPswdChnge->ShowModal();

        EdUserID->Text = FRMPswdChnge->EdUserID->Text.Trim();
        EdPswd->Text   = FRMPswdChnge->EdCnfmNewPswd->Text.Trim();

        delete FRMPswdChnge;
        FRMPswdChnge = NULL;
    }
    catch(...)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::BtnLoginClick(TObject *Sender)
{
    String sUserID   = Trim(EdUserID->Text);
    String sUserPswd = Trim(EdPswd->Text);

    //c4ca4238a0b923820dcc509a6f75849b  == "1"
    if (sUserID.Compare("") == 0)
    {
        Application->NormalizeTopMosts();
        if (g_AppCfg.sLang == "kr") Application->MessageBox(L"아이디를 입력하세요.", L"아이디 입력 오류", MB_OK|MB_ICONERROR);     // ID를 입력하세요.
        else                        Application->MessageBox(L"Please enter Use ID.", L"User ID Error", MB_OK|MB_ICONERROR);     // ID를 입력하세요.
        Application->RestoreTopMosts();
        EdUserID->SetFocus();
        return;
    }
    if (sUserPswd.Compare("") == 0)
    {
        Application->NormalizeTopMosts();
        if (g_AppCfg.sLang == "kr") Application->MessageBox(L"비밀번호를 입력하세요.", L"비밀번호 입력 오류", MB_OK|MB_ICONERROR);     // 비밀번호를 입력하세요.
        else                        Application->MessageBox(L"Please enter User Password.", L"Password Error", MB_OK|MB_ICONERROR);     // 비밀번호를 입력하세요.
        Application->RestoreTopMosts();
        EdPswd->SetFocus();
        return;
    }

    int nRes = GetUserPassword(sUserID, sUserPswd);
    if (LOGIN_DB_ERR == nRes)
    {
        return;
    }
    if (LOGIN_OK == nRes)
    {
        m_bLogin = true;
        ModalResult = mrOk;
        //Close();
    }
    else
    {
        String sErrMsg;
        m_bLogin = false;
        if (LOGIN_ID_ERR == nRes)
        {
            if (g_AppCfg.sLang == "kr") sErrMsg = "등록되지 않은 사용자 입니다.";
            else                        sErrMsg = "Unregistered user.";//"등록되지 않은 사용자 입니다.";
            Application->NormalizeTopMosts();
            if (g_AppCfg.sLang == "kr") Application->MessageBox(sErrMsg.c_str(), L"로그인 오류", MB_OK|MB_ICONERROR);     // 등록되지 않은 사용자 입니다.
            else                        Application->MessageBox(sErrMsg.c_str(), L"Login Error", MB_OK|MB_ICONERROR);     // 등록되지 않은 사용자 입니다.
            Application->RestoreTopMosts();
            EdUserID->SetFocus();
        }
        if (LOGIN_PSWD_ERR == nRes)
        {
            if (g_AppCfg.sLang == "kr") sErrMsg = "비밀번호가 정확하지 않습니다.";
            else                        sErrMsg = "The password is incorrect.";//"비밀번호가 정확하지 않습니다.";
            Application->NormalizeTopMosts();
            if (g_AppCfg.sLang == "kr") Application->MessageBox(sErrMsg.c_str(), L"로그인 오류", MB_OK|MB_ICONERROR);     // 비밀번호가 정확하지 않습니다.
            else                        Application->MessageBox(sErrMsg.c_str(), L"Login Error", MB_OK|MB_ICONERROR);     // 비밀번호가 정확하지 않습니다.
            Application->RestoreTopMosts();
            EdPswd->SetFocus();
        }
        
        m_nLoginTryCnt++;
        if (g_AppCfg.sLang == "kr") LbMessage->Caption = sErrMsg + "\r\n접속실패 3회면 프로그램이 종료됩니다.\r\n현재 "+String(m_nLoginTryCnt) +" 회";
        else                        LbMessage->Caption = sErrMsg + "\r\nIf the connection fails 3 times, the program ends.\r\nCurrent "+String(m_nLoginTryCnt) +" Trys";
        if (m_nLoginTryCnt >= USER_LOGIN_TRY_CNT)
        {
            Application->NormalizeTopMosts();
            if (g_AppCfg.sLang == "kr") Application->MessageBox(L"사용자 로그인 오류 횟수(3회) 초과 오류입니다.", L"로그인 오류", MB_OK|MB_ICONERROR);     // 사용자 인증오류입니다. 프로그램을 종료합니다.
            else                        Application->MessageBox(L"Error exceeding user login failure count (3).", L"Login Error", MB_OK|MB_ICONERROR);     // 사용자 인증오류입니다. 프로그램을 종료합니다.
            Application->RestoreTopMosts();

            ModalResult = mrCancel;
            //Close();
        }
    }
}
//---------------------------------------------------------------------------

/*
 * 입력된 아이디로 비밀번호를 얻어온다.
 *  parameter
 *   strUserID : 사용자 ID
 *   strPswd   : 조회한 사용자 비밀번호
 *  return
 *   int     : 성공이면 1, 실패면 0
 */
int __fastcall TFRMLogin::GetUserPassword(String sUserID, String sPswd)
{
    int    nRes;
    String sTmpPswd;
    String sEncPswd;
    String sQry;


    nRes     = LOGIN_OK;
    sTmpPswd = "";


    if (!ITSDb_IsOpen())
    {
        if (!ITSDb_Open())
        {
            Application->NormalizeTopMosts();
            if (g_AppCfg.sLang == "kr") Application->MessageBox(L"데이터베이스에 연결할 수 없습니다.", L"데이터베이스 연결 오류", MB_OK|MB_ICONERROR);     // 비밀번호를 입력하세요.
            else                        Application->MessageBox(L"Unable to connect to database.", L"Database Connect Error", MB_OK|MB_ICONERROR);     // 비밀번호를 입력하세요.
            Application->RestoreTopMosts();
            EdPswd->SetFocus();
            return LOGIN_DB_ERR;
        }
    }
    if (!ITSDb_IsOpen())
    {
        return LOGIN_DB_ERR;
    }

    sEncPswd = sPswd;
    sEncPswd = String(ITSSHA256_Encrpyt(AnsiString(sPswd)));

    sQry = "SELECT a.*,                                              \r\n"
           "       a.NAME as levelname,                              \r\n"
           "       a.PWD  as passwordname,                           \r\n"
           "       a.GROP_ID as RIGHTID,                             \r\n"
           "       TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') as logintime \r\n"
           "  FROM TB_USER_INFR a                                    \r\n"
           " WHERE USER_ID = :p01                                    \r\n"
           "   AND DEL_YN <> 'Y'                                     \r\n";
    
    TADOQuery *pADO = NULL;
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
            pADO->Connection = ITSDb_GetConnection();
            pADO->Close();
            pADO->SQL->Text = sQry;
            pADO->Parameters->ParamByName("p01")->Value = sUserID;
            pADO->Prepared = true;
            pADO->Open();
            if (!pADO->Eof)
            {
                pADO->First();
                sTmpPswd = pADO->FieldByName("passwordname")->AsString;

                if (sTmpPswd != sEncPswd)
                {
                    nRes = LOGIN_PSWD_ERR;
                }
                else
                {
                    m_sUserID        = pADO->FieldByName("USER_ID")->AsString;
                    m_sUserName      = pADO->FieldByName("NAME")->AsString;
                    m_sUserRightID   = pADO->FieldByName("NAME")->AsString;
                    m_sUserRightName = pADO->FieldByName("levelname")->AsString;
                    m_sLoginTime     = pADO->FieldByName("logintime")->AsString;
                }
            }
            else
            {
                nRes = LOGIN_ID_ERR;
            }
            pADO->Close();
        }
        catch(EDatabaseError &E)
        {
            nRes = LOGIN_DB_ERR;
            throw Exception(String(E.ClassName())+E.Message);
        }
        catch (Exception &exception)
        {
            nRes = LOGIN_DB_ERR;
            throw Exception(String(exception.ClassName())+exception.Message);
        }
        catch(...)
        {
            nRes = LOGIN_DB_ERR;
            if (g_AppCfg.sLang == "kr")  throw Exception("알수없는 오류가 발생하였습니다.");
            else                         throw Exception("Unknown Error.");
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }

    return nRes;
}
//---------------------------------------------------------------------------

String __fastcall TFRMLogin::GetPassword(String APswd)
{
    int    nRes;
    String sEncPswd = "";
    String sQry;

    sQry = "SELECT SCP.HASH_B64('71', :p01) AS PWD FROM DUAL \r\n";

    TADOQuery *pADO = NULL;
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
            pADO->Connection = ITSDb_GetConnection();
            pADO->Close();
            pADO->SQL->Text = sQry;
            pADO->Parameters->ParamByName("p01")->Value = APswd;
            pADO->Prepared = true;
            pADO->Open();
            if (!pADO->Eof)
            {
                pADO->First();
                sEncPswd = pADO->FieldByName("PWD")->AsString;
            }
            pADO->Close();
        }
        catch(EDatabaseError &E)
        {
            nRes = LOGIN_DB_ERR;
            throw Exception(String(E.ClassName())+E.Message);
        }
        catch (Exception &exception)
        {
            nRes = LOGIN_DB_ERR;
            throw Exception(String(exception.ClassName())+exception.Message);
        }
        catch(...)
        {
            nRes = LOGIN_DB_ERR;
            if (g_AppCfg.sLang == "kr")  throw Exception("알수없는 오류가 발생하였습니다.");
            else                         throw Exception("Unknown Error.");
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }

    return sEncPswd;
}
//---------------------------------------------------------------------------

String __fastcall TFRMLogin::GetLocalIp()
{
    char slocal[256];
    WSAData wsaData;


    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
        return "";


    if (gethostname(slocal, 256) == SOCKET_ERROR)
        return "";

    hostent *hos = gethostbyname(slocal);
    if (hos == NULL)
        return "";

    char *addr = *(hos->h_addr_list);

    String LocalIP = String((unsigned char)addr[0]) + '.'
                   + String((unsigned char)addr[1]) + '.'
                   + String((unsigned char)addr[2]) + '.'
                   + String((unsigned char)addr[3]);
    WSACleanup();
    return LocalIP;
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::FormShow(TObject *Sender)
{
    if (EdUserID->Text != "")
    {
        EdPswd->SetFocus();
    }
    else
    {
        EdUserID->SetFocus();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::EdUserIDKeyPress(TObject *Sender, char &Key)
{
    if (Key == 13)
    {
        EdPswd->SetFocus();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::EdPswdKeyPress(TObject *Sender, char &Key)
{
    if (Key == 13)
    {
        BtnLoginClick(BtnLogin);
    }
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::FormCreate(TObject *Sender)
{
    /*
    *  스킨 변경
    */
    Application->ShowMainForm = false;

    try {
        Application->Icon->LoadFromResourceName(((unsigned int)HInstance), "MAINICON");
    } catch(...) { ShowMessage("LoadFromResourceName failed"); }

	SetLocalSkin();
}
//---------------------------------------------------------------------------

/*
 * 공통으로 처리되지 않는 스킨을 변경한다.
 *  arguments
 *
 *  return
 *      void
 */
void __fastcall TFRMLogin::SetLocalSkin()
{
}
//---------------------------------------------------------------------------

/*
 * 캡션타입틀 마우스 클릭시 화면 이동하기
 *  arguments
 *
 *  return
 *      void
 */
void __fastcall TFRMLogin::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
    ReleaseCapture();
    SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
//---------------------------------------------------------------------------

void __fastcall TFRMLogin::FormClose(TObject *Sender, TCloseAction &Action)
{
    //Action = caFree;
}
//---------------------------------------------------------------------------

