// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Wnd.h"
#include "../../include/pdfwindow/PWL_EditCtrl.h"
#include "../../include/pdfwindow/PWL_Edit.h"
#include "../../include/pdfwindow/PWL_ListBox.h"
#include "../../include/pdfwindow/PWL_ComboBox.h"
#include "../../include/pdfwindow/PWL_Utils.h"

#define PWLCB_DEFAULTFONTSIZE  12.0f

#define IsFloatZero(f)						((f) < 0.0001 && (f) > -0.0001)
#define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatEqual(fa,fb)					IsFloatZero((fa)-(fb))


/* ---------------------------- CPWL_CBListBox ---------------------------- */

FX_BOOL	CPWL_CBListBox::OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag)
{
	CPWL_Wnd::OnLButtonUp(point,nFlag);

	if (m_bMouseDown)
	{
		ReleaseCapture();
		m_bMouseDown = FALSE;	

		if (this->ClientHitTest(point))
		{
			if (CPWL_Wnd * pParent = GetParentWindow())
			{
				pParent->OnNotify(this,PNM_LBUTTONUP,0,PWL_MAKEDWORD(point.x,point.y));			
			}
		
			FX_BOOL bExit = FALSE;
			OnNotifySelChanged(FALSE,bExit, nFlag);
			if (bExit) return FALSE;
		}
	}

	return TRUE;
}

FX_BOOL CPWL_CBListBox::OnKeyDownWithExit(FX_WORD nChar, FX_BOOL & bExit, FX_DWORD nFlag)
{
	if (!m_pList) return FALSE;

	switch (nChar)
	{
	default:
		return FALSE;
	case FWL_VKEY_Up:
	case FWL_VKEY_Down:
	case FWL_VKEY_Home:
	case FWL_VKEY_Left:
	case FWL_VKEY_End:
	case FWL_VKEY_Right:
		break;	
	}

	switch (nChar)
	{
	case FWL_VKEY_Up:
		m_pList->OnVK_UP(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
		break;
	case FWL_VKEY_Down:
		m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
		break;
	case FWL_VKEY_Home:
		m_pList->OnVK_HOME(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
		break;
	case FWL_VKEY_Left:
		m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
		break;
	case FWL_VKEY_End:
		m_pList->OnVK_END(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
		break;
	case FWL_VKEY_Right:
		m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
		break;
	case FWL_VKEY_Delete:
		break;
	}

	OnNotifySelChanged(TRUE,bExit, nFlag);

	return TRUE;
}

FX_BOOL	CPWL_CBListBox::OnCharWithExit(FX_WORD nChar, FX_BOOL & bExit, FX_DWORD nFlag)
{
	if (!m_pList) return FALSE;

	if (!m_pList->OnChar(nChar,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag))) return FALSE;

	if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow())
	{
		pComboBox->SetSelectText();
	}

	OnNotifySelChanged(TRUE,bExit,nFlag);

	return TRUE;
}

/* ---------------------------- CPWL_CBButton ---------------------------- */

void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
{
	CPWL_Wnd::GetThisAppearanceStream(sAppStream);
	
	CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
	
	if (IsVisible() && !rectWnd.IsEmpty())
	{
		CFX_ByteTextBuf sButton;	

		CPDF_Point ptCenter = this->GetCenterPoint();

		CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
		CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
		CPDF_Point pt3(ptCenter.x,ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);

		if (IsFloatBigger(rectWnd.right - rectWnd.left,PWL_CBBUTTON_TRIANGLE_HALFLEN * 2)
			&&
			IsFloatBigger(rectWnd.top - rectWnd.bottom,PWL_CBBUTTON_TRIANGLE_HALFLEN)
			)
		{
			sButton << "0 g\n";
			sButton << pt1.x << " " << pt1.y << " m\n";
			sButton << pt2.x << " " << pt2.y << " l\n";
			sButton << pt3.x << " " << pt3.y << " l\n";
			sButton << pt1.x << " " << pt1.y << " l f\n";

			sAppStream << "q\n" << sButton << "Q\n";
		}	
	}
}

void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
{
	CPWL_Wnd::DrawThisAppearance(pDevice,pUser2Device);

	CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
	
	if (IsVisible() && !rectWnd.IsEmpty())
	{
		CPDF_Point ptCenter = this->GetCenterPoint();

		CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
		CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
		CPDF_Point pt3(ptCenter.x,ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);

		if (IsFloatBigger(rectWnd.right - rectWnd.left,PWL_CBBUTTON_TRIANGLE_HALFLEN * 2)
			&&
			IsFloatBigger(rectWnd.top - rectWnd.bottom,PWL_CBBUTTON_TRIANGLE_HALFLEN)
			)
		{
			CFX_PathData path;

			path.SetPointCount(4);
			path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
			path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
			path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
			path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);

			pDevice->DrawPath(&path, pUser2Device, NULL, 
				CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,GetTransparency()), 
				0, FXFILL_ALTERNATE);
		}
	}
}

