/**************************************************************
 * 
 * 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 <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/util/XCloseBroadcaster.hpp>
#include <com/sun/star/util/XCloseListener.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <cppuhelper/implbase1.hxx>
#include <comphelper/processfactory.hxx>

#include <math.h>
#include <tools/svwin.h>
#include <tools/stream.hxx>
#include <vos/mutex.hxx>
#include <vos/module.hxx>
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/sysdata.hxx>
#include <vcl/salbtype.hxx>
#include "scanner.hxx"

#pragma warning (push,1)
#pragma warning (disable:4668)
#include "twain/twain.h"
#pragma warning (pop)

using namespace ::com::sun::star;

// -----------
// - Defines -
// -----------

#define TWAIN_SELECT			0x00000001UL
#define TWAIN_ACQUIRE			0x00000002UL
#define TWAIN_TERMINATE			0xFFFFFFFFUL

#define TWAIN_EVENT_NONE		0x00000000UL
#define TWAIN_EVENT_QUIT		0x00000001UL
#define TWAIN_EVENT_SCANNING	0x00000002UL
#define TWAIN_EVENT_XFER		0x00000004UL

#define PFUNC					(*pDSM)
#define PTWAINMSG				MSG*
#define FIXTODOUBLE( nFix ) 	((double)nFix.Whole+(double)nFix.Frac/65536.)
#define FIXTOLONG( nFix )		((long)floor(FIXTODOUBLE(nFix)+0.5))
								
#if defined WNT				
#define TWAIN_LIBNAME			"TWAIN_32.DLL"
#define TWAIN_FUNCNAME			"DSM_Entry"
#endif

// --------------
// - TwainState -
// --------------

enum TwainState
{
	TWAIN_STATE_NONE = 0,
	TWAIN_STATE_SCANNING = 1,
	TWAIN_STATE_DONE = 2,
	TWAIN_STATE_CANCELED = 3
};

// ------------
// - ImpTwain -
// ------------

class ImpTwain : public ::cppu::WeakImplHelper1< util::XCloseListener >
{
    friend LRESULT CALLBACK TwainMsgProc( int nCode, WPARAM wParam, LPARAM lParam );

    uno::Reference< uno::XInterface >			mxSelfRef;
	uno::Reference< scanner::XScannerManager >	mxMgr;
	ScannerManager&								mrMgr;
	TW_IDENTITY									aAppIdent;
	TW_IDENTITY									aSrcIdent;
	Link										aNotifyLink;
	DSMENTRYPROC								pDSM;
	vos:: OModule *					pMod;
	ULONG										nCurState;
	HWND						                hTwainWnd;
	HHOOK						                hTwainHook;
    bool										mbCloseFrameOnExit;

	bool						                ImplHandleMsg( void* pMsg );
	void										ImplCreate();
	void										ImplOpenSourceManager();
	void										ImplOpenSource();
	bool										ImplEnableSource();
	void										ImplXfer();
	void										ImplFallback( ULONG nEvent );
    void 										ImplSendCloseEvent();
    void 										ImplDeregisterCloseListener();
    void 										ImplRegisterCloseListener();
    uno::Reference< frame::XFrame > 			ImplGetActiveFrame();
    uno::Reference< util::XCloseBroadcaster > 	ImplGetActiveFrameCloseBroadcaster();

												DECL_LINK( ImplFallbackHdl, void* );
												DECL_LINK( ImplDestroyHdl, void* );

    // from util::XCloseListener
    virtual void SAL_CALL queryClosing( const lang::EventObject& Source, sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException);
    virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException);

    // from lang::XEventListener
    virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);

public:

								                ImpTwain( ScannerManager& rMgr, const Link& rNotifyLink );
								                ~ImpTwain();

	void						                Destroy();

	bool						                SelectSource();
	bool						                InitXfer(); 
};

// ---------
// - Procs -
// ---------

static ImpTwain* pImpTwainInstance = NULL;

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

LRESULT CALLBACK TwainWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
{
	return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
}

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

LRESULT CALLBACK TwainMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
{
	MSG* pMsg = (MSG*) lParam;

	if( ( nCode < 0 ) || ( pImpTwainInstance->hTwainWnd != pMsg->hwnd ) || !pImpTwainInstance->ImplHandleMsg( (void*) lParam ) )
	{
		return CallNextHookEx( pImpTwainInstance->hTwainHook, nCode, wParam, lParam );
	}
	else
	{
		pMsg->message = WM_USER;
		pMsg->lParam = 0;
		
		return 0;
	}
}

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

// #107835# hold reference to ScannerManager, to prevent premature death
ImpTwain::ImpTwain( ScannerManager& rMgr, const Link& rNotifyLink ) :
			mrMgr( rMgr ),
		    mxMgr( uno::Reference< scanner::XScannerManager >( static_cast< OWeakObject* >( &rMgr ), uno::UNO_QUERY) ),
			aNotifyLink( rNotifyLink ),
			pDSM( NULL ),
			pMod( NULL ),
			hTwainWnd( 0 ),
			hTwainHook( 0 ),
			nCurState( 1 ),
            mbCloseFrameOnExit( false )
{
    // setup TWAIN window
	pImpTwainInstance = this;

	aAppIdent.Id = 0;
	aAppIdent.Version.MajorNum = 1;
	aAppIdent.Version.MinorNum = 0;
	aAppIdent.Version.Language = TWLG_USA;
	aAppIdent.Version.Country = TWCY_USA;
	aAppIdent.ProtocolMajor = TWON_PROTOCOLMAJOR;
	aAppIdent.ProtocolMinor = TWON_PROTOCOLMINOR;
	aAppIdent.SupportedGroups =	DG_IMAGE | DG_CONTROL;
	strncpy( aAppIdent.Version.Info, "8.0", 32 ); 
    aAppIdent.Version.Info[32] = aAppIdent.Version.Info[33] = 0;
	strncpy( aAppIdent.Manufacturer, "Sun Microsystems", 32 );
    aAppIdent.Manufacturer[32] = aAppIdent.Manufacturer[33] = 0;
	strncpy( aAppIdent.ProductFamily,"Office", 32 );
    aAppIdent.ProductFamily[32] = aAppIdent.ProductFamily[33] = 0;
	strncpy( aAppIdent.ProductName, "Office", 32 );
    aAppIdent.ProductName[32] = aAppIdent.ProductName[33] = 0;

	WNDCLASS aWc = { 0, &TwainWndProc, 0, sizeof( WNDCLASS ), GetModuleHandle( NULL ), NULL, NULL, NULL, NULL, "TwainClass" };
	RegisterClass( &aWc );
	
	hTwainWnd = CreateWindowEx( WS_EX_TOPMOST, aWc.lpszClassName, "TWAIN", 0, 0, 0, 0, 0, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
	hTwainHook = SetWindowsHookEx( WH_GETMESSAGE, &TwainMsgProc, NULL, GetCurrentThreadId() );

    // #107835# block destruction until ImplDestroyHdl is called
    mxSelfRef = static_cast< ::cppu::OWeakObject* >( this );
}

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

ImpTwain::~ImpTwain()
{
    // are we responsible for application shutdown?
    if( mbCloseFrameOnExit )
        ImplSendCloseEvent();
}

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

void ImpTwain::Destroy()
{
	ImplFallback( TWAIN_EVENT_NONE );
	Application::PostUserEvent( LINK( this, ImpTwain, ImplDestroyHdl ), NULL );
}

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

bool ImpTwain::SelectSource()
{
	TW_UINT16 nRet = TWRC_FAILURE;

	ImplOpenSourceManager();

	if( 3 == nCurState )
	{
		TW_IDENTITY aIdent;

		aIdent.Id = 0, aIdent.ProductName[ 0 ] = '\0';
		aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
		nRet = PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &aIdent );
	}

	ImplFallback( TWAIN_EVENT_QUIT );

	return( TWRC_SUCCESS == nRet );
}

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

bool ImpTwain::InitXfer()
{
	bool bRet = false;

	ImplOpenSourceManager();

	if( 3 == nCurState )
	{
		ImplOpenSource();

		if( 4 == nCurState )
			bRet = ImplEnableSource();
	}

	if( !bRet )
		ImplFallback( TWAIN_EVENT_QUIT );

	return bRet;
}

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

void ImpTwain::ImplOpenSourceManager()
{
	if( 1 == nCurState )
	{
		pMod = new ::vos::OModule( ::rtl::OUString() );

		if( pMod->load( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( TWAIN_LIBNAME ) ) ) )
		{
			nCurState = 2;

			if( ( ( pDSM = (DSMENTRYPROC) pMod->getSymbol( String( RTL_CONSTASCII_USTRINGPARAM( TWAIN_FUNCNAME ) ) ) ) != NULL ) &&
				( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, &hTwainWnd ) == TWRC_SUCCESS ) )
			{
				nCurState = 3;
			}
		}
		else
		{
			delete pMod;
			pMod = NULL;
		}
	}
}

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

void ImpTwain::ImplOpenSource()
{
	if( 3 == nCurState )
	{
		if( ( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &aSrcIdent ) == TWRC_SUCCESS ) &&
			( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &aSrcIdent ) == TWRC_SUCCESS ) )
		{
			TW_CAPABILITY	aCap = { CAP_XFERCOUNT, TWON_ONEVALUE, GlobalAlloc( GHND, sizeof( TW_ONEVALUE ) ) };
			TW_ONEVALUE*	pVal = (TW_ONEVALUE*) GlobalLock( aCap.hContainer );

			pVal->ItemType = TWTY_INT16, pVal->Item = 1;
			GlobalUnlock( aCap.hContainer );
			PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_CAPABILITY, MSG_SET, &aCap );
			GlobalFree( aCap.hContainer );
			nCurState = 4;
		}
	}
}

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

bool ImpTwain::ImplEnableSource()
{
	bool bRet = false;

	if( 4 == nCurState )
	{
		TW_USERINTERFACE aUI = { true, true, hTwainWnd };

		aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
		nCurState = 5;

        // #107835# register as vetoable close listener, to prevent application to die under us
        ImplRegisterCloseListener();

		if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &aUI ) == TWRC_SUCCESS )
        {
			bRet = true;
        }
		else
        {
			nCurState = 4;

            // #107835# deregister as vetoable close listener, dialog failed
            ImplDeregisterCloseListener();
        }
	}

	return bRet;
}

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

bool ImpTwain::ImplHandleMsg( void* pMsg )
{
	TW_UINT16	nRet;
	PTWAINMSG	pMess = (PTWAINMSG) pMsg;
	TW_EVENT	aEvt = { pMess, MSG_NULL };

	nRet = PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &aEvt );

	if( aEvt.TWMessage != MSG_NULL )
	{
		switch( aEvt.TWMessage )
		{
			case MSG_XFERREADY:
			{
				ULONG nEvent = TWAIN_EVENT_QUIT;

				if( 5 == nCurState )
				{
					nCurState = 6;
					ImplXfer();

					if( mrMgr.GetData() )
						nEvent = TWAIN_EVENT_XFER;
				}

				ImplFallback( nEvent );
			}
			break;
			
			case MSG_CLOSEDSREQ:
				ImplFallback( TWAIN_EVENT_QUIT );
			break;

			default:
			break;
		}
	}
	else
		nRet = TWRC_NOTDSEVENT;

	return( TWRC_DSEVENT == nRet );
}

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

void ImpTwain::ImplXfer()
{
	if( nCurState == 6 )
	{
		TW_IMAGEINFO	aInfo;
		TW_UINT32		hDIB = 0;
		long			nWidth, nHeight, nXRes, nYRes;

		if( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, &aInfo ) == TWRC_SUCCESS )
		{
			nWidth = aInfo.ImageWidth;
			nHeight = aInfo.ImageLength;
			nXRes = FIXTOLONG( aInfo.XResolution );
			nYRes = FIXTOLONG( aInfo.YResolution );
		}
		else
			nWidth = nHeight = nXRes = nYRes = -1L;

		switch( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hDIB ) )
		{
			case( TWRC_CANCEL ):
				nCurState = 7;
			break;

			case( TWRC_XFERDONE ):
			{
				if( hDIB )
				{
					if( ( nXRes != -1 ) && ( nYRes != - 1 ) && ( nWidth != - 1 ) && ( nHeight != - 1 ) )
					{
						// set resolution of bitmap
						BITMAPINFOHEADER*	pBIH = (BITMAPINFOHEADER*) GlobalLock( (HGLOBAL) hDIB );
						static const double	fFactor = 100.0 / 2.54;

						pBIH->biXPelsPerMeter = FRound( fFactor * nXRes );
						pBIH->biYPelsPerMeter = FRound( fFactor * nYRes );

						GlobalUnlock( (HGLOBAL) hDIB );
					}

					mrMgr.SetData( (void*)(long) hDIB );
				}
				else
					GlobalFree( (HGLOBAL) hDIB );

				nCurState = 7;
			}
			break;

			default:
			break;
		}
	}
}

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

void ImpTwain::ImplFallback( ULONG nEvent )
{
	Application::PostUserEvent( LINK( this, ImpTwain, ImplFallbackHdl ), (void*) nEvent );
}

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

IMPL_LINK( ImpTwain, ImplFallbackHdl, void*, pData )
{
	const ULONG	nEvent = (ULONG) pData;
	bool		bFallback = true;

	switch( nCurState )
	{
		case( 7 ):
		case( 6 ):
		{
			TW_PENDINGXFERS aXfers;

			if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, &aXfers ) == TWRC_SUCCESS )
			{
				if( aXfers.Count != 0 )
					PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, &aXfers );
			}

			nCurState = 5;
		}
		break;

		case( 5 ):
		{
			TW_USERINTERFACE aUI = { true, true, hTwainWnd };
		
			PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &aUI );
			nCurState = 4;

            // #107835# deregister as vetoable close listener
            ImplDeregisterCloseListener();
		}
		break;

		case( 4 ):
		{
			PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &aSrcIdent );
			nCurState = 3;
		}
		break;

		case( 3 ):
		{
			PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, &hTwainWnd );
			nCurState = 2;
		}
		break;

		case( 2 ):
		{
			delete pMod;
			pMod = NULL;
			nCurState = 1;
		}
		break;

		default:
		{
			if( nEvent != TWAIN_EVENT_NONE )
				aNotifyLink.Call( (void*) nEvent );

			bFallback = false;
		}
		break;
	}

	if( bFallback )
		ImplFallback( nEvent );

	return 0L;
}

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

IMPL_LINK( ImpTwain, ImplDestroyHdl, void*, /*p*/ )
{
	if( hTwainWnd )
		DestroyWindow( hTwainWnd );

	if( hTwainHook )
		UnhookWindowsHookEx( hTwainHook );

    // #107835# permit destruction of ourselves (normally, refcount
    // should drop to zero exactly here)
	mxSelfRef = NULL;
	pImpTwainInstance = NULL;

	return 0L;
}

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

