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

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------
#include "filepickerstate.hxx"
#include <osl/diagnose.h>
#include "controlaccess.hxx"
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/ListBoxControlActions.hpp>
#include <com/sun/star/ui/dialogs/ControlActions.hpp>
#include "controlcommandrequest.hxx"
#include "controlcommandresult.hxx"
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <osl/file.hxx>
#include "FileOpenDlg.hxx"

#include <memory>
#include "..\misc\WinImplHelper.hxx"
//---------------------------------------------
//
//---------------------------------------------

using rtl::OUString;
using com::sun::star::uno::Any;
using com::sun::star::uno::Sequence;
using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;

using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
using namespace ::com::sun::star::ui::dialogs::ListboxControlActions;

//---------------------------------------------
//
//---------------------------------------------

const sal_Int32 MAX_LABEL = 256;
const sal_Int16 LISTBOX_LABEL_OFFSET = 100;

//---------------------------------------------
// declaration
//---------------------------------------------

CFilePickerState::~CFilePickerState( )
{
}

//---------------------------------------------
//
//---------------------------------------------

CNonExecuteFilePickerState::CNonExecuteFilePickerState( ) :
    m_FirstControlCommand( NULL )
{
}

//---------------------------------------------
//
//---------------------------------------------

CNonExecuteFilePickerState::~CNonExecuteFilePickerState( )
{
    reset( );
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CNonExecuteFilePickerState::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue )
{
    CValueControlCommand* value_command = new CValueControlCommand(
        aControlId, aControlAction, aValue );

    addControlCommand( value_command );
}

//---------------------------------------------
//
//---------------------------------------------

