// 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/formfiller/FormFiller.h"
#include "../../include/formfiller/FFL_FormFiller.h"
#include "../../include/formfiller/FFL_ListBox.h"
//#include "../../include/formfiller/FFL_Module.h"
#include "../../include/formfiller/FFL_IFormFiller.h"
//#include "../../include/formfiller/FFL_Undo.h"
#include "../../include/formfiller/FFL_CBA_Fontmap.h"


#define	FFL_DEFAULTLISTBOXFONTSIZE		12.0f


/* ------------------------------- CFFL_ListBox ------------------------------- */

CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
	CFFL_FormFiller(pApp, pWidget),
	m_pFontMap(NULL)
{
}

CFFL_ListBox::~CFFL_ListBox()
{
	if (m_pFontMap)
	{
		delete m_pFontMap;
		m_pFontMap = NULL;
	}
}

PWL_CREATEPARAM	CFFL_ListBox::GetCreateParam()
{
	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();

	ASSERT(m_pWidget != NULL);
	FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
		
	if (dwFieldFlag & FIELDFLAG_MULTISELECT)
	{		
		cp.dwFlags |= PLBS_MULTIPLESEL;
	}

	if (dwFieldFlag & FIELDFLAG_COMMITONSELCHANGE)
	{
		//cp.dwFlags |= PLBS_COMMITSELECTEDVALUE;
	}

	cp.dwFlags |= PWS_VSCROLL;

	if (cp.dwFlags & PWS_AUTOFONTSIZE)
		cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;

	if (!m_pFontMap)
	{
		ASSERT(this->m_pApp != NULL);
		m_pFontMap = new CBA_FontMap(m_pWidget,m_pApp->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pApp));
		m_pFontMap->Initial();
	}
	cp.pFontMap = m_pFontMap;

	return cp;
}

CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
{
	CPWL_ListBox* pWnd = new CPWL_ListBox();
	pWnd->AttachFFLData(this);
	pWnd->Create(cp);

	ASSERT(m_pApp != NULL);
	CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
	pWnd->SetFillerNotify(pIFormFiller);

	ASSERT(m_pWidget != NULL);
	
	for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
		pWnd->AddString(m_pWidget->GetOptionLabel(i));
	
	if (pWnd->HasFlag(PLBS_MULTIPLESEL))
	{
		m_OriginSelections.RemoveAll();
		
		FX_BOOL bSetCaret = FALSE;
		for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
		{
			if (m_pWidget->IsOptionSelected(i))
			{
				if (!bSetCaret)
				{
					pWnd->SetCaret(i);
					bSetCaret = TRUE;
				}
				pWnd->Select(i);
				m_OriginSelections.SetAt(i, NULL);
			}
		}
	}
	else
	{
		for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
		{
			if (m_pWidget->IsOptionSelected(i))
			{
				pWnd->Select(i);
				break;
			}
		}
	}
	
	pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
	
	return pWnd;
}


FX_BOOL	CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
{
	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
}

FX_BOOL	CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView)
{
	ASSERT(m_pWidget != NULL);

	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
	{
		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
		{
			int nSelCount = 0;
			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
			{
				if (pListBox->IsItemSelected(i))
				{
					void* p = NULL;
					if (!m_OriginSelections.Lookup(i, p))
						return TRUE;

					nSelCount++;
				}
			}

			return nSelCount != m_OriginSelections.GetCount();
		}
		else
		{
			return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
		}
	}
	
	return FALSE;
}

void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView)
{
	ASSERT(m_pWidget != NULL);

	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
	{
		CFX_IntArray aOldSelect, aNewSelect;

		{
			for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
			{
				if (m_pWidget->IsOptionSelected(i))
				{
					aOldSelect.Add(i);
				}
			}
		}

		
		FX_INT32 nNewTopIndex = pListBox->GetTopVisibleIndex();

		m_pWidget->ClearSelection(FALSE);	

		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
		{
			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
			{
				if (pListBox->IsItemSelected(i))
				{
					m_pWidget->SetOptionSelection(i, TRUE, FALSE);
					aNewSelect.Add(i);
				}
			}
		}
		else
		{
			m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
			aNewSelect.Add(pListBox->GetCurSel());
		}

		m_pWidget->SetTopVisibleIndex(nNewTopIndex);
		m_pWidget->ResetFieldAppearance(TRUE);
		m_pWidget->UpdateField();
		SetChangeMark();
	}
}

void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
						PDFSDK_FieldAction& fa)
{
	switch (type)
	{
	case CPDF_AAction::Validate:
		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
		{
			fa.sValue = L"";
		}
		else
		{
			if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
			{
				ASSERT(m_pWidget != NULL);
				FX_INT32 nCurSel = pListBox->GetCurSel();
				if (nCurSel >= 0)
					fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
			}
		}
		break;
	case CPDF_AAction::LoseFocus:
	case CPDF_AAction::GetFocus:
		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
		{
			fa.sValue = L"";
		}
		else
		{
			ASSERT(m_pWidget != NULL);
			FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
			if (nCurSel >= 0)
				fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
		}
		break;
	default:
		break;
	}
}


void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
								const PDFSDK_FieldAction& fa)
{
}

void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView)
{
	ASSERT(pPageView != NULL);

	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
	{
		for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
		{
			if (pListBox->IsItemSelected(i))
			{
				m_State.Add(i);
			}
		}
	}
}

void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView)
{
	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
	{
		for (int i=0,sz=m_State.GetSize(); i<sz; i++)
			pListBox->Select(m_State[i]);
	}
}

CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
{
	if (bRestoreValue)
		SaveState(pPageView);
	
	DestroyPDFWindow(pPageView);
	
	CPWL_Wnd* pRet = NULL;
	
	if (bRestoreValue)
	{
		RestoreState(pPageView);
		pRet = this->GetPDFWindow(pPageView, FALSE);
	}
	else
		pRet = this->GetPDFWindow(pPageView, TRUE);
	
	m_pWidget->UpdateField();
	
	return pRet;
}

void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag)
{
	ASSERT(m_pWidget != NULL);

	int nFlags = m_pWidget->GetFieldFlags();
	
	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
	{
		if (m_bValid)
		{
			CPDFSDK_PageView* pPageView = this->GetCurPageView();
			ASSERT(pPageView != NULL);

			if (CommitData(pPageView, nFlag))
			{
				DestroyPDFWindow(pPageView);
				m_bValid = FALSE;
			}
		}
	}
}