FX_BOOL	CPWL_CBButton::OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag)
{
	CPWL_Wnd::OnLButtonDown(point,nFlag);

	SetCapture();

	if (CPWL_Wnd * pParent = GetParentWindow())
	{		
		pParent->OnNotify(this,PNM_LBUTTONDOWN,0,PWL_MAKEDWORD(point.x,point.y));
	}
	
	return TRUE;
}

FX_BOOL	CPWL_CBButton::OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag)
{
	CPWL_Wnd::OnLButtonUp(point, nFlag);

	ReleaseCapture();

	return TRUE;
}

/* ---------------------------- CPWL_ComboBox ---------------------------- */

CPWL_ComboBox::CPWL_ComboBox() : m_pEdit(NULL),
	m_pButton(NULL),
	m_pList(NULL),
	m_bPopup(FALSE),
	m_nPopupWhere(0),
	m_nSelectItem(-1),
	m_pFillerNotify(NULL)
{
}

CFX_ByteString CPWL_ComboBox::GetClassName() const
{
	return "CPWL_ComboBox";
}

void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM & cp)
{
	cp.dwFlags &= ~PWS_HSCROLL;
	cp.dwFlags &= ~PWS_VSCROLL;
}

void CPWL_ComboBox::SetFocus()
{
	if (m_pEdit)
		m_pEdit->SetFocus();
}

void CPWL_ComboBox::KillFocus()
{
	SetPopup(FALSE);
	CPWL_Wnd::KillFocus();
}

CFX_WideString CPWL_ComboBox::GetText() const
{
	if (m_pEdit)
	{
		return m_pEdit->GetText();
	}
	return CFX_WideString();
}

void CPWL_ComboBox::SetText(FX_LPCWSTR text)
{
	if (m_pEdit)
		m_pEdit->SetText(text);
}

void CPWL_ComboBox::AddString(FX_LPCWSTR string)
{
	if (m_pList)
		m_pList->AddString(string);
}

FX_INT32 CPWL_ComboBox::GetSelect() const
{
	return m_nSelectItem;
}

void CPWL_ComboBox::SetSelect(FX_INT32 nItemIndex)
{
	if (m_pList)
		m_pList->Select(nItemIndex);

	m_pEdit->SetText(m_pList->GetText().c_str());

	m_nSelectItem = nItemIndex;
}

void CPWL_ComboBox::SetEditSel(FX_INT32 nStartChar,FX_INT32 nEndChar)
{
	if (m_pEdit)
	{
		m_pEdit->SetSel(nStartChar,nEndChar);
	}
}

void CPWL_ComboBox::GetEditSel(FX_INT32 & nStartChar, FX_INT32 & nEndChar) const
{
	nStartChar = -1;
	nEndChar = -1;

	if (m_pEdit)
	{
		m_pEdit->GetSel(nStartChar,nEndChar);
	}
}

void CPWL_ComboBox::Clear()
{
	if (m_pEdit)
	{
		m_pEdit->Clear();
	}
}

void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM & cp)
{
	CreateEdit(cp);
	CreateButton(cp);
	CreateListBox(cp);
}

void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM & cp)
{
	if (!m_pEdit)
	{
		m_pEdit = new CPWL_CBEdit;
		m_pEdit->AttachFFLData(m_pFormFiller);

		PWL_CREATEPARAM ecp = cp;
		ecp.pParentWnd = this;
		ecp.dwFlags =  PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER | PES_AUTOSCROLL | PES_UNDO;

		if (HasFlag(PWS_AUTOFONTSIZE))
			ecp.dwFlags |= PWS_AUTOFONTSIZE;

		if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
			ecp.dwFlags |= PWS_READONLY;

		ecp.rcRectWnd = CPDF_Rect(0,0,0,0);
		ecp.dwBorderWidth = 0;
		ecp.nBorderStyle = PBS_SOLID;

		m_pEdit->Create(ecp);
	}
}