uno::Reference< frame::XFrame > ImpTwain::ImplGetActiveFrame()
{
    try
    {
        uno::Reference< lang::XMultiServiceFactory >  xMgr( ::comphelper::getProcessServiceFactory() );

        if( xMgr.is() )
        {
            // query desktop instance
            uno::Reference< frame::XDesktop > xDesktop( xMgr->createInstance(
                                                            OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), uno::UNO_QUERY );
        
            if( xDesktop.is() )
            {
                // query property set from desktop, which contains the currently active frame
                uno::Reference< beans::XPropertySet > xDesktopProps( xDesktop, uno::UNO_QUERY );

                if( xDesktopProps.is() )
                {
                    uno::Any aActiveFrame;

                    try
                    {
                        aActiveFrame = xDesktopProps->getPropertyValue(
                            OUString::createFromAscii( "ActiveFrame" ) );
                    }
                    catch( const beans::UnknownPropertyException& )
                    {
                        // property unknown.
                        DBG_ERROR("ImpTwain::ImplGetActiveFrame: ActiveFrame property unknown, cannot determine active frame!");
                        return uno::Reference< frame::XFrame >();
                    }

                    uno::Reference< frame::XFrame > xActiveFrame;
                
                    if( (aActiveFrame >>= xActiveFrame) &&
                        xActiveFrame.is() )
                    {
                        return xActiveFrame;
                    }
                }
            }
        }
    }
    catch( const uno::Exception& )
    {
    }

    DBG_ERROR("ImpTwain::ImplGetActiveFrame: Could not determine active frame!");
    return uno::Reference< frame::XFrame >();
}

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

