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

#include <vcl.h>
#include <pcre.h>
#include <stdio.h>
#include "GlobalUnit.h"
#pragma hdrstop

#include "LoginFormUnit.h"
#include "MessageFormUnit.h"
#include "VerifyCodeFormUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "GeneralDialogPanel"
#pragma link "LineEdit"
#pragma link "TextButton"
#pragma link "CKBox"
#pragma resource "*.dfm"

TLoginForm *LoginForm = NULL;

const char *g_pPattern[5] = {"^[_a-zA-Z0-9\\xA1-\\xFE\\.-]{3,16}$",
				"^[_a-zA-Z0-9\\.-]+@([_a-zA-Z0-9]+\\.)+[a-zA-Z0-9]{2,3}$",
				"^[\\x21-\\x7E]{3,16}$",
				"^[\\x21-\\x7E]{6,16}$",
				"^$|^1(3\\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\\d|9[0-35-9])\\d{8}$"
			};

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

__fastcall TLoginForm::TLoginForm(TComponent* Owner)
	: TForm(Owner)
{
	FIsLogin = true;
//	m_logPasswordEdit->PasswordChar = L'*';
//	m_regPasswordEdit->PasswordChar = L'*';
//	m_ConfirmEdit->PasswordChar = L'*';
    isEmailOrMobile = 0;

	for( int i=0; i<ComponentCount; i++ ){
		if(Components[i]->ClassNameIs( TLabel::ClassName() ) )
			((TLabel*)Components[i])->ControlStyle>>csOpaque;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::FormCreate(TObject *Sender)
{
	m_logDialogPanel->Font->Size = g_szFont9;
	m_logUserEdit->SetTextFont(g_strTxtFontName, g_szFont9);
	m_logPasswordEdit->SetTextFont(g_strTxtFontName, g_szFont9);
	m_logButton->FontSize = g_szFont9;

	m_regDialogPanel->Font->Size = g_szFont9;
	m_regUserEdit->SetTextFont(g_strTxtFontName, g_szFont9);
	m_regPasswordEdit->SetTextFont(g_strTxtFontName, g_szFont9);
	m_VerifyEdit->SetTextFont(g_strTxtFontName, g_szFont9);
	m_ConfirmEdit->SetTextFont(g_strTxtFontName, g_szFont9);
	m_IsAutoLogin->Font->Size = g_szFont9;
	m_ckAgree->Font->Size = g_szFont9;
	m_regButton->FontSize = g_szFont9;
    m_sendButton->FontSize = g_szFont9;

	FUserName = String(g_infoUser.strUserName);
	m_logUserEdit->Text = FUserName;

	char strURL[256];
	f_CS_GetWebPageURL( URL_REGCODE, strURL );

	RESTClient->BaseURL = String(strURL);
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::FormShow(TObject *Sender)
{
	Layout();
}
//---------------------------------------------------------------------------

bool __fastcall TLoginForm::CheckInput(const char * pText, int type)
{
    bool bRet = false;
	pcre *pPcre = NULL;
	int nOffset = -1;
	const char *pPattern = g_pPattern[type];
	const char *pErrMsg = NULL;

	if( NULL == (pPcre = pcre_compile(pPattern, 0, &pErrMsg, &nOffset, NULL)) ){
		printf("pcre_compile ErrMsg=%s\n", pErrMsg);
	}
	else{
		if( pcre_exec(pPcre, NULL, pText, strlen(pText), 0, NULL, 0) < 0 ){
			printf("%s doesn't match %s\n", pText, pPattern);
		}
		else{
			printf("%s matches %s\n", pText, pPattern);
			bRet = true;
		}

		pcre_free(pPcre);
	}

	return bRet;
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::DoGoClick(TObject *Sender)
{
	if(FIsLogin){
		m_logUserEdit->Text = m_logUserEdit->Text.Trim();
		m_logPasswordEdit->Text = m_logPasswordEdit->Text.Trim();

		if(m_logUserEdit->Text.IsEmpty()){
			m_logUserEdit->SetFocus();
		}
		else if(m_logPasswordEdit->Text.IsEmpty()){
			m_logPasswordEdit->SetFocus();
		}
		else{
			bool bCheckOk = true;
			AnsiString astrUN = m_logUserEdit->Text;
			if( !CheckInput(astrUN.c_str(), 0) && !CheckInput(astrUN.c_str(), 1 )){
				m_logUserEdit->Text = "";
				m_logUserEdit->SetFocus();
				bCheckOk = false;
			}
			else{
				AnsiString astrPW = m_logPasswordEdit->Text;
				if(!CheckInput(astrPW.c_str(), 2)){
					m_logPasswordEdit->Text = "";
					m_logPasswordEdit->SetFocus();
					bCheckOk = false;
				}
			}

			if(bCheckOk){
				FUserName = m_logUserEdit->Text;
				FPassword = m_logPasswordEdit->Text;
				ModalResult = mrOk;

				string strUN = AnsiString(FUserName).c_str();
				string strPW = AnsiString(FPassword).c_str();
				SetAutoLogin(FAutoLogin, strUN.c_str(), strPW.c_str());
			}
		}
	}
	else{
		m_regUserEdit->Text = m_regUserEdit->Text.Trim();
		m_regPasswordEdit->Text = m_regPasswordEdit->Text.Trim();
		m_ConfirmEdit->Text = m_ConfirmEdit->Text.Trim();
		m_VerifyEdit->Text = m_VerifyEdit->Text.Trim();

		if(m_regUserEdit->Text.IsEmpty()){
			m_regUserEdit->SetFocus();
		}
		else if(m_VerifyEdit->Text.IsEmpty()){
			m_VerifyEdit->SetFocus();
		}
		else if(m_regPasswordEdit->Text.IsEmpty()){
			m_regPasswordEdit->SetFocus();
		}
		else if(m_ConfirmEdit->Text.IsEmpty()){
			m_ConfirmEdit->SetFocus();
		}
		else{
			AnsiString astrPW = m_regPasswordEdit->Text;
			if(!CheckInput(astrPW.c_str(), 3)){
				m_regPasswordEdit->Text = "";
				m_regPasswordEdit->SetFocus();

				return;
			}

			if(m_regPasswordEdit->Text.Compare(m_ConfirmEdit->Text)){
				m_ConfirmEdit->Text = "";
				m_ConfirmEdit->SetFocus();

				return;
			}

			AnsiString astrUN = m_regUserEdit->Text;

            if( CheckInput(astrUN.c_str(), 1) ){
                isEmailOrMobile = 1;
            }
			else if( CheckInput(astrUN.c_str(), 4) ){
                isEmailOrMobile = 2;
            }
            else{
				m_regUserEdit->Text = "";
				m_regUserEdit->SetFocus();

				return;
			}

            this->Enabled = false;
			Screen->Cursor = crHourGlass;
			AnsiString strVerify = m_VerifyEdit->Text;

			RESTRequest->Resource = "verifyRegCode";
            RESTRequest->Params->Clear();
			RESTRequest->Params->AddItem("username", astrUN);
			RESTRequest->Params->AddItem("verifyCode", strVerify);

            try{
                RESTRequest->Execute();
            }
            catch (Exception &exception){
                DebugPrint("exception: %s", exception.Message );
            }

			Screen->Cursor = crDefault;
            this->Enabled = true;

			if(RESTResponse->StatusCode==200){
				TJSONValue *jValue = RESTResponse->JSONValue;
				if(jValue==NULL)
					return;

				TJSONValue *jCode = jValue->FindValue("code");
				if( jCode==NULL )
					return;

				String code =  ((TJSONString*)jCode)->Value();
				if(code!="00000"){
                    String msg;
                    if(code=="A0213")
                        msg = "注册验证码已过期";
                    else if(code=="A0214")
                        msg = "注册验证码错误";
                    else
						msg = ((TJSONString*)jValue->FindValue("msg"))->Value();

					MessageForm->ShowMessage( msg, MB_ICONERROR | MB_OK );

					return;
				}
			}
			else{
				MessageForm->ShowMessage( RESTResponse->StatusText, MB_ICONERROR | MB_OK );
				return;
			}

			FUserName = m_regUserEdit->Text;
			FPassword = m_regPasswordEdit->Text;
			ModalResult = mrOk;
		}
    }
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::DoSwitchClick(TObject *Sender)
{
	FIsLogin = Sender!=(TObject*)m_logSwitchLabel;

	Layout();
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::DoAutoCheck(TObject *Sender)
{
	FAutoLogin = m_IsAutoLogin->Checked;
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::Layout()
{
	if( FIsLogin ){
		m_logDialogPanel->Visible = true;
		m_regDialogPanel->Visible = false;

		Height = 190;

		if( m_logUserEdit->Text.IsEmpty() ){
			m_logUserEdit->SetFocus();
		}
		else if( m_logPasswordEdit->Text.IsEmpty() ){
			m_logPasswordEdit->SetFocus();
		}
	}
	else{
		m_logDialogPanel->Visible = false;
		m_regDialogPanel->Visible = true;

		Height = 235;

		m_ckAgree->Checked = true;
		m_ConfirmEdit->Text = "";

		if( m_regUserEdit->Text.IsEmpty() ){
			m_regUserEdit->SetFocus();
		}
		else if( m_VerifyEdit->Text.IsEmpty() ){
			m_VerifyEdit->SetFocus();
		}
		else if( m_regPasswordEdit->Text.IsEmpty() ){
			m_regPasswordEdit->SetFocus();
		}
		else if( m_ConfirmEdit->Text.IsEmpty() ){
			m_ConfirmEdit->SetFocus();
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::SetUserName(String Value)
{
	if(FUserName != Value){
        FUserName = Value;
		m_logUserEdit->Text = Value;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::SetPassWord(String Value)
{
	if(FPassword != Value){
		FPassword = Value;
		m_logPasswordEdit->Text = Value;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::SetConfirm(String Value)
{
	if(FConfirm != Value){
		FConfirm = Value;
		m_ConfirmEdit->Text = Value;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::SetVerify(String Value)
{
	if(FVerify != Value){
		FVerify = Value;
		m_VerifyEdit->Text = Value;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::SetIsLogin(bool Value)
{
	if(FIsLogin != Value){
		FIsLogin = Value;

		Layout();
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::SetIsAntoLogin(bool Value)
{
	if(FAutoLogin != Value){
		FAutoLogin = Value;
		m_IsAutoLogin->Checked = Value;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
	switch( Key ){
	case VK_RETURN:
		DoGoClick(NULL);
		break;

	case VK_ESCAPE:
		ModalResult = mrCancel;
		break;
	}
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::AgreementMouseEnter(TObject *Sender)
{
	m_lblAgreement->Font->Color = RGB(0, 255, 255);
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::AgreementMouseLeave(TObject *Sender)
{
	m_lblAgreement->Font->Color = RGB(0, 200, 200);
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::AgreementClick(TObject *Sender)
{
	char strURL[256];
	f_CS_GetWebPageURL( URL_USERAGREEMENT, strURL );
	ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::LinkLabelMouseEnter(TObject *Sender)
{
	TLabel* pLabel = (TLabel*)Sender;
	pLabel->Font->Color = RGB(225, 235, 245);
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::LinkLabelMouseLeave(TObject *Sender)
{
	TLabel* pLabel = (TLabel*)Sender;
	pLabel->Font->Color = RGB(191,203,218);
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::AgreeChange(TObject *Sender)
{
	m_regButton->Enabled = m_ckAgree->Checked;
}
//---------------------------------------------------------------------------

void __fastcall TLoginForm::DoSendClick(TObject *Sender)
{
//	m_regUserEdit->Text = m_regUserEdit->Text.Trim();
//	if(m_regUserEdit->Text.IsEmpty()){
//		m_regUserEdit->SetFocus();
//		return;
//	}
//
	AnsiString astrUN = m_regUserEdit->Text;
//	if( !CheckInput(astrUN.c_str(), 1) && !CheckInput(astrUN.c_str(), 4 )){
//		m_regUserEdit->Text = "";
//		m_regUserEdit->SetFocus();
//		return;
//	}

	String sKey, sCode;
	TVerifyCodeForm* pForm = new TVerifyCodeForm(NULL, RESTClient->BaseURL);
	if( pForm->ShowModal() == mrOk){
		sKey = pForm->GetKey();
		sCode = pForm->GetCode();
	}
	delete pForm;

	if(sKey.Length()==0 || sCode.Length()==0)
		return;

	this->Enabled = false;
	Screen->Cursor = crHourGlass;

	RESTRequest->Resource = "sendRegCode";
	RESTRequest->Params->Clear();
	RESTRequest->Params->AddItem("contact", astrUN);
	RESTRequest->Params->AddItem("captchaKey", sKey);
	RESTRequest->Params->AddItem("captchaCode", sCode);

	try{
		RESTRequest->Execute();
	}
	catch (Exception &exception){
		DebugPrint("exception: %s", exception.Message );
	}

	Screen->Cursor = crDefault;
	this->Enabled = true;

	if(RESTResponse->StatusCode==200){
		TJSONValue *jValue = RESTResponse->JSONValue;
		if(jValue==NULL)
			return;

		TJSONValue *jCode = jValue->FindValue("code");
		if( jCode==NULL )
			return;

		String code =  ((TJSONString*)jCode)->Value();
		if(code=="00000"){
			m_sendButton->Text = String(CODE_INTERVAL) + "秒";
			m_sendButton->Enabled = false;

			PostMessage(Application->MainFormHandle, UM_STARTCDTIMER, 0, 0);
			MessageForm->ShowMessage("已向 " + astrUN + " 发送注册验证码\n（15分钟内有效，请勿重复提交!）", MB_OK | MB_ICONINFORMATION);
		}
		else{
        	String msg;
            if(code=="A0213")
                msg = "人机验证码已过期";
            else if(code=="A0214")
                msg = "人机验证码错误";
            else
                msg = ((TJSONString*)jValue->FindValue("msg"))->Value();

			MessageForm->ShowMessage( msg, MB_ICONERROR | MB_OK );
		}
	}
	else{
		MessageForm->ShowMessage( RESTResponse->StatusText, MB_ICONERROR | MB_OK );
	}
}

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

void __fastcall TLoginForm::OnCDTimer(int countDown)
{

	if( countDown==0 ){
		m_sendButton->Text = "重新发送";
		m_sendButton->Enabled = true;
	}
	else{
		m_sendButton->Text = String(countDown) + "秒";
		m_sendButton->Enabled = false;
	}

	m_sendButton->Invalidate();
}
//---------------------------------------------------------------------------


void __fastcall TLoginForm::ResetPassClick(TObject *Sender)
{
	char strURL[256];
	f_CS_GetWebPageURL( URL_RESETPASS, strURL );
	ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------

