/*************************************************************************
 *
 *  $RCSfile: filter.hxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: hr $ $Date: 2003/03/27 14:36:11 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FILTER_HXX
#define _FILTER_HXX

#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif
#ifndef _SV_GRAPH_HXX //autogen
#include <vcl/graph.hxx>
#endif
#ifndef _GEN_HXX //autogen
#include <tools/gen.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#include <vcl/svapp.hxx>
#include <vcl/field.hxx>
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

// -----------------------
// - GraphicFilter-Types -
// -----------------------

struct ImplDirEntryHelper
{
	static BOOL Exists( const INetURLObject& rObj );
	static void Kill( const String& rStr );
};

class Window;

#define OPT_FILTERSECTION			"Graphic"

#define GRFILTER_OK					0
#define GRFILTER_OPENERROR			1
#define GRFILTER_IOERROR			2
#define GRFILTER_FORMATERROR		3
#define GRFILTER_VERSIONERROR		4
#define GRFILTER_FILTERERROR		5
#define GRFILTER_ABORT				6
#define GRFILTER_TOOBIG				7

#define GRFILTER_FORMAT_NOTFOUND	((USHORT)0xFFFF)
#define GRFILTER_FORMAT_DONTKNOW	((USHORT)0xFFFF)

#define GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG       00000001
#define GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG  00000002

#define IMP_BMP					"SVBMP"
#define IMP_SVMETAFILE			"SVMETAFILE"
#define IMP_WMF					"SVWMF"
#define IMP_EMF					"SVEMF"
#define IMP_SVSGF				"SVSGF"
#define IMP_SVSGV				"SVSGV"
#define IMP_GIF					"SVIGIF"
#define IMP_PNG					"SVIPNG"
#define IMP_JPEG				"SVIJPEG"
#define IMP_XBM					"SVIXBM"
#define IMP_XPM					"SVIXPM"
#define EXP_BMP					"SVBMP"
#define EXP_SVMETAFILE			"SVMETAFILE"
#define EXP_WMF					"SVWMF"
#define EXP_EMF					"SVEMF"
#define EXP_JPEG				"SVEJPEG"
#define EXP_SVG					"SVESVG"

#define BMP_SHORTNAME			"BMP"
#define GIF_SHORTNAME			"GIF"
#define JPG_SHORTNAME			"JPG"
#define MET_SHORTNAME			"MET"
#define PCT_SHORTNAME			"PCT"
#define PNG_SHORTNAME			"PNG"
#define SVM_SHORTNAME			"SVM"
#define TIF_SHORTNAME			"TIF"
#define WMF_SHORTNAME			"WMF"
#define EMF_SHORTNAME			"EMF"

// ------------------------------------
// - Info-Klasse fuer alle von uns
//	unterstuetzten Grafik-Fileformate
// ------------------------------------

#define	GFF_NOT	( (USHORT)0x0000 )
#define	GFF_BMP	( (USHORT)0x0001 )
#define	GFF_GIF	( (USHORT)0x0002 )
#define	GFF_JPG	( (USHORT)0x0003 )
#define	GFF_PCD	( (USHORT)0x0004 )
#define	GFF_PCX	( (USHORT)0x0005 )
#define	GFF_PNG	( (USHORT)0x0006 )
#define	GFF_TIF	( (USHORT)0x0007 )
#define	GFF_XBM	( (USHORT)0x0008 )
#define	GFF_XPM	( (USHORT)0x0009 )
#define	GFF_PBM	( (USHORT)0x000a )
#define	GFF_PGM	( (USHORT)0x000b )
#define	GFF_PPM	( (USHORT)0x000c )
#define	GFF_RAS	( (USHORT)0x000d )
#define	GFF_TGA	( (USHORT)0x000e )
#define	GFF_PSD	( (USHORT)0x000f )
#define	GFF_EPS	( (USHORT)0x0010 )
#define	GFF_DXF	( (USHORT)0x00f1 )
#define	GFF_MET	( (USHORT)0x00f2 )
#define	GFF_PCT	( (USHORT)0x00f3 )
#define	GFF_SGF	( (USHORT)0x00f4 )
#define	GFF_SVM	( (USHORT)0x00f5 )
#define	GFF_WMF	( (USHORT)0x00f6 )
#define GFF_SGV	( (USHORT)0x00f7 )
#define	GFF_EMF	( (USHORT)0x00f8 )
#define	GFF_XXX	( (USHORT)0xffff )

// ---------------
// - RequestInfo -
// ---------------

struct RequestInfo
{
	BYTE*	pBuffer;
	ULONG	nRealBufferSize;
};

// ---------------------
// - GraphicDescriptor -
// ---------------------

class GraphicDescriptor
{
	SvStream*			pFileStm;
	Link				aReqLink;
	String				aPathExt;
	Size				aPixSize;
	Size				aLogSize;
	SvStream*			pMemStm;
	SvStream*			pBaseStm;
	ULONG				nStmPos;
	USHORT				nBitsPerPixel;
	USHORT				nPlanes;
	USHORT				nFormat;
	BOOL				bCompressed;
	BOOL				bDataReady;
	BOOL				bLinked;
	BOOL				bLinkChanged;
	BOOL				bWideSearch;
	BOOL				bBaseStm;
	long				nExtra1;
	long				nExtra2;

	void				ImpConstruct();

#if 0 // _SOLAR__PRIVATE

	BOOL				ImpDetectBMP( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectGIF( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectJPG( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPCD( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPCX( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPNG( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectTIF( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectXBM( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectXPM( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPBM( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPGM( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPPM( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectRAS( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectTGA( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPSD( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectEPS( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectDXF( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectMET( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectPCT( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectSGF( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectSVM( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectWMF( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectSGV( SvStream& rStm, BOOL bExtendedInfo );
	BOOL				ImpDetectEMF( SvStream& rStm, BOOL bExtendedInfo );

#endif

	GraphicDescriptor( const GraphicDescriptor& );
	GraphicDescriptor& operator=( const GraphicDescriptor& );

protected:

	BOOL				IsDataReady() const;
	BOOL				IsWideSearch() const;
	SvStream&			GetSearchStream() const;
	const String&		GetPathExtension() const;

public:

	// Default-Ctor, um anschliessend einen Link zu setzen, mit dem
	// die Daten vom Aufrufer im ::Detect() angefordert werden.
	// da einige Formate ( Mtf's ) keinen eindeutigen Header besitzen,
	// ist es sinnvoll den vollen Filenamen (inkl. Ext. ) mitanzugeben,
	// da so das Format ueber die Extension ermittelt werden kann
	GraphicDescriptor( const String* pPath = NULL );

	// Ctor, um einen Filenamen zu setzen. Es muss ::Detect() gerufen werden,
	// um das File zu identifizieren;
	// wenn das File keinen eindeutigen Header besitzt ( Mtf's ) wird das
	// Format anhand der Extension bestimmt
	GraphicDescriptor( const INetURLObject& rPath );

	// Ctor, um einen Stream zu setzen. Es muss ::Detect() gerufen werden,
	// um das File zu identifizieren;
	// da einige Formate ( Mtf's ) keinen eindeutigen Header besitzen,
	// ist es sinnvoll den Filenamen (inkl. Ext. ) mitanzugeben,
	// da so das Format ueber die Extension ermittelt werden kann
	GraphicDescriptor( SvStream& rInStream, const String* pPath = NULL );

	// Dtor
	~GraphicDescriptor();

	// Startet die Detektion;
	// bei bExtendedInfo == TRUE werden soweit wie moeglich
	// Daten aus dem jeweiligen FileHeader ermittelt
	// ( Groesse, Farbtiefe usw. )
	virtual BOOL	Detect( BOOL bExtendedInfo = FALSE );

	// liefert das Fileformat nach erfolgreicher  Detektion zurueck;
	// wenn kein Format erkannt wurde, ist das Formart GFF_NOT
	USHORT			GetFileFormat() const { return nFormat; }

	// liefert die Pixel-Bildgroesse oder 0-Size zurueck
	const Size&		GetSizePixel() const { return (Size&) aPixSize; }

	// liefert die logische Bildgroesse in 1/100mm oder 0-Size zurueck
	const Size&		GetSize_100TH_MM() const { return (Size&) aLogSize; }

	// liefert die Bits/Pixel oder 0 zurueck
	USHORT			GetBitsPerPixel() const { return nBitsPerPixel; }

	// liefert die Anzahl der Planes oder 0 zurueck
	USHORT			GetPlanes() const { return nPlanes; }

	// zeigt an, ob das Bild evtl. komprimiert (wie auch immer) ist
	BOOL			IsCompressed() const { return bCompressed; }

	// setzt den LinkHdl zum Setzen der Bytes;
	// der Handler muss einen Pointer auf die RequestInfo-Struktur
	// zurueckgeben; die Anzahl der minimal zur Verfuegung zu stellenden
	// Daten muss im Handler ueber ::GetRequestedByteCount() erfragt werden;
	// die tatsaechlich zur Verfuegung gestellte BYTE-Anzahl
	// wird in der RequestInfo-Struktur gesetzt
	void			SetRequestHdl( const Link& rRequestHdl );

	// gibt den LinkHdl zum Setzen der Bytes zurueck
	const Link&		GetRequestHdl() const { return aReqLink; }

	// muss im ReqHdl gerufen werden, um zu erfahren, wieviele
	// Bytes _mindestens_ bereitgestellt werden muessen
	ULONG			GetRequestedByteCount() const;

	// gibt die Filternummer des Filters zurueck,
	// der im GraphicFilter zum Lesen dieses Formats
	// benoetigt wird
	static String GetImportFormatShortName( sal_uInt16 nFormat );
};

// -----------------
// - GraphicFilter -
// -----------------

struct FilterErrorEx
{
	ULONG	nFilterError;
	ULONG	nStreamError;
	long	nDummy1;
	long	nDummy2;
	long	nDummy3;
	long	nDummy4;

			FilterErrorEx() : nFilterError( 0UL ), nStreamError( 0UL ) {}
};

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

struct ConvertData;
class FilterConfigCache;
class GraphicFilter
{
    friend class SvFilterOptionsDialog;

private:

	void			ImplInit();
	ULONG			ImplSetError( ULONG nError, const SvStream* pStm = NULL );
	sal_uInt16		ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat );

					DECL_LINK( FilterCallback, ConvertData* pData );

protected:

	Link				aStartFilterHdlLink;
	Link				aEndFilterHdlLink;
	Link				aUpdatePercentHdlLink;
	Link				aErrorHdlLink;
	String				aFilterPath;
	FilterConfigCache*	pConfig;
	FilterErrorEx*		pErrorEx;
	sal_uInt16			nPercent;
	sal_Bool			bAbort;
	sal_Bool			bUseConfig;

	sal_Bool			bDummy1;
	sal_Bool			bDummy2;
	sal_Bool			bDummy3;
	sal_Bool			bDummy4;
	long				nDummy1;
	long				nDummy2;
	void*				pDummy1;
	void*				pDummy2;

public:

					GraphicFilter( sal_Bool bUseConfig = sal_True );
					~GraphicFilter();

	void			SetFilterPath( const String& rFilterPath ) { aFilterPath = rFilterPath; };

	USHORT          GetImportFormatCount();
	USHORT          GetImportFormatNumber( const String& rFormatName );
	USHORT			GetImportFormatNumberForMediaType( const String& rMediaType );
	USHORT          GetImportFormatNumberForShortName( const String& rShortName );
	sal_uInt16		GetImportFormatNumberForTypeName( const String& rType );
	String          GetImportFormatName( USHORT nFormat );
	String          GetImportFormatTypeName( USHORT nFormat );
	String          GetImportFormatMediaType( USHORT nFormat );
	String          GetImportFormatShortName( USHORT nFormat );
	String			GetImportOSFileType( USHORT nFormat );
	String			GetImportWildcard( USHORT nFormat, sal_Int32 nEntry = 0 );
	BOOL			IsImportPixelFormat( USHORT nFormat );

	USHORT          GetExportFormatCount();
	USHORT          GetExportFormatNumber( const String& rFormatName );
	USHORT          GetExportFormatNumberForMediaType( const String& rShortName );
	USHORT          GetExportFormatNumberForShortName( const String& rShortName );
	sal_uInt16		GetExportFormatNumberForTypeName( const String& rType );
	String          GetExportFormatName( USHORT nFormat );
	String          GetExportFormatTypeName( USHORT nFormat );
	String          GetExportFormatMediaType( USHORT nFormat );
	String          GetExportFormatShortName( USHORT nFormat );
	String			GetExportOSFileType( USHORT nFormat );
	String			GetExportWildcard( USHORT nFormat, sal_Int32 nEntry = 0 );
	BOOL			IsExportPixelFormat( USHORT nFormat );

	BOOL			HasImportDialog( USHORT nFormat );
	BOOL			DoImportDialog( Window* pWindow, USHORT nFormat );

	BOOL			HasExportDialog( USHORT nFormat );
	BOOL			DoExportDialog( Window* pWindow, USHORT nFormat );
	BOOL			DoExportDialog( Window* pWindow, USHORT nFormat, FieldUnit eFieldUnit );

	USHORT			ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
									USHORT nFormat = GRFILTER_FORMAT_DONTKNOW,
										sal_Bool bIgnoreOptions = sal_True,
										const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL );
	USHORT			ExportGraphic( const Graphic& rGraphic, const String& rPath,
									SvStream& rOStm, USHORT nFormat = GRFILTER_FORMAT_DONTKNOW,
										sal_Bool bIgnoreOptions = sal_True,
										const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL );

	USHORT          CanImportGraphic( const INetURLObject& rPath,
									  USHORT nFormat = GRFILTER_FORMAT_DONTKNOW,
									  USHORT * pDeterminedFormat = NULL);

	USHORT          ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
								   USHORT nFormat = GRFILTER_FORMAT_DONTKNOW,
								   USHORT * pDeterminedFormat = NULL, sal_uInt32 nImportFlags = 0 );

	USHORT          CanImportGraphic( const String& rPath, SvStream& rStream,
									  USHORT nFormat = GRFILTER_FORMAT_DONTKNOW,
									  USHORT * pDeterminedFormat = NULL);

	USHORT          ImportGraphic( Graphic& rGraphic, const String& rPath,
								   SvStream& rStream,
								   USHORT nFormat = GRFILTER_FORMAT_DONTKNOW,
								   USHORT * pDeterminedFormat = NULL, sal_uInt32 nImportFlags = 0 );

	BOOL            Setup( USHORT nFormat );

	USHORT          GetPercent() const { return nPercent; }
	void            Abort() { bAbort = TRUE; }

	void            SetStartFilterHdl( const Link& rLink ) { aStartFilterHdlLink = rLink; }
	const Link&     GetStartFilterHdl() const { return aStartFilterHdlLink; }
	void            SetEndFilterHdl( const Link& rLink ) { aEndFilterHdlLink = rLink; }
	const Link&     GetEndFilterHdl() const { return aEndFilterHdlLink; }

	void            SetUpdatePercentHdl( const Link& rLink ) { aUpdatePercentHdlLink = rLink; }
	const Link&     GetUpdatePercentHdl() const { return aUpdatePercentHdlLink; }
	void			CallUpdatePercentHdl( const USHORT _nPercent ) { nPercent = _nPercent, aUpdatePercentHdlLink.Call( this ); }

	void            SetFilterErrorHdl( const Link& rLink ) { aErrorHdlLink = rLink; }
	const Link&     GetFilterErrorHdl() const { return aErrorHdlLink; }

	const FilterErrorEx&	GetLastError() const;
	void					ResetLastError();

    const Link      GetFilterCallback() const;
};

// ------------------------------------
// - Windows Metafile Lesen/Schreiben -
// ------------------------------------

BOOL ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF );
BOOL WriteWindowMetafile( SvStream& rStream, const GDIMetaFile& rMTF );
BOOL WriteWindowMetafileBits( SvStream& rStream, const GDIMetaFile& rMTF );

#endif  //_FILTER_HXX