uno::Reference< util::XCloseBroadcaster > ImpTwain::ImplGetActiveFrameCloseBroadcaster()
{
    try
    {
        return uno::Reference< util::XCloseBroadcaster >( ImplGetActiveFrame(), uno::UNO_QUERY );
    }
    catch( const uno::Exception& )
    {
    }

    DBG_ERROR("ImpTwain::ImplGetActiveFrameCloseBroadcaster: Could determine close broadcaster on active frame!");
    return uno::Reference< util::XCloseBroadcaster >();
}

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

void ImpTwain::ImplRegisterCloseListener()
{
    try
    {
        uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( ImplGetActiveFrameCloseBroadcaster() );
        
        if( xCloseBroadcaster.is() )
        {
            xCloseBroadcaster->addCloseListener(this);
            return; // successfully registered as a close listener
        }
        else
        {
            // interface unknown. don't register, then
            DBG_ERROR("ImpTwain::ImplRegisterCloseListener: XFrame has no XCloseBroadcaster!");
            return;
        }
    }
    catch( const uno::Exception& )
    {
    }

    DBG_ERROR("ImpTwain::ImplRegisterCloseListener: Could not register as close listener!");
}

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

void ImpTwain::ImplDeregisterCloseListener()
{
    try
    {
        uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( 
            ImplGetActiveFrameCloseBroadcaster() );
        
        if( xCloseBroadcaster.is() )
        {
            xCloseBroadcaster->removeCloseListener(this);
            return; // successfully deregistered as a close listener
        }
        else
        {
            // interface unknown. don't deregister, then
            DBG_ERROR("ImpTwain::ImplDeregisterCloseListener: XFrame has no XCloseBroadcaster!");
            return;
        }
    }
    catch( const uno::Exception& )
    {
    }

    DBG_ERROR("ImpTwain::ImplDeregisterCloseListener: Could not deregister as close listener!");
}

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

