// 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_ListBox.h"
#include "../../include/pdfwindow/PWL_Utils.h"
#include "../../include/pdfwindow/PWL_ScrollBar.h"
#include "../../include/pdfwindow/PWL_EditCtrl.h"
#include "../../include/pdfwindow/PWL_Edit.h"

#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_List_Notify ----------------------- */

CPWL_List_Notify::CPWL_List_Notify(CPWL_ListBox* pList) : m_pList(pList)
{
	ASSERT(m_pList != NULL);
}

CPWL_List_Notify::~CPWL_List_Notify()
{
}

void CPWL_List_Notify::IOnSetScrollInfoY(FX_FLOAT fPlateMin, FX_FLOAT fPlateMax, 
												FX_FLOAT fContentMin, FX_FLOAT fContentMax, 
												FX_FLOAT fSmallStep, FX_FLOAT fBigStep)
{
	PWL_SCROLL_INFO Info;

	Info.fPlateWidth = fPlateMax - fPlateMin;
	Info.fContentMin = fContentMin;
	Info.fContentMax = fContentMax;
	Info.fSmallStep = fSmallStep;
	Info.fBigStep = fBigStep;

	m_pList->OnNotify(m_pList,PNM_SETSCROLLINFO,SBT_VSCROLL,(FX_INTPTR)&Info);

	if (CPWL_ScrollBar * pScroll = m_pList->GetVScrollBar())
	{
		if (IsFloatBigger(Info.fPlateWidth,Info.fContentMax-Info.fContentMin)
			|| IsFloatEqual(Info.fPlateWidth,Info.fContentMax-Info.fContentMin))
		{
			if (pScroll->IsVisible())
			{
				pScroll->SetVisible(FALSE);
				m_pList->RePosChildWnd();
			}			
		}
		else
		{
			if (!pScroll->IsVisible())
			{
				pScroll->SetVisible(TRUE);	
				m_pList->RePosChildWnd();
			}
		}
	}	
}

void CPWL_List_Notify::IOnSetScrollPosY(FX_FLOAT fy)
{
	m_pList->OnNotify(m_pList,PNM_SETSCROLLPOS,SBT_VSCROLL,(FX_INTPTR)&fy);
}

void CPWL_List_Notify::IOnInvalidateRect(CPDF_Rect * pRect)
{
	m_pList->InvalidateRect(pRect);
}

/* --------------------------- CPWL_ListBox ---------------------------- */

CPWL_ListBox::CPWL_ListBox() :
	m_pList(NULL),
	m_pListNotify(NULL),
	m_bMouseDown(FALSE),
	m_bHoverSel(FALSE),
	m_pFillerNotify(NULL)
{
	m_pList = IFX_List::NewList();

	ASSERT(m_pList != NULL);
}

CPWL_ListBox::~CPWL_ListBox()
{
	IFX_List::DelList(m_pList);
	
	if (m_pListNotify)
	{
		delete m_pListNotify;
		m_pListNotify = NULL;
	}
}

CFX_ByteString CPWL_ListBox::GetClassName() const
{	
	return "CPWL_ListBox";
}

void CPWL_ListBox::OnCreated()
{
	if (m_pList)
	{
		if (m_pListNotify) delete m_pListNotify;

		m_pList->SetFontMap(GetFontMap());
		m_pList->SetNotify(m_pListNotify = new CPWL_List_Notify(this));
	
		SetHoverSel(HasFlag(PLBS_HOVERSEL));	
		m_pList->SetMultipleSel(HasFlag(PLBS_MULTIPLESEL));
		m_pList->SetFontSize(this->GetCreationParam().fFontSize);	

		m_bHoverSel = HasFlag(PLBS_HOVERSEL);
	}
}

void CPWL_ListBox::OnDestroy()
{
	if (m_pListNotify)
	{
		delete m_pListNotify;
		m_pListNotify = NULL;
	}
}