Any SAL_CALL CNonExecuteFilePickerState::getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
{
    CValueControlCommandRequest value_request( aControlId, aControlAction );
    Any aAny;

	if (m_FirstControlCommand)
	{
		// pass the request along the command-chain
		std::auto_ptr< CControlCommandResult > result( m_FirstControlCommand->handleRequest( &value_request ) );

		OSL_ENSURE( result.get(), "invalid getValue request" );

		if ( result.get() )
		{
			// #101753 must remove assertion else running into deadlock
			// because getValue may be called asynchronously from main thread
			// with locked SOLAR_MUTEX but we also need SOLAR_MUTEX in
			// WinFileOpenDialog::onInitDone ... but we cannot dismiss the
			// assertion dialog because at this point the FileOpen Dialog
			// has already the focus but is not yet visible :-(
			// The real cure is to remove the VCL/SOLAR_MUTEX dependency
			// cause by the use of our resource manager and not being able to
			// generate native windows resources
			//OSL_ENSURE( result->hasResult( ), "invalid getValue request" );

			if ( result->hasResult( ) )
			{
				CValueCommandResult* value_result = dynamic_cast< CValueCommandResult* >( result.get( ) );
				OSL_ENSURE( value_result, "should have be a CValueCommandResult" );

				aAny = value_result->getValue( );
				OSL_ENSURE( aAny.hasValue( ), "empty any" );
			}
		}
	}

    return aAny;
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CNonExecuteFilePickerState::enableControl( sal_Int16 aControlId, sal_Bool bEnable )
{
    CEnableControlCommand* enable_command = new CEnableControlCommand(
        aControlId, bEnable );

    addControlCommand( enable_command );
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CNonExecuteFilePickerState::setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel )
{
    CLabelControlCommand* label_command = new CLabelControlCommand(
        aControlId, aLabel );

    addControlCommand( label_command );
}

//---------------------------------------------
//
//---------------------------------------------

OUString SAL_CALL CNonExecuteFilePickerState::getLabel( sal_Int16 aControlId )
{
    CControlCommandRequest label_request( aControlId );

    // pass the request along the command-chain
    std::auto_ptr< CControlCommandResult > result( m_FirstControlCommand->handleRequest( &label_request ) );

    OSL_ENSURE( result->hasResult( ), "invalid getValue request" );

    OUString aLabel;

    if ( result->hasResult( ) )
    {
        CLabelCommandResult* label_result = dynamic_cast< CLabelCommandResult* >( result.get( ) );
        OSL_ENSURE( label_result, "should have be a CLabelCommandResult" );

        aLabel = label_result->getLabel( );
    }

    return aLabel;
}

/*  #i26224#
    When typing file names with drive letter but without '\'
    in the "File name" box of the FileOpen dialog the FileOpen
    dialog makes strange paths out of them e.g. "d:.\test.sxw".
    Such file names will not be accepted by sal so we fix these
    somehow broken paths here. */
OUString MatchFixBrokenPath(const OUString& path)
{
    OSL_ASSERT(path.getLength() >= 4);

    if (path[1] == ':' && path[2] == '.' && path[3] == '\\')
    {
        // skip the '.'
        return (path.copy(0,2) + path.copy(3));
    }
    return path;
}

//-----------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------
static ::rtl::OUString trimTrailingSpaces(const ::rtl::OUString& rString)
{
    rtl::OUString aResult(rString);

    sal_Int32 nIndex = rString.lastIndexOf(' ');
    if (nIndex == rString.getLength()-1)
    {
        while (nIndex >= 0 && rString[nIndex] == ' ')
            nIndex--;
        if (nIndex >= 0)
            aResult = rString.copy(0,nIndex+1);
        else
            aResult = ::rtl::OUString();
    }
    return aResult;
}

Sequence< OUString > SAL_CALL CNonExecuteFilePickerState::getFiles( CFileOpenDialog* aFileOpenDialog )
{
    OSL_PRECOND( aFileOpenDialog, "invalid parameter" );

    Sequence< OUString > aFilePathList;
    OUString aFilePathURL;
    OUString aFilePath;
    ::osl::FileBase::RC rc;

    aFilePath = aFileOpenDialog->getFullFileName( );

    if ( aFilePath.getLength( ) )
    {
        // tokenize the returned string and copy the
        // sub-strings separately into a sequence
        const sal_Unicode* pTemp = aFilePath.getStr();
        const sal_Unicode* pStrEnd = pTemp + aFilePath.getLength();
        sal_uInt32 lSubStr;

        while (pTemp < pStrEnd)
        {
            // detect the length of the next sub string
            lSubStr = rtl_ustr_getLength(pTemp);

            aFilePathList.realloc(aFilePathList.getLength() + 1);

            aFilePathList[aFilePathList.getLength() - 1] =
                MatchFixBrokenPath(OUString(pTemp, lSubStr));

            pTemp += (lSubStr + 1);
        }

        // change all entries to file URLs
        sal_Int32 lenFileList = aFilePathList.getLength( );
		OSL_ASSERT( lenFileList >= 1 );

        for ( sal_Int32 i = 0; i < lenFileList; i++ )
        {
			aFilePath = trimTrailingSpaces(aFilePathList[i]);
			rc = ::osl::FileBase::getFileURLFromSystemPath(
                aFilePath, aFilePathURL );

            // we do return all or nothing, that means
            // in case of failures we destroy the sequence
            // and return an empty sequence
            if ( rc != ::osl::FileBase::E_None )
            {
                aFilePathList.realloc( 0 );
                break;
            }

            aFilePathList[i] = aFilePathURL;
        }
    }

    return aFilePathList;
}

//---------------------------------------------
//
//---------------------------------------------

OUString SAL_CALL CNonExecuteFilePickerState::getDisplayDirectory( CFileOpenDialog* aFileOpenDialog )
{
    OSL_PRECOND( aFileOpenDialog, "invalid parameter" );

    OUString pathURL;
    OUString displayDir;

    displayDir = aFileOpenDialog->getLastDisplayDirectory( );

	if ( displayDir.getLength( ) )
        ::osl::FileBase::getFileURLFromSystemPath( displayDir, pathURL );

	return pathURL;
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CNonExecuteFilePickerState::reset( )
{
    CControlCommand* nextCommand;
    CControlCommand* currentCommand = m_FirstControlCommand;

    while( currentCommand )
    {
        nextCommand = currentCommand->getNextCommand( );
        delete currentCommand;
        currentCommand = nextCommand;
    }

    m_FirstControlCommand = NULL;
}

//---------------------------------------------
//
//---------------------------------------------

CControlCommand* SAL_CALL CNonExecuteFilePickerState::getControlCommand( ) const
{
    return m_FirstControlCommand;
}

//---------------------------------------------
// we append new control commands to the end
// of the list so that we are sure the commands
// will be executed as the client issued it
//---------------------------------------------

void SAL_CALL CNonExecuteFilePickerState::addControlCommand( CControlCommand* aControlCommand )
{
    OSL_ASSERT( aControlCommand );

    if ( NULL == m_FirstControlCommand )
    {
        m_FirstControlCommand = aControlCommand;
    }
    else
    {
        CControlCommand* pNextControlCommand = m_FirstControlCommand;

        while ( pNextControlCommand->getNextCommand( ) != NULL )
            pNextControlCommand = pNextControlCommand->getNextCommand( );

        pNextControlCommand->setNextCommand( aControlCommand );
    }
}

//#######################################################################

//---------------------------------------------
//
//---------------------------------------------

CExecuteFilePickerState::CExecuteFilePickerState( HWND hwndDlg ) :
    m_hwndDlg( hwndDlg )
{
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CExecuteFilePickerState::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue )
{
    // we do not support SET_HELP_URL/GET_HELP_URL
    if ( com::sun::star::ui::dialogs::ControlActions::SET_HELP_URL == aControlAction )
        return;

    HWND hwndCtrl = GetHwndDlgItem( aControlId );

	// the filter listbox can be manipulated via this
	// method the caller should use XFilterManager
    if ( !hwndCtrl || (aControlId == LISTBOX_FILTER) )
    {
        OSL_ENSURE( sal_False, "invalid control id" );
        return;
    }

    CTRL_CLASS aCtrlClass = GetCtrlClass( hwndCtrl );
    if ( UNKNOWN == aCtrlClass )
    {
        OSL_ENSURE( sal_False, "unsupported control class" );
        return;
    }

    CTRL_SETVALUE_FUNCTION_T lpfnSetValue =
        GetCtrlSetValueFunction( aCtrlClass, aControlAction );

    if ( !lpfnSetValue )
    {
        OSL_ENSURE( sal_False, "unsupported control action" );
        return;
    }

    // the function that we call should throw an IllegalArgumentException if
    // the given value is invalid or empty, that's why we provide a Reference
    // to an XInterface and a argument position
    lpfnSetValue( hwndCtrl, aValue, Reference< XInterface >( ), 3 );
}

//---------------------------------------------
//
//---------------------------------------------

Any SAL_CALL CExecuteFilePickerState::getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
{
    // we do not support SET_HELP_URL/GET_HELP_URL
    if ( com::sun::star::ui::dialogs::ControlActions::GET_HELP_URL == aControlAction )
        return Any( );

    HWND hwndCtrl = GetHwndDlgItem( aControlId );

	// the filter listbox can be manipulated via this
	// method the caller should use XFilterManager
    if ( !hwndCtrl || (aControlId == LISTBOX_FILTER) )
    {
        OSL_ENSURE( sal_False, "invalid control id" );
        return Any( );
    }

    CTRL_CLASS aCtrlClass = GetCtrlClass( hwndCtrl );
    if ( UNKNOWN == aCtrlClass )
    {
        OSL_ENSURE( sal_False, "unsupported control class" );
        return Any( );
    }

    CTRL_GETVALUE_FUNCTION_T lpfnGetValue =
        GetCtrlGetValueFunction( aCtrlClass, aControlAction );

    if ( !lpfnGetValue )
    {
        OSL_ENSURE( sal_False, "unsupported control action" );
        return Any( );
    }

    return lpfnGetValue( hwndCtrl );
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CExecuteFilePickerState::enableControl( sal_Int16 aControlId, sal_Bool bEnable )
{
    HWND hwndCtrl = GetHwndDlgItem( aControlId );

    OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id");

    EnableWindow( hwndCtrl, bEnable );
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CExecuteFilePickerState::setLabel( sal_Int16 aControlId, const OUString& aLabel )
{
    HWND hwndCtrl = GetHwndDlgItem( aControlId );

    OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id");

    if ( IsListboxControl( hwndCtrl ) )
        hwndCtrl = GetListboxLabelItem( aControlId );

    OUString aWinLabel = SOfficeToWindowsLabel( aLabel );

	// somewhat risky because we don't know if OUString
	// has a terminating '\0'
    SetWindowText( hwndCtrl, reinterpret_cast<LPCTSTR>(aWinLabel.getStr( )) );
}

//---------------------------------------------
//
//---------------------------------------------

OUString SAL_CALL CExecuteFilePickerState::getLabel( sal_Int16 aControlId )
{
    HWND hwndCtrl = GetHwndDlgItem( aControlId );

    OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id");

    if ( IsListboxControl( hwndCtrl ) )
        hwndCtrl = GetListboxLabelItem( aControlId );

    sal_Unicode aLabel[MAX_LABEL];
    int nRet = GetWindowText( hwndCtrl, reinterpret_cast<LPTSTR>(aLabel), MAX_LABEL );

    OUString ctrlLabel;
    if ( nRet )
    {
        ctrlLabel = OUString( aLabel, rtl_ustr_getLength( aLabel ) );
        ctrlLabel = WindowsToSOfficeLabel( aLabel );
    }

    return ctrlLabel;
}

//---------------------------------------------
//
//---------------------------------------------

Sequence< OUString > SAL_CALL CExecuteFilePickerState::getFiles( CFileOpenDialog* aFileOpenDialog )
{
    OSL_POSTCOND( aFileOpenDialog, "invalid parameter" );

    Sequence< OUString > aFilePathList;
    OUString aFilePathURL;
    OUString aFilePath;
    ::osl::FileBase::RC rc;

	// in execution mode getFullFileName doesn't
	// return anything, so we must use another way

    // returns the currently selected file(s)
    // including path information
    aFilePath = aFileOpenDialog->getCurrentFilePath( );

	// if multiple files are selected or the user
	// typed anything that doesn't seem to be a valid
	// file name getFileURLFromSystemPath fails
	// and we return an empty file list
    rc = ::osl::FileBase::getFileURLFromSystemPath(
        aFilePath, aFilePathURL );

    if ( ::osl::FileBase::E_None == rc )
    {
        aFilePathList.realloc( 1 );
        aFilePathList[0] = aFilePathURL;
    }

    return aFilePathList;
}

//---------------------------------------------
//
//---------------------------------------------

OUString SAL_CALL CExecuteFilePickerState::getDisplayDirectory( CFileOpenDialog* aFileOpenDialog )
{
    OSL_POSTCOND( aFileOpenDialog, "invalid parameter" );

    OUString pathURL;
    OUString displayDir;

    displayDir = aFileOpenDialog->getCurrentFolderPath( );

    if ( displayDir.getLength( ) )
        ::osl::FileBase::getFileURLFromSystemPath( displayDir, pathURL );

	return pathURL;
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CExecuteFilePickerState::initFilePickerControls( CControlCommand* firstControlCommand )
{
    CControlCommand* aControlCommand = firstControlCommand;

    while ( aControlCommand )
    {
        aControlCommand->exec( this );
        aControlCommand = aControlCommand->getNextCommand( );
    }
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CExecuteFilePickerState::cacheControlState( HWND hwndControl, CFilePickerState* aNonExecFilePickerState )
{
    OSL_ENSURE( hwndControl && aNonExecFilePickerState, "invalid parameters" );

    CTRL_CLASS aCtrlClass = GetCtrlClass( hwndControl );

    sal_Int16 aControlAction;
    CTRL_GETVALUE_FUNCTION_T lpfnGetValue;

    if ( CHECKBOX == aCtrlClass )
    {
        aControlAction = 0;

        lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction );

        OSL_ASSERT( lpfnGetValue );

        aNonExecFilePickerState->setValue(
            sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
            aControlAction,
            lpfnGetValue( hwndControl ) );

        aNonExecFilePickerState->setLabel(
            sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
            getLabel(
                sal::static_int_cast< sal_Int16 >(
                    GetDlgCtrlID( hwndControl ) ) ) );
    }
    else if ( LISTBOX == aCtrlClass )
    {
        // for listboxes we save only the
        // last selected item and the last
        // selected item index

        aControlAction = GET_SELECTED_ITEM;

        lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction );

        aNonExecFilePickerState->setValue(
            sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
            aControlAction,
            lpfnGetValue( hwndControl ) );

        aControlAction = ::com::sun::star::ui::dialogs::ControlActions::GET_SELECTED_ITEM_INDEX;

        lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction );

        aNonExecFilePickerState->setValue(
            sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
            aControlAction,
            lpfnGetValue( hwndControl ) );
    }
}

//---------------------------------------------
//
//---------------------------------------------

void SAL_CALL CExecuteFilePickerState::setHwnd( HWND hwndDlg )
{
    m_hwndDlg = hwndDlg;
}

//---------------------------------------------
//
//---------------------------------------------

inline sal_Bool SAL_CALL CExecuteFilePickerState::IsListboxControl( HWND hwndControl ) const
{
    OSL_PRECOND( IsWindow( hwndControl ), "invalid parameter" );

    CTRL_CLASS aCtrlClass = GetCtrlClass( hwndControl );
    return ( LISTBOX == aCtrlClass );
}

//---------------------------------------------
// because listboxes (comboboxes) and their labels
// are separated we have to translate the listbox
// id to their corresponding label id
// the convention is that the label id of a listbox
// is the id of the listbox + 100
//---------------------------------------------

inline sal_Int16 SAL_CALL CExecuteFilePickerState::ListboxIdToListboxLabelId( sal_Int16 aListboxId ) const
{
    return ( aListboxId + LISTBOX_LABEL_OFFSET );
}

//---------------------------------------------
//
//---------------------------------------------

inline HWND SAL_CALL CExecuteFilePickerState::GetListboxLabelItem( sal_Int16 aControlId ) const
{
    sal_Int16 aLabelId = ListboxIdToListboxLabelId( aControlId );
    HWND hwndCtrl = GetHwndDlgItem( aLabelId );

    OSL_ASSERT( IsWindow( hwndCtrl ) );

    return hwndCtrl;
}

//---------------------------------------------
//
//---------------------------------------------

HWND SAL_CALL CExecuteFilePickerState::GetHwndDlgItem( sal_Int16 aControlId, sal_Bool bIncludeStdCtrls ) const
{
    OSL_ENSURE( IsWindow( m_hwndDlg ), "no valid parent window set before" );

    HWND hwndCtrl = GetDlgItem( m_hwndDlg, aControlId );

    // maybe it's a control of the dialog itself for instance
    // the ok and cancel button
    if ( !hwndCtrl && bIncludeStdCtrls )
    {
		hwndCtrl = GetDlgItem(
            GetParent( m_hwndDlg ),
            CommonFilePickerCtrlIdToWinFileOpenCtrlId( aControlId ) );
    }

	return hwndCtrl;
}
