/**************************************************************
 *
 * 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_dbui.hxx"

#ifndef DBAUI_WIZ_COLUMNSELECT_HXX
#include "WColumnSelect.hxx"
#endif
#ifndef _DBU_MISC_HRC_
#include "dbu_misc.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef DBAUI_WIZARD_PAGES_HRC
#include "WizardPages.hrc"
#endif
#ifndef DBAUI_WIZ_COPYTABLEDIALOG_HXX
#include "WCopyTable.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XAPPEND_HPP_
#include <com/sun/star/sdbcx/XAppend.hpp>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
#include <com/sun/star/sdbc/DataType.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_APPLICATION_COPYTABLEOPERATION_HPP_
#include <com/sun/star/sdb/application/CopyTableOperation.hpp>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#include <functional>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace dbaui;

namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;

// -----------------------------------------------------------------------
String OWizColumnSelect::GetTitle() const { return String(ModuleRes(STR_WIZ_COLUMN_SELECT_TITEL)); }
// -----------------------------------------------------------------------------
OWizardPage::OWizardPage( Window* pParent, const ResId& rResId )
	: TabPage(pParent,rResId)
	,m_pParent(static_cast<OCopyTableWizard*>(pParent))
	,m_bFirstTime(sal_True)
{
}
//========================================================================
// OWizColumnSelect
DBG_NAME(OWizColumnSelect);
//========================================================================
OWizColumnSelect::OWizColumnSelect( Window* pParent)
    :OWizardPage( pParent, ModuleRes( TAB_WIZ_COLUMN_SELECT ))
    ,m_flColumns( this, ModuleRes( FL_COLUMN_SELECT ) )
    ,m_lbOrgColumnNames( this, ModuleRes( LB_ORG_COLUMN_NAMES ) )
    ,m_ibColumn_RH( this, ModuleRes( IB_COLUMN_RH ) )
    ,m_ibColumns_RH( this, ModuleRes( IB_COLUMNS_RH ) )
    ,m_ibColumn_LH( this, ModuleRes( IB_COLUMN_LH ) )
    ,m_ibColumns_LH( this, ModuleRes( IB_COLUMNS_LH ) )
    ,m_lbNewColumnNames( this, ModuleRes( LB_NEW_COLUMN_NAMES ) )
{
	DBG_CTOR(OWizColumnSelect,NULL);
    m_ibColumn_RH.SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
    m_ibColumn_LH.SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
    m_ibColumns_RH.SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));
    m_ibColumns_LH.SetClickHdl(LINK(this,OWizColumnSelect,ButtonClickHdl));

	m_lbOrgColumnNames.EnableMultiSelection(sal_True);
	m_lbNewColumnNames.EnableMultiSelection(sal_True);

	m_lbOrgColumnNames.SetDoubleClickHdl(LINK(this,OWizColumnSelect,ListDoubleClickHdl));
	m_lbNewColumnNames.SetDoubleClickHdl(LINK(this,OWizColumnSelect,ListDoubleClickHdl));
	FreeResource();
}
// -----------------------------------------------------------------------
OWizColumnSelect::~OWizColumnSelect()
{
	DBG_DTOR(OWizColumnSelect,NULL);
	while ( m_lbNewColumnNames.GetEntryCount() )
	{
		void* pData = m_lbNewColumnNames.GetEntryData(0);
		if ( pData )
			delete static_cast<OFieldDescription*>(pData);

		m_lbNewColumnNames.RemoveEntry(0);
	}
	m_lbNewColumnNames.Clear();
}

// -----------------------------------------------------------------------
void OWizColumnSelect::Reset()
{
	// urspr"unglichen zustand wiederherstellen
	DBG_CHKTHIS(OWizColumnSelect,NULL);

	clearListBox(m_lbOrgColumnNames);
	clearListBox(m_lbNewColumnNames);
    m_pParent->m_mNameMapping.clear();

	// insert the source columns in the left listbox
	const ODatabaseExport::TColumnVector* pSrcColumns = m_pParent->getSrcVector();
	ODatabaseExport::TColumnVector::const_iterator aIter = pSrcColumns->begin();
    ODatabaseExport::TColumnVector::const_iterator aEnd = pSrcColumns->end();

	for(;aIter != aEnd;++aIter)
	{
		sal_uInt16 nPos = m_lbOrgColumnNames.InsertEntry((*aIter)->first);
		m_lbOrgColumnNames.SetEntryData(nPos,(*aIter)->second);
	}

	// m_pParent->clearDestColumns();

	if(m_lbOrgColumnNames.GetEntryCount())
		m_lbOrgColumnNames.SelectEntryPos(0);

	m_bFirstTime = sal_False;
}
// -----------------------------------------------------------------------
void OWizColumnSelect::ActivatePage( )
{
	DBG_CHKTHIS(OWizColumnSelect,NULL);
	// if there are no dest columns reset the left side with the origibnal columns
	if(m_pParent->getDestColumns()->size() == 0)
		Reset();

	clearListBox(m_lbNewColumnNames);

	const ODatabaseExport::TColumnVector* pDestColumns = m_pParent->getDestVector();

	ODatabaseExport::TColumnVector::const_iterator aIter = pDestColumns->begin();
    ODatabaseExport::TColumnVector::const_iterator aEnd = pDestColumns->end();
	for(;aIter != aEnd;++aIter)
	{
		sal_uInt16 nPos = m_lbNewColumnNames.InsertEntry((*aIter)->first);
		m_lbNewColumnNames.SetEntryData(nPos,new OFieldDescription(*((*aIter)->second)));
		m_lbOrgColumnNames.RemoveEntry((*aIter)->first);
	}
	m_pParent->GetOKButton().Enable(m_lbNewColumnNames.GetEntryCount() != 0);
	m_pParent->EnableButton(OCopyTableWizard::WIZARD_NEXT,m_lbNewColumnNames.GetEntryCount() && m_pParent->getOperation() != CopyTableOperation::AppendData);
	m_ibColumns_RH.GrabFocus();
}
// -----------------------------------------------------------------------
sal_Bool OWizColumnSelect::LeavePage()
{
	DBG_CHKTHIS(OWizColumnSelect,NULL);

	//	m_pParent->getColumns()->clear();
	m_pParent->clearDestColumns();

	for(sal_uInt16 i=0 ; i< m_lbNewColumnNames.GetEntryCount();++i)
	{
		OFieldDescription* pField = static_cast<OFieldDescription*>(m_lbNewColumnNames.GetEntryData(i));
		OSL_ENSURE(pField,"The field information can not be null!");
		m_pParent->insertColumn(i,pField);
	}

	clearListBox(m_lbNewColumnNames);


	if  (   m_pParent->GetPressedButton() == OCopyTableWizard::WIZARD_NEXT
        ||  m_pParent->GetPressedButton() == OCopyTableWizard::WIZARD_FINISH
        )
		return m_pParent->getDestColumns()->size() != 0;
	else
		return sal_True;
}
// -----------------------------------------------------------------------
IMPL_LINK( OWizColumnSelect, ButtonClickHdl, Button *, pButton )
{
	MultiListBox *pLeft = NULL;
	MultiListBox *pRight = NULL;
	sal_Bool bAll = sal_False;

    if(pButton == &m_ibColumn_RH)
	{
		pLeft  = &m_lbOrgColumnNames;
		pRight = &m_lbNewColumnNames;
	}
    else if(pButton == &m_ibColumn_LH)
	{
		pLeft  = &m_lbNewColumnNames;
		pRight = &m_lbOrgColumnNames;
	}
    else if(pButton == &m_ibColumns_RH)
	{
		pLeft  = &m_lbOrgColumnNames;
		pRight = &m_lbNewColumnNames;
		bAll   = sal_True;
	}
    else if(pButton == &m_ibColumns_LH)
	{
		pLeft  = &m_lbNewColumnNames;
		pRight = &m_lbOrgColumnNames;
		bAll   = sal_True;
	}
	// else ????

	Reference< XDatabaseMetaData > xMetaData( m_pParent->m_xDestConnection->getMetaData() );
	::rtl::OUString sExtraChars = xMetaData->getExtraNameCharacters();
	sal_Int32 nMaxNameLen		= m_pParent->getMaxColumnNameLength();

	::comphelper::TStringMixEqualFunctor aCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
	::std::vector< ::rtl::OUString> aRightColumns;
	fillColumns(pRight,aRightColumns);

	String aColumnName;
	if(!bAll)
	{
		for(sal_uInt16 i=0; i < pLeft->GetSelectEntryCount(); ++i)
			moveColumn(pRight,pLeft,aRightColumns,pLeft->GetSelectEntry(i),sExtraChars,nMaxNameLen,aCase);

		for(sal_uInt16 j=pLeft->GetSelectEntryCount(); j ; --j)
			pLeft->RemoveEntry(pLeft->GetSelectEntry(j-1));
	}
	else
	{
		sal_uInt16 nEntries = pLeft->GetEntryCount();
		for(sal_uInt16 i=0; i < nEntries; ++i)
			moveColumn(pRight,pLeft,aRightColumns,pLeft->GetEntry(i),sExtraChars,nMaxNameLen,aCase);
		for(sal_uInt16 j=pLeft->GetEntryCount(); j ; --j)
			pLeft->RemoveEntry(j-1);
	}

	enableButtons();

	if(m_lbOrgColumnNames.GetEntryCount())
		m_lbOrgColumnNames.SelectEntryPos(0);

	return 0;
}
// -----------------------------------------------------------------------
IMPL_LINK( OWizColumnSelect, ListDoubleClickHdl, MultiListBox *, pListBox )
{
	MultiListBox *pLeft,*pRight;
	if(pListBox == &m_lbOrgColumnNames)
	{
		pLeft  = &m_lbOrgColumnNames;
		pRight = &m_lbNewColumnNames;
	}
	else
	{
		pRight = &m_lbOrgColumnNames;
		pLeft  = &m_lbNewColumnNames;
	}

	//////////////////////////////////////////////////////////////////////
	// Wenn Datenbank PrimaryKeys verarbeiten kann, PrimaryKey anlegen
	Reference< XDatabaseMetaData >  xMetaData( m_pParent->m_xDestConnection->getMetaData() );
	::rtl::OUString sExtraChars = xMetaData->getExtraNameCharacters();
	sal_Int32 nMaxNameLen		= m_pParent->getMaxColumnNameLength();

	::comphelper::TStringMixEqualFunctor aCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
	::std::vector< ::rtl::OUString> aRightColumns;
	fillColumns(pRight,aRightColumns);

	String aColumnName;
	for(sal_uInt16 i=0; i < pLeft->GetSelectEntryCount(); ++i)
		moveColumn(pRight,pLeft,aRightColumns,pLeft->GetSelectEntry(i),sExtraChars,nMaxNameLen,aCase);
	for(sal_uInt16 j=pLeft->GetSelectEntryCount(); j ; --j)
		pLeft->RemoveEntry(pLeft->GetSelectEntry(j-1));

	enableButtons();
	return 0;
}
// -----------------------------------------------------------------------------
void OWizColumnSelect::clearListBox(MultiListBox& _rListBox)
{
	while(_rListBox.GetEntryCount())
		_rListBox.RemoveEntry(0);
	_rListBox.Clear();
}
// -----------------------------------------------------------------------------
void OWizColumnSelect::fillColumns(ListBox* pRight,::std::vector< ::rtl::OUString> &_rRightColumns)
{
	sal_uInt16 nCount = pRight->GetEntryCount();
	_rRightColumns.reserve(nCount);
	for(sal_uInt16 i=0; i < nCount;++i)
		_rRightColumns.push_back(pRight->GetEntry(i));
}
// -----------------------------------------------------------------------------
void OWizColumnSelect::createNewColumn(	ListBox* _pListbox,
										OFieldDescription* _pSrcField,
										::std::vector< ::rtl::OUString>& _rRightColumns,
										const ::rtl::OUString&	_sColumnName,
										const ::rtl::OUString&	_sExtraChars,
										sal_Int32				_nMaxNameLen,
										const ::comphelper::TStringMixEqualFunctor& _aCase)
{
	::rtl::OUString sConvertedName = m_pParent->convertColumnName(TMultiListBoxEntryFindFunctor(&_rRightColumns,_aCase),
																_sColumnName,
																_sExtraChars,
																_nMaxNameLen);
	OFieldDescription* pNewField = new OFieldDescription(*_pSrcField);
	pNewField->SetName(sConvertedName);
	sal_Bool bNotConvert = sal_True;
	pNewField->SetType(m_pParent->convertType(_pSrcField->getSpecialTypeInfo(),bNotConvert));
	if ( !m_pParent->supportsPrimaryKey() )
		pNewField->SetPrimaryKey(sal_False);

	_pListbox->SetEntryData(_pListbox->InsertEntry(sConvertedName),pNewField);
	_rRightColumns.push_back(sConvertedName);

	if ( !bNotConvert )
		m_pParent->showColumnTypeNotSupported(sConvertedName);
}
// -----------------------------------------------------------------------------
void OWizColumnSelect::moveColumn(	ListBox* _pRight,
									ListBox* _pLeft,
									::std::vector< ::rtl::OUString>& _rRightColumns,
									const ::rtl::OUString&	_sColumnName,
									const ::rtl::OUString&	_sExtraChars,
									sal_Int32				_nMaxNameLen,
									const ::comphelper::TStringMixEqualFunctor& _aCase)
{
	if(_pRight == &m_lbNewColumnNames)
	{
		// we copy the column into the new format for the dest
		OFieldDescription* pSrcField = static_cast<OFieldDescription*>(_pLeft->GetEntryData(_pLeft->GetEntryPos(String(_sColumnName))));
		createNewColumn(_pRight,pSrcField,_rRightColumns,_sColumnName,_sExtraChars,_nMaxNameLen,_aCase);
	}
	else
	{
		// find the new column in the dest name mapping to obtain the old column
		OCopyTableWizard::TNameMapping::iterator aIter = ::std::find_if(m_pParent->m_mNameMapping.begin(),m_pParent->m_mNameMapping.end(),
																::std::compose1(
																	::std::bind2nd(_aCase, _sColumnName),
																	::std::select2nd<OCopyTableWizard::TNameMapping::value_type>())
																	);

		DBG_ASSERT(aIter != m_pParent->m_mNameMapping.end(),"Column must be defined");
        if ( aIter == m_pParent->m_mNameMapping.end() )
            return; // do nothing
		const ODatabaseExport::TColumns* pSrcColumns = m_pParent->getSourceColumns();
		ODatabaseExport::TColumns::const_iterator aSrcIter = pSrcColumns->find((*aIter).first);
		if ( aSrcIter != pSrcColumns->end() )
		{
			// we need also the old position of this column to insert it back on that position again
			const ODatabaseExport::TColumnVector* pSrcVector = m_pParent->getSrcVector();
			ODatabaseExport::TColumnVector::const_iterator aPos = ::std::find(pSrcVector->begin(),pSrcVector->end(),aSrcIter);
			OSL_ENSURE( aPos != pSrcVector->end(),"Invalid position for the iterator here!");
			ODatabaseExport::TColumnVector::size_type nPos = (aPos - pSrcVector->begin()) - adjustColumnPosition(_pLeft, _sColumnName, (aPos - pSrcVector->begin()), _aCase);

			_pRight->SetEntryData( _pRight->InsertEntry( (*aIter).first, sal::static_int_cast< sal_uInt16 >(nPos)),aSrcIter->second );
			_rRightColumns.push_back((*aIter).first);
            m_pParent->removeColumnNameFromNameMap(_sColumnName);
		}
	}
}
// -----------------------------------------------------------------------------
// Simply returning fields back to their original position is
// not enough. We need to take into account what fields have
// been removed earlier and adjust accordingly. Based on the
// algorithm employed in moveColumn().
sal_uInt16 OWizColumnSelect::adjustColumnPosition( ListBox* _pLeft,
                                               const ::rtl::OUString&	_sColumnName,
                                               ODatabaseExport::TColumnVector::size_type nCurrentPos,
                                               const ::comphelper::TStringMixEqualFunctor& _aCase)
{
    sal_uInt16 nAdjustedPos = 0;

    // if returning all entries to their original position,
    // then there is no need to adjust the positions.
    if (m_ibColumns_LH.HasFocus())
        return nAdjustedPos;

    sal_uInt16 nCount = _pLeft->GetEntryCount();
    ::rtl::OUString sColumnString;
    for(sal_uInt16 i=0; i < nCount; ++i)
    {
        sColumnString = _pLeft->GetEntry(i);
        if(_sColumnName != sColumnString)
        {
            // find the new column in the dest name mapping to obtain the old column
            OCopyTableWizard::TNameMapping::iterator aIter = ::std::find_if(m_pParent->m_mNameMapping.begin(),m_pParent->m_mNameMapping.end(),
                                                                    ::std::compose1(
                                                                    ::std::bind2nd(_aCase, sColumnString),
                                                                    ::std::select2nd<OCopyTableWizard::TNameMapping::value_type>())
                                                                    );

            DBG_ASSERT(aIter != m_pParent->m_mNameMapping.end(),"Column must be defined");
            const ODatabaseExport::TColumns* pSrcColumns = m_pParent->getSourceColumns();
            ODatabaseExport::TColumns::const_iterator aSrcIter = pSrcColumns->find((*aIter).first);
            if ( aSrcIter != pSrcColumns->end() )
            {
                // we need also the old position of this column to insert it back on that position again
                const ODatabaseExport::TColumnVector* pSrcVector = m_pParent->getSrcVector();
                ODatabaseExport::TColumnVector::const_iterator aPos = ::std::find(pSrcVector->begin(),pSrcVector->end(),aSrcIter);
                ODatabaseExport::TColumnVector::size_type nPos = aPos - pSrcVector->begin();
                if( nPos < nCurrentPos)
                {
                    nAdjustedPos++;
                }
            }
        }
    }

    return nAdjustedPos;
}
// -----------------------------------------------------------------------------
void OWizColumnSelect::enableButtons()
{
	sal_Bool bEntries = m_lbNewColumnNames.GetEntryCount() != 0;
	if(!bEntries)
		m_pParent->m_mNameMapping.clear();

	m_pParent->GetOKButton().Enable(bEntries);
	m_pParent->EnableButton(OCopyTableWizard::WIZARD_NEXT,bEntries && m_pParent->getOperation() != CopyTableOperation::AppendData);
}
// -----------------------------------------------------------------------------