void CPWL_ListBox::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
{
	CPWL_Wnd::GetThisAppearanceStream(sAppStream);

	CFX_ByteTextBuf sListItems;

	if (m_pList)
	{
		CPDF_Rect rcPlate = m_pList->GetPlateRect();
		for (FX_INT32 i=0,sz=m_pList->GetCount(); i<sz; i++)
		{
			CPDF_Rect rcItem = m_pList->GetItemRect(i);

			if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom) continue;
			
			CPDF_Point ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
			if (m_pList->IsItemSelected(i))
			{
				sListItems << CPWL_Utils::GetRectFillAppStream(rcItem,PWL_DEFAULT_SELBACKCOLOR);
				CFX_ByteString sItem = CPWL_Utils::GetEditAppStream(m_pList->GetItemEdit(i), ptOffset);
				if (sItem.GetLength() > 0)
				{
					sListItems << "BT\n" << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELTEXTCOLOR) << sItem << "ET\n";
				}
			}
			else
			{
				CFX_ByteString sItem = CPWL_Utils::GetEditAppStream(m_pList->GetItemEdit(i), ptOffset);
				if (sItem.GetLength() > 0)
				{
					sListItems << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sItem << "ET\n";
				}
			}
		}
	}

	if (sListItems.GetLength() > 0)
	{
		CFX_ByteTextBuf sClip;			
		CPDF_Rect rcClient = this->GetClientRect();

		sClip << "q\n";
		sClip << rcClient.left << " " << rcClient.bottom << " "
			<< rcClient.right - rcClient.left << " " <<	rcClient.top - rcClient.bottom << " re W n\n";

		sClip << sListItems << "Q\n";

		sAppStream << "/Tx BMC\n" << sClip << "EMC\n";
	}
}

void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
{
	CPWL_Wnd::DrawThisAppearance(pDevice,pUser2Device);

	if (m_pList)
	{
		CPDF_Rect rcPlate = m_pList->GetPlateRect();
		CPDF_Rect rcList = GetListRect();
		CPDF_Rect rcClient = GetClientRect();

		for (FX_INT32 i=0,sz=m_pList->GetCount(); i<sz; i++)
		{
			CPDF_Rect rcItem = m_pList->GetItemRect(i);
			if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom) continue;
			
			CPDF_Point ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
			if (IFX_Edit* pEdit = m_pList->GetItemEdit(i))
			{
				CPDF_Rect rcContent = pEdit->GetContentRect();
				if (rcContent.Width() > rcClient.Width())
					rcItem.Intersect(rcList);
				else
					rcItem.Intersect(rcClient);
			}

			if (m_pList->IsItemSelected(i))
			{
			//	CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcItem, ArgbEncode(255,0,51,113));
				IFX_SystemHandler* pSysHandler = GetSystemHandler();
				if(pSysHandler && pSysHandler->IsSelectionImplemented())
				{
					IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), CPWL_Utils::PWLColorToFXColor(GetTextColor()), CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()),
						rcList, ptOffset, NULL,pSysHandler, m_pFormFiller);
					pSysHandler->OutputSelectedRect(m_pFormFiller, rcItem);
				}
				else
				{
					CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcItem, ArgbEncode(255,0,51,113));
					IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), ArgbEncode(255,255,255,255), 0,
						rcList, ptOffset, NULL, pSysHandler, m_pFormFiller);
				}
			}
			else
			{
				IFX_SystemHandler* pSysHandler = GetSystemHandler();
				IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), 
						CPWL_Utils::PWLColorToFXColor(GetTextColor()),
						CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()),
						rcList, ptOffset, NULL,pSysHandler, NULL);

			}
		}
	}
}

FX_BOOL CPWL_ListBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag)
{
	CPWL_Wnd::OnKeyDown(nChar, 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;
	}

	FX_BOOL bExit = FALSE;
	OnNotifySelChanged(TRUE,bExit,nFlag);

	return TRUE;
}

FX_BOOL CPWL_ListBox::OnChar(FX_WORD nChar, FX_DWORD nFlag)
{
	CPWL_Wnd::OnChar(nChar,nFlag);

	if (!m_pList) return FALSE;

	if (!m_pList->OnChar(nChar,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag))) return FALSE;

	FX_BOOL bExit = FALSE;
	OnNotifySelChanged(TRUE,bExit, nFlag);

	return TRUE;
}