void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM & cp)
{
	if (!m_pButton)
	{
		m_pButton = new CPWL_CBButton;	

		PWL_CREATEPARAM bcp = cp;
		bcp.pParentWnd = this;
		bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;	
		bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
		bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
		bcp.dwBorderWidth = 2;
		bcp.nBorderStyle = PBS_BEVELED;
		bcp.eCursorType = FXCT_ARROW;

		m_pButton->Create(bcp);
	}
}

void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM & cp)
{
	if (!m_pList)
	{
		m_pList = new CPWL_CBListBox;
		m_pList->AttachFFLData(m_pFormFiller);
		PWL_CREATEPARAM lcp = cp;
		lcp.pParentWnd = this;
		lcp.dwFlags = PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
		lcp.nBorderStyle = PBS_SOLID;
		lcp.dwBorderWidth = 1;
		lcp.eCursorType = FXCT_ARROW;
		lcp.rcRectWnd = CPDF_Rect(0,0,0,0);

		if (cp.dwFlags & PWS_AUTOFONTSIZE)
			lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
		else
			lcp.fFontSize = cp.fFontSize;

		if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
			lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;

		if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
			lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;		

		m_pList->Create(lcp);
	}
}

void CPWL_ComboBox::RePosChildWnd()
{
	CPDF_Rect rcClient = GetClientRect();

	if (m_bPopup)
	{
		CPDF_Rect rclient = GetClientRect();
		CPDF_Rect rcButton = rclient;
		CPDF_Rect rcEdit = rcClient;
		CPDF_Rect rcList = CPWL_Wnd::GetWindowRect();

		FX_FLOAT fOldWindowHeight = m_rcOldWindow.Height();
		FX_FLOAT fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
		
		switch (m_nPopupWhere)
		{
		case 0:
			rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;

			if (rcButton.left < rclient.left)
				rcButton.left = rclient.left;
			
			rcButton.bottom = rcButton.top - fOldClientHeight;

			rcEdit.right = rcButton.left - 1.0f;

			if (rcEdit.left < rclient.left)
				rcEdit.left = rclient.left;

			if (rcEdit.right < rcEdit.left)
				rcEdit.right = rcEdit.left;

			rcEdit.bottom = rcEdit.top - fOldClientHeight;

			rcList.top -= fOldWindowHeight;

			break;
		case 1:
			rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;

			if (rcButton.left < rclient.left)
				rcButton.left = rclient.left;
			
			rcButton.top = rcButton.bottom + fOldClientHeight;

			rcEdit.right = rcButton.left - 1.0f;

			if (rcEdit.left < rclient.left)
				rcEdit.left = rclient.left;

			if (rcEdit.right < rcEdit.left)
				rcEdit.right = rcEdit.left;

			rcEdit.top = rcEdit.bottom + fOldClientHeight;

			rcList.bottom += fOldWindowHeight;

			break;
		}		

		if (m_pButton)
			m_pButton->Move(rcButton,TRUE,FALSE);

		if (m_pEdit)
			m_pEdit->Move(rcEdit,TRUE,FALSE);

		if (m_pList)
		{
			m_pList->SetVisible(TRUE);			
			m_pList->Move(rcList,TRUE,FALSE);
			m_pList->ScrollToListItem(m_nSelectItem);
		}
	}
	else
	{		
		CPDF_Rect rcButton = rcClient;

		rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;	
		
		if (rcButton.left < rcClient.left)
			rcButton.left = rcClient.left;

		if (m_pButton)
			m_pButton->Move(rcButton,TRUE,FALSE);

		CPDF_Rect rcEdit = rcClient;
		rcEdit.right = rcButton.left - 1.0f;

		if (rcEdit.left < rcClient.left)
			rcEdit.left = rcClient.left;

		if (rcEdit.right < rcEdit.left)
			rcEdit.right = rcEdit.left;

		if (m_pEdit)
			m_pEdit->Move(rcEdit,TRUE,FALSE);

		if (m_pList)
			m_pList->SetVisible(FALSE);
	}
}

void CPWL_ComboBox::SelectAll()
{
	if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
		m_pEdit->SelectAll();
}

CPDF_Rect CPWL_ComboBox::GetFocusRect() const
{
	return CPDF_Rect();
}