void SAL_CALL ImpTwain::queryClosing( const lang::EventObject& /*Source*/, sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException)
{
    // shall we re-send the close query later on?
    mbCloseFrameOnExit = GetsOwnership;

    // the sole purpose of this listener is to forbid closing of the listened-at frame
    throw util::CloseVetoException();
}

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

void SAL_CALL ImpTwain::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
{
    // should not happen
    DBG_ERROR("ImpTwain::notifyClosing called, but we vetoed the closing before!");
}

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

void SAL_CALL ImpTwain::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
{
    // we're not holding any references to the frame, thus noop
}

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

void ImpTwain::ImplSendCloseEvent()
{
    try
    {
        uno::Reference< util::XCloseable > xCloseable( ImplGetActiveFrame(), uno::UNO_QUERY );
        
        if( xCloseable.is() )
            xCloseable->close( true );
    }
    catch( const uno::Exception& )
    {
    }

    DBG_ERROR("ImpTwain::ImplSendCloseEvent: Could not send required close broadcast!");
}


// ---------
// - Twain -
// ---------

class Twain
{
	uno::Reference< lang::XEventListener >	    mxListener;
	uno::Reference< scanner::XScannerManager >	mxMgr;
	const ScannerManager*			            mpCurMgr;
	ImpTwain* 						            mpImpTwain;
	TwainState						            meState;
												
