// 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::OnKeyDown(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::OnChar(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());

	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->OnKeyDown(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->OnKeyDown(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->OnChar(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());
	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);
}