void CPWL_ComboBox::SetPopup(FX_BOOL bPopup)
{
	if (!m_pList) return;
	if (bPopup == m_bPopup) return;
	FX_FLOAT fListHeight = m_pList->GetContentRect().Height();
	if (!IsFloatBigger(fListHeight,0.0f)) return;

	if (bPopup)
	{
		if (m_pFillerNotify)
		{
			FX_INT32 nWhere = 0;
			FX_FLOAT fPopupRet = 0.0f;
			FX_FLOAT fPopupMin = 0.0f;
			if (m_pList->GetCount() > 3)
				fPopupMin = m_pList->GetFirstHeight() * 3 + m_pList->GetBorderWidth() * 2;
			FX_FLOAT fPopupMax = fListHeight + m_pList->GetBorderWidth() * 2;
			m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin,fPopupMax,nWhere,fPopupRet);

			if (IsFloatBigger(fPopupRet,0.0f))
			{
				m_bPopup = bPopup;

				CPDF_Rect rcWindow = CPWL_Wnd::GetWindowRect();
				m_rcOldWindow = rcWindow;
				switch (nWhere)
				{
				default:
				case 0:
					rcWindow.bottom -= fPopupRet;
					break;
				case 1:
					rcWindow.top += fPopupRet;
					break;
				}
				
				m_nPopupWhere = nWhere;
				Move(rcWindow, TRUE, TRUE);
			}
		}
	}
	else
	{
		m_bPopup = bPopup;
		Move(m_rcOldWindow, TRUE, TRUE);
	}
}

FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag)
{
	if (!m_pList) return FALSE;
	if (!m_pEdit) return FALSE;

	m_nSelectItem = -1;

	switch (nChar)
	{
	case FWL_VKEY_Up:
		if (m_pList->GetCurSel() > 0)
		{
			FX_BOOL bExit = FALSE;
			if (m_pList->OnKeyDownWithExit(nChar,bExit,nFlag))
			{
				if (bExit) return FALSE;
				SetSelectText();				
			}
		}
		return TRUE;
	case FWL_VKEY_Down:
		if (m_pList->GetCurSel() < m_pList->GetCount() - 1)
		{
			FX_BOOL bExit = FALSE;
			if (m_pList->OnKeyDownWithExit(nChar,bExit,nFlag))
			{
				if (bExit) return FALSE;
				SetSelectText();				
			}
		}
		return TRUE;
	}

	if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
		return m_pEdit->OnKeyDown(nChar,nFlag);
	else
		return FALSE;
}

FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag)
{
	if (!m_pList) return FALSE;
	if (!m_pEdit) return FALSE;

	m_nSelectItem = -1;
	FX_BOOL bExit = FALSE;

	if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
	{
		return m_pEdit->OnChar(nChar,nFlag);			
	}
	else
	{
		if (m_pList->OnCharWithExit(nChar,bExit,nFlag))
		{
			return bExit;
		}
		else
			return FALSE;
	}
}

void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam)
{
	switch (msg)
	{
	case PNM_LBUTTONDOWN:
		if (pWnd == m_pButton)
		{
			SetPopup(!m_bPopup);
			return;
		}
		break;
	case PNM_LBUTTONUP:
		if (m_pEdit && m_pList)
		{
			if (pWnd == m_pList)
			{			
				SetSelectText();
				SelectAll();
				m_pEdit->SetFocus();
				SetPopup(FALSE);
				return;
			}
		}
	}

	CPWL_Wnd::OnNotify(pWnd,msg,wParam,lParam);
}

FX_BOOL CPWL_ComboBox::IsPopup() const
{
	return m_bPopup;
}

void CPWL_ComboBox::SetSelectText()
{
	CFX_WideString swText = m_pList->GetText();
	m_pEdit->SelectAll();
	m_pEdit->ReplaceSel(m_pList->GetText().c_str());
	m_pEdit->SelectAll();

	m_nSelectItem = m_pList->GetCurSel();
}

FX_BOOL CPWL_ComboBox::IsModified() const
{
	return m_pEdit->IsModified();
}

void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify)
{
	 m_pFillerNotify = pNotify;

	 if (m_pEdit)
		 m_pEdit->SetFillerNotify(pNotify);

	 if (m_pList)
		 m_pList->SetFillerNotify(pNotify);
}