FX_BOOL CPWL_ListBox::OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag)
{
	CPWL_Wnd::OnLButtonDown(point,nFlag);

	if (ClientHitTest(point))
	{
		m_bMouseDown = TRUE;
		SetFocus();
		SetCapture();

		if (m_pList)
			m_pList->OnMouseDown(point,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
	}

	return TRUE;
}

FX_BOOL CPWL_ListBox::OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag)
{
	CPWL_Wnd::OnLButtonUp(point,nFlag);

	if (m_bMouseDown)
	{
		ReleaseCapture();
		m_bMouseDown = FALSE;
	}

	FX_BOOL bExit = FALSE;
	OnNotifySelChanged(FALSE,bExit,nFlag);

	return TRUE;
}

void CPWL_ListBox::SetHoverSel(FX_BOOL bHoverSel)
{
	m_bHoverSel = bHoverSel;
}

FX_BOOL CPWL_ListBox::OnMouseMove(const CPDF_Point & point, FX_DWORD nFlag)
{
	CPWL_Wnd::OnMouseMove(point, nFlag);

	if (m_bHoverSel && !IsCaptureMouse() && ClientHitTest(point))
	{
		if (m_pList)
			m_pList->Select(m_pList->GetItemIndex(point));
	}

	if (m_bMouseDown)
	{
		if (m_pList)
			m_pList->OnMouseMove(point,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
	}	

	return TRUE;
}

void CPWL_ListBox::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam)
{
	CPWL_Wnd::OnNotify(pWnd,msg,wParam,lParam);

	FX_FLOAT fPos;	
	
	switch (msg)
	{
	case PNM_SETSCROLLINFO:
		switch (wParam)
		{
		case SBT_VSCROLL:
			if (CPWL_Wnd * pChild = GetVScrollBar())
			{
				pChild->OnNotify(pWnd,PNM_SETSCROLLINFO,wParam,lParam);
			}
			break;
		}
		break;
	case PNM_SETSCROLLPOS:			
		switch (wParam)
		{
		case SBT_VSCROLL:
			if (CPWL_Wnd * pChild = GetVScrollBar())
			{
				pChild->OnNotify(pWnd,PNM_SETSCROLLPOS,wParam,lParam);
			}
			break;
		}
		break;
	case PNM_SCROLLWINDOW:
		fPos = *(FX_FLOAT*)lParam;
		switch (wParam)
		{
		case SBT_VSCROLL:
			if (m_pList)
				m_pList->SetScrollPos(CPDF_Point(0,fPos));
			break;
		}
		break;
	}
}

void CPWL_ListBox::KillFocus()
{
	CPWL_Wnd::KillFocus();

	/*
	if (this->IsMultipleSel())
	{
		for(FX_INT32 i=0;i<this->GetCount();i++)
		{
			if (this->IsListItemSelected(i))
			{
				if (!IsListItemVisible(i))
					this->ScrollToListItem(i);
				break;
			}
		}
	}
	else
	{
		if (!IsListItemVisible(this->GetCurSel()))
			this->ScrollToListItem(this->GetCurSel());
	}

	SetListItemCaret(m_nCaretIndex,FALSE);
	*/
}

void CPWL_ListBox::RePosChildWnd()
{
	CPWL_Wnd::RePosChildWnd();

	if (m_pList)
		m_pList->SetPlateRect(GetListRect());
}

void CPWL_ListBox::OnNotifySelChanged(FX_BOOL bKeyDown, FX_BOOL & bExit,  FX_DWORD nFlag)
{
	if (m_pFillerNotify)
	{		
		FX_BOOL bRC = TRUE;
		CFX_WideString swChange = GetText();
		CFX_WideString strChangeEx;
		int nSelStart = 0;
		int nSelEnd = swChange.GetLength();
		m_pFillerNotify->OnBeforeKeyStroke(FALSE, GetAttachedData(), 0, swChange, strChangeEx, nSelStart, nSelEnd, bKeyDown, bRC, bExit, nFlag);
		if (bExit) return;

		m_pFillerNotify->OnAfterKeyStroke(FALSE, GetAttachedData(), bExit,nFlag);
	}
}