									            DECL_LINK( ImpNotifyHdl, ImpTwain* );
														
public:													
														
									Twain();
									~Twain();
														
	bool							SelectSource( ScannerManager& rMgr );
	bool							PerformTransfer( ScannerManager& rMgr, const uno::Reference< lang::XEventListener >& rxListener );
														
	TwainState						GetState() const { return meState; }
};

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

Twain::Twain() :
		mpCurMgr( NULL ),
		mpImpTwain( NULL ),
		meState( TWAIN_STATE_NONE )
{
}

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

Twain::~Twain()
{
	if( mpImpTwain )
		mpImpTwain->Destroy();
}

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

bool Twain::SelectSource( ScannerManager& rMgr )
{
	bool bRet;

	if( !mpImpTwain )
	{
        // #107835# hold reference to ScannerManager, to prevent premature death
        mxMgr = uno::Reference< scanner::XScannerManager >( static_cast< OWeakObject* >( const_cast< ScannerManager* >( mpCurMgr = &rMgr ) ),
                                                            uno::UNO_QUERY ),
		
		meState = TWAIN_STATE_NONE;
		mpImpTwain = new ImpTwain( rMgr, LINK( this, Twain, ImpNotifyHdl ) );
		bRet = mpImpTwain->SelectSource();
	}
	else
		bRet = false;

	return bRet;
}

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

