/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#include "selectlabeldialog.hxx"
#ifndef _EXTENSIONS_PROPCTRLR_FORMRESID_HRC_
#include "formresid.hrc"
#endif
#include "formbrowsertools.hxx"
#include "formstrings.hxx"
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/sdbc/XResultSet.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <comphelper/property.hxx>
#include <comphelper/types.hxx>

//............................................................................
namespace pcr
{
//............................................................................

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::form;
	using namespace ::com::sun::star::sdbc;
	using namespace ::com::sun::star::lang;

	//========================================================================
	// OSelectLabelDialog
	//========================================================================
	DBG_NAME(OSelectLabelDialog)
	//------------------------------------------------------------------------
	OSelectLabelDialog::OSelectLabelDialog( Window* pParent, Reference< XPropertySet >  _xControlModel )
		:ModalDialog(pParent, PcrRes(RID_DLG_SELECTLABELCONTROL))
		,m_aMainDesc(this, PcrRes(1))
		,m_aControlTree(this, PcrRes(1))
		,m_aNoAssignment(this, PcrRes(1))
		,m_aSeparator(this, PcrRes(1))
		,m_aOk(this, PcrRes(1))
		,m_aCancel(this, PcrRes(1))
		,m_aModelImages(PcrRes(RID_IL_FORMEXPLORER))
		,m_xControlModel(_xControlModel)
		,m_pInitialSelection(NULL)
		,m_pLastSelected(NULL)
		,m_bHaveAssignableControl(sal_False)
	{
		DBG_CTOR(OSelectLabelDialog,NULL);

		// initialize the TreeListBox
		m_aControlTree.SetSelectionMode( SINGLE_SELECTION );
		m_aControlTree.SetDragDropMode( 0 );
		m_aControlTree.EnableInplaceEditing( sal_False );
		m_aControlTree.SetStyle(m_aControlTree.GetStyle() | WB_BORDER | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL);

		m_aControlTree.SetNodeBitmaps( m_aModelImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ), m_aModelImages.GetImage( RID_SVXIMG_EXPANDEDNODE ) );
		m_aControlTree.SetSelectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected));
		m_aControlTree.SetDeselectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected));

		// fill the description
		UniString sDescription = m_aMainDesc.GetText();
		sal_Int16 nClassID = FormComponentType::CONTROL;
		if (::comphelper::hasProperty(PROPERTY_CLASSID, m_xControlModel))
			nClassID = ::comphelper::getINT16(m_xControlModel->getPropertyValue(PROPERTY_CLASSID));

		sDescription.SearchAndReplace(String::CreateFromAscii("$control_class$"), GetUIHeadlineName(nClassID, makeAny(m_xControlModel)));
		UniString sName = ::comphelper::getString(m_xControlModel->getPropertyValue(PROPERTY_NAME)).getStr();
		sDescription.SearchAndReplace(String::CreateFromAscii("$control_name$"), sName);
		m_aMainDesc.SetText(sDescription);

		// search for the root of the form hierarchy
		Reference< XChild >  xCont(m_xControlModel, UNO_QUERY);
		Reference< XInterface >  xSearch( xCont.is() ? xCont->getParent() : Reference< XInterface > ());
		Reference< XResultSet >  xParentAsResultSet(xSearch, UNO_QUERY);
		while (xParentAsResultSet.is())
		{
			xCont = Reference< XChild > (xSearch, UNO_QUERY);
			xSearch = xCont.is() ? xCont->getParent() : Reference< XInterface > ();
			xParentAsResultSet = Reference< XResultSet > (xSearch, UNO_QUERY);
		}

		// and insert all entries below this root into the listbox
		if (xSearch.is())
		{
			// check which service the allowed components must suppport
			sal_Int16 nClassId = 0;
			try { nClassId = ::comphelper::getINT16(m_xControlModel->getPropertyValue(PROPERTY_CLASSID)); } catch(...) { }
			m_sRequiredService = (FormComponentType::RADIOBUTTON == nClassId) ? SERVICE_COMPONENT_GROUPBOX : SERVICE_COMPONENT_FIXEDTEXT;
			m_aRequiredControlImage = m_aModelImages.GetImage((FormComponentType::RADIOBUTTON == nClassId) ? RID_SVXIMG_GROUPBOX : RID_SVXIMG_FIXEDTEXT);

			// calc the currently set label control (so InsertEntries can calc m_pInitialSelection)
			Any aCurrentLabelControl( m_xControlModel->getPropertyValue(PROPERTY_CONTROLLABEL) );
			DBG_ASSERT((aCurrentLabelControl.getValueTypeClass() == TypeClass_INTERFACE) || !aCurrentLabelControl.hasValue(),

				"OSelectLabelDialog::OSelectLabelDialog : invalid ControlLabel property !");
			if (aCurrentLabelControl.hasValue())
				aCurrentLabelControl >>= m_xInitialLabelControl;

			// insert the root
			Image aRootImage = m_aModelImages.GetImage(RID_SVXIMG_FORMS);
			SvLBoxEntry* pRoot = m_aControlTree.InsertEntry(PcrRes(RID_STR_FORMS), aRootImage, aRootImage);

			// build the tree
			m_pInitialSelection = NULL;
			m_bHaveAssignableControl = sal_False;
			InsertEntries(xSearch, pRoot);
			m_aControlTree.Expand(pRoot);
		}

		if (m_pInitialSelection)
		{
			m_aControlTree.MakeVisible(m_pInitialSelection, sal_True);
			m_aControlTree.Select(m_pInitialSelection, sal_True);
		}
		else
		{
			m_aControlTree.MakeVisible(m_aControlTree.First(), sal_True);
			if (m_aControlTree.FirstSelected())
				m_aControlTree.Select(m_aControlTree.FirstSelected(), sal_False);
			m_aNoAssignment.Check(sal_True);
		}

		if (!m_bHaveAssignableControl)
		{	// no controls which can be assigned
			m_aNoAssignment.Check(sal_True);
			m_aNoAssignment.Enable(sal_False);
		}

		m_aNoAssignment.SetClickHdl(LINK(this, OSelectLabelDialog, OnNoAssignmentClicked));
		m_aNoAssignment.GetClickHdl().Call(&m_aNoAssignment);

		FreeResource();
	}

	//------------------------------------------------------------------------
	OSelectLabelDialog::~OSelectLabelDialog()
	{
		// delete the entry datas of the listbox entries
		SvLBoxEntry* pLoop = m_aControlTree.First();
		while (pLoop)
		{
			void* pData = pLoop->GetUserData();
			if (pData)
				delete (Reference< XPropertySet > *)pData;
			pLoop = m_aControlTree.Next(pLoop);
		}

		DBG_DTOR(OSelectLabelDialog,NULL);
	}

	//------------------------------------------------------------------------
	sal_Int32 OSelectLabelDialog::InsertEntries(const Reference< XInterface > & _xContainer, SvLBoxEntry* pContainerEntry)
	{
		Reference< XIndexAccess >  xContainer(_xContainer, UNO_QUERY);
		if (!xContainer.is())
			return 0;

		sal_Int32 nChildren = 0;
		UniString sName,sDisplayName;
		Reference< XPropertySet >  xAsSet;
		for (sal_Int32 i=0; i<xContainer->getCount(); ++i)
		{
			xContainer->getByIndex(i) >>= xAsSet;
			if (!xAsSet.is())
			{
				DBG_WARNING("OSelectLabelDialog::InsertEntries : strange : a form component which isn't a property set !");
				continue;
			}

			if (!::comphelper::hasProperty(PROPERTY_NAME, xAsSet))
				// we need at least a name for displaying ...
				continue;
			sName = ::comphelper::getString(xAsSet->getPropertyValue(PROPERTY_NAME)).getStr();

			// we need to check if the control model supports the required service
			Reference< XServiceInfo >  xInfo(xAsSet, UNO_QUERY);
			if (!xInfo.is())
				continue;

			if (!xInfo->supportsService(m_sRequiredService))
			{	// perhaps it is a container
				Reference< XIndexAccess >  xCont(xAsSet, UNO_QUERY);
				if (xCont.is() && xCont->getCount())
				{	// yes -> step down
					Image aFormImage = m_aModelImages.GetImage( RID_SVXIMG_FORM );
					SvLBoxEntry* pCont = m_aControlTree.InsertEntry(sName, aFormImage, aFormImage, pContainerEntry);
					sal_Int32 nContChildren = InsertEntries(xCont, pCont);
					if (nContChildren)
					{
						m_aControlTree.Expand(pCont);
						++nChildren;
					}
					else
					{	// oops, no valid childs -> remove the entry
						m_aControlTree.ModelIsRemoving(pCont);
						m_aControlTree.GetModel()->Remove(pCont);
						m_aControlTree.ModelHasRemoved(pCont);
					}
				}
				continue;
			}

			// get the label
			if (!::comphelper::hasProperty(PROPERTY_LABEL, xAsSet))
				continue;
			sDisplayName = ::comphelper::getString(xAsSet->getPropertyValue(PROPERTY_LABEL)).getStr();
			sDisplayName += String::CreateFromAscii(" (");
			sDisplayName += sName;
			sDisplayName += ')';

			// all requirements met -> insert
			SvLBoxEntry* pCurrent = m_aControlTree.InsertEntry(sDisplayName, m_aRequiredControlImage, m_aRequiredControlImage, pContainerEntry);
			pCurrent->SetUserData(new Reference< XPropertySet > (xAsSet));
			++nChildren;

			if (m_xInitialLabelControl == xAsSet)
				m_pInitialSelection = pCurrent;

			m_bHaveAssignableControl = sal_True;
		}

		return nChildren;
	}

	//------------------------------------------------------------------------
	IMPL_LINK(OSelectLabelDialog, OnEntrySelected, SvTreeListBox*, pLB)
	{
		DBG_ASSERT(pLB == &m_aControlTree, "OSelectLabelDialog::OnEntrySelected : where did this come from ?");
        (void)pLB;
		SvLBoxEntry* pSelected = m_aControlTree.FirstSelected();
		void* pData = pSelected ? pSelected->GetUserData() : NULL;

		if (pData)
			m_xSelectedControl = Reference< XPropertySet > (*(Reference< XPropertySet > *)pData);

		m_aNoAssignment.SetClickHdl(Link());
		m_aNoAssignment.Check(pData == NULL);
		m_aNoAssignment.SetClickHdl(LINK(this, OSelectLabelDialog, OnNoAssignmentClicked));

		return 0L;
	}

	//------------------------------------------------------------------------
	IMPL_LINK(OSelectLabelDialog, OnNoAssignmentClicked, Button*, pButton)
	{
		DBG_ASSERT(pButton == &m_aNoAssignment, "OSelectLabelDialog::OnNoAssignmentClicked : where did this come from ?");
        (void)pButton;

		if (m_aNoAssignment.IsChecked())
			m_pLastSelected = m_aControlTree.FirstSelected();
		else
		{
			DBG_ASSERT(m_bHaveAssignableControl, "OSelectLabelDialog::OnNoAssignmentClicked");
			// search the first assignable entry
			SvLBoxEntry* pSearch = m_aControlTree.First();
			while (pSearch)
			{
				if (pSearch->GetUserData())
					break;
				pSearch = m_aControlTree.Next(pSearch);
			}
			// and select it
			if (pSearch)
			{
				m_aControlTree.Select(pSearch);
				m_pLastSelected = pSearch;
			}
		}

		if (m_pLastSelected)
		{
			m_aControlTree.SetSelectHdl(Link());
			m_aControlTree.SetDeselectHdl(Link());
			m_aControlTree.Select(m_pLastSelected, !m_aNoAssignment.IsChecked());
			m_aControlTree.SetSelectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected));
			m_aControlTree.SetDeselectHdl(LINK(this, OSelectLabelDialog, OnEntrySelected));
		}

		return 0L;
	}

//............................................................................
}	// namespace pcr
//............................................................................