CPDF_Rect CPWL_ListBox::GetFocusRect() const
{
	if (m_pList && m_pList->IsMultipleSel())
	{
		CPDF_Rect rcCaret = m_pList->GetItemRect(m_pList->GetCaret());
		rcCaret.Intersect(GetClientRect());
		return rcCaret;
	}
	
	return CPWL_Wnd::GetFocusRect();
}

void CPWL_ListBox::AddString(FX_LPCWSTR string)
{
	if (m_pList)
	{		
		m_pList->AddString(string);
	}
}

void CPWL_ListBox::SetText(FX_LPCWSTR csText,FX_BOOL bRefresh)
{
	//return CPDF_List::SetText(csText,bRefresh);
}

CFX_WideString CPWL_ListBox::GetText() const
{
	if (m_pList)
		return m_pList->GetText();

	return L"";
}

void CPWL_ListBox::SetFontSize(FX_FLOAT fFontSize)
{
	if (m_pList)
		m_pList->SetFontSize(fFontSize);
}

FX_FLOAT CPWL_ListBox::GetFontSize() const
{
	if (m_pList)
		return m_pList->GetFontSize();
	return 0.0f;
}

void CPWL_ListBox::Select(FX_INT32 nItemIndex)
{
	if (m_pList)
		m_pList->Select(nItemIndex);
}

void CPWL_ListBox::SetCaret(FX_INT32 nItemIndex)
{
	if (m_pList)
		m_pList->SetCaret(nItemIndex);
}

void CPWL_ListBox::SetTopVisibleIndex(FX_INT32 nItemIndex)
{
	if (m_pList)
		m_pList->SetTopItem(nItemIndex);
}

void CPWL_ListBox::ScrollToListItem(FX_INT32 nItemIndex)
{
	if (m_pList)
		m_pList->ScrollToListItem(nItemIndex);
}

void CPWL_ListBox::ResetContent()
{
	if (m_pList)
		m_pList->Empty();
}

void CPWL_ListBox::Reset()
{
	if (m_pList)
		m_pList->Cancel();
}

FX_BOOL CPWL_ListBox::IsMultipleSel() const
{
	if (m_pList)
		return m_pList->IsMultipleSel();

	return FALSE;
}

FX_INT32 CPWL_ListBox::GetCaretIndex() const
{
	if (m_pList)
		return m_pList->GetCaret();

	return -1;
}

FX_INT32 CPWL_ListBox::GetCurSel() const
{
	if (m_pList)
		return m_pList->GetSelect();

	return -1;
}

FX_BOOL CPWL_ListBox::IsItemSelected(FX_INT32 nItemIndex) const
{
	if (m_pList)
		return m_pList->IsItemSelected(nItemIndex);

	return FALSE;
}

FX_INT32 CPWL_ListBox::GetTopVisibleIndex() const
{
	if (m_pList)
	{
		m_pList->ScrollToListItem(m_pList->GetFirstSelected());
		return m_pList->GetTopItem();
	}

	return -1;
}

FX_INT32 CPWL_ListBox::GetCount() const
{
	if (m_pList)
		return m_pList->GetCount();

	return 0;
}

FX_INT32 CPWL_ListBox::FindNext(FX_INT32 nIndex,FX_WCHAR nChar) const
{
	if (m_pList)
		return m_pList->FindNext(nIndex,nChar);

	return nIndex;
}

CPDF_Rect CPWL_ListBox::GetContentRect() const
{
	if (m_pList)
		return m_pList->GetContentRect();

	return CPDF_Rect();
}

FX_FLOAT CPWL_ListBox::GetFirstHeight() const
{
	if (m_pList)
		return m_pList->GetFirstHeight();

	return 0.0f;
}

CPDF_Rect CPWL_ListBox::GetListRect() const
{
	return CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
}

FX_BOOL	CPWL_ListBox::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag)
{
	if (!m_pList) return FALSE;

	if (zDelta < 0)
	{
		m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
	}
	else
	{
		m_pList->OnVK_UP(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
	}

	FX_BOOL bExit = FALSE;
	OnNotifySelChanged(FALSE,bExit, nFlag);
	return TRUE;
}