bool Twain::PerformTransfer( ScannerManager& rMgr, const uno::Reference< lang::XEventListener >& rxListener )
{
	bool bRet;

	if( !mpImpTwain )
	{
        // #107835# hold reference to ScannerManager, to prevent premature death
        mxMgr = uno::Reference< scanner::XScannerManager >( static_cast< OWeakObject* >( const_cast< ScannerManager* >( mpCurMgr = &rMgr ) ),
                                                            uno::UNO_QUERY ),
		
		mxListener = rxListener;
		meState = TWAIN_STATE_NONE;
		mpImpTwain = new ImpTwain( rMgr, LINK( this, Twain, ImpNotifyHdl ) );
		bRet = mpImpTwain->InitXfer();
	}
	else
		bRet = false;

	return bRet;
}

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

IMPL_LINK( Twain, ImpNotifyHdl, ImpTwain*, nEvent )
{
	switch( (ULONG)(void*) nEvent )
	{
		case( TWAIN_EVENT_SCANNING ):
			meState = TWAIN_STATE_SCANNING;
		break;

		case( TWAIN_EVENT_QUIT ):
		{
			if( meState != TWAIN_STATE_DONE )
				meState = TWAIN_STATE_CANCELED;

			if( mpImpTwain )
			{
			    mpImpTwain->Destroy();
			    mpImpTwain = NULL;
                mpCurMgr = NULL;
			}

			if( mxListener.is() )
				mxListener->disposing( lang::EventObject( mxMgr ) );

			mxListener = NULL;
		}
		break;

		case( TWAIN_EVENT_XFER ):
		{
			if( mpImpTwain )
			{
				meState = ( mpCurMgr->GetData() ? TWAIN_STATE_DONE : TWAIN_STATE_CANCELED );
				
				mpImpTwain->Destroy();
				mpImpTwain = NULL;
                mpCurMgr = NULL;

				if( mxListener.is() )
					mxListener->disposing( lang::EventObject( mxMgr ) );
			}

			mxListener = NULL;
		}
		break;

		default:
		break;
	}

	return 0L;
}

// -----------
// - statics -
// -----------

static Twain aTwain;

// ------------------
// - ScannerManager -
// ------------------

void ScannerManager::AcquireData()
{
}

void ScannerManager::ReleaseData()
{
	if( mpData )
	{
		GlobalFree( (HGLOBAL)(long) mpData );
		mpData = NULL;
	}
}

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

AWT::Size ScannerManager::getSize() throw()
{
	AWT::Size	aRet;
	HGLOBAL		hDIB = (HGLOBAL)(long) mpData;

	if( hDIB )
	{
		BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) GlobalLock( hDIB );

		if( pBIH )
		{
			aRet.Width = pBIH->biWidth;
			aRet.Height = pBIH->biHeight; 
		}
		else
			aRet.Width = aRet.Height = 0;

		GlobalUnlock( hDIB );
	}
	else
		aRet.Width = aRet.Height = 0;

	return aRet;
}

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

SEQ( sal_Int8 ) ScannerManager::getDIB() throw()
{
	SEQ( sal_Int8 ) aRet;

	if( mpData )
	{
		HGLOBAL				hDIB = (HGLOBAL)(long) mpData;
		const sal_uInt32	nDIBSize = GlobalSize( hDIB );
		BITMAPINFOHEADER*	pBIH = (BITMAPINFOHEADER*) GlobalLock( hDIB );

		if( pBIH )
		{
			sal_uInt32	nColEntries;

			switch( pBIH->biBitCount )
			{
				case( 1 ):
				case( 4 ):
				case( 8 ):
					nColEntries = pBIH->biClrUsed ? pBIH->biClrUsed : ( 1 << pBIH->biBitCount );
				break;

				case( 24 ):
					nColEntries = pBIH->biClrUsed ? pBIH->biClrUsed : 0;
				break;

				case( 16 ):
				case( 32 ):
				{
					nColEntries = pBIH->biClrUsed;

					if( pBIH->biCompression == BI_BITFIELDS )
						nColEntries += 3;
				}
				break;

				default:
					nColEntries = 0;
				break;
			}

			aRet = SEQ( sal_Int8 )( sizeof( BITMAPFILEHEADER ) + nDIBSize );
			
			sal_Int8*		pBuf = aRet.getArray();
			SvMemoryStream* pMemStm = new SvMemoryStream( (char*) pBuf, sizeof( BITMAPFILEHEADER ), STREAM_WRITE );

			*pMemStm << 'B' << 'M' << (sal_uInt32) 0 << (sal_uInt32) 0;
			*pMemStm << (sal_uInt32) ( sizeof( BITMAPFILEHEADER ) + pBIH->biSize + ( nColEntries * sizeof( RGBQUAD ) ) );

			delete pMemStm;
			memcpy( pBuf + sizeof( BITMAPFILEHEADER ), pBIH, nDIBSize );
		}

		GlobalUnlock( hDIB );
		ReleaseData();
	}

	return aRet;
}

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

SEQ( ScannerContext ) SAL_CALL ScannerManager::getAvailableScanners() throw()
{
	vos::OGuard				aGuard( maProtector );
	SEQ( ScannerContext )	aRet( 1 );
	
	aRet.getArray()[0].ScannerName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TWAIN" ) );
	aRet.getArray()[0].InternalData = 0;

	return aRet;
}

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

sal_Bool SAL_CALL ScannerManager::configureScanner( ScannerContext& rContext ) 
    throw( ScannerException )
{
	vos::OGuard				            aGuard( maProtector );
	uno::Reference< XScannerManager >	xThis( this );

	if( rContext.InternalData != 0 || rContext.ScannerName != ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TWAIN" ) ) )
		throw ScannerException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scanner does not exist" ) ), xThis, ScanError_InvalidContext );

	ReleaseData();

	return aTwain.SelectSource( *this );
}

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

void SAL_CALL ScannerManager::startScan( const ScannerContext& rContext, const uno::Reference< lang::XEventListener >& rxListener ) 
    throw( ScannerException )
{
	vos::OGuard				            aGuard( maProtector );
	uno::Reference< XScannerManager >	xThis( this );

	if( rContext.InternalData != 0 || rContext.ScannerName != ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TWAIN" ) ) )
		throw ScannerException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scanner does not exist" ) ), xThis, ScanError_InvalidContext );

	ReleaseData();
	aTwain.PerformTransfer( *this, rxListener );
}

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

ScanError SAL_CALL ScannerManager::getError( const ScannerContext& rContext )
    throw( ScannerException )
{
	vos::OGuard				            aGuard( maProtector );
	uno::Reference< XScannerManager >	xThis( this );

	if( rContext.InternalData != 0 || rContext.ScannerName != ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TWAIN" ) ) )
		throw ScannerException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scanner does not exist" ) ), xThis, ScanError_InvalidContext );
    
	return( ( aTwain.GetState() == TWAIN_STATE_CANCELED ) ? ScanError_ScanCanceled : ScanError_ScanErrorNone );
}

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

uno::Reference< awt::XBitmap > SAL_CALL ScannerManager::getBitmap( const ScannerContext& /*rContext*/ ) 
    throw( ScannerException )
{
	vos::OGuard	aGuard( maProtector );
	return uno::Reference< awt::XBitmap >( this );
}
