// GflAXObj.h : Declaration of the CGflAX

#ifndef __GFLAXOBJ_H_
#define __GFLAXOBJ_H_

#include "Resource.h"
#include <comdef.h>
#include <libgfl.h>
#include <libgfle.h>

#ifdef _UNICODE
#define _gflLoadBitmap          gflLoadBitmapW
#define _gflGetFileInformation  gflGetFileInformationW
#define _gflLoadThumbnail       gflLoadThumbnailW
#define _gflSaveBitmap          gflSaveBitmapW
#define _gflAddText             gflAddTextW
#else
#define _gflLoadBitmap          gflLoadBitmap
#define _gflGetFileInformation  gflGetFileInformation
#define _gflLoadThumbnail       gflLoadThumbnail
#define _gflSaveBitmap          gflSaveBitmap
#define _gflAddText             gflAddText
#endif


class GFL_MERGE {
    public:
        OLECHAR filename[MAX_PATH];
        long opacity;
        long x, y;
    };

template <class D> class GFL_ARRAY {
    public:
        GFL_ARRAY() :
            array(NULL)
        {
            count = allocatedCount = 0;
        }

        ~GFL_ARRAY()
        {
            clear();
        }

        D & push(void)
        {
            if (count+1 >= allocatedCount)
            {
                allocatedCount += 32;
                if (array)
                    array = (D *)realloc(array, allocatedCount*sizeof(D));
                else
                    array = (D *)malloc(allocatedCount*sizeof(D));
            }
            return array[count++];
        }

        D * getPtr(void)
        {
            return array;
        }

        long getCount(void)
        {
            return count;
        }

        const D & operator[](int i)
        {
            return array[i];
        }

        void clear(void)
        {
            if (array)
                free(array);
            array = NULL;
            count = allocatedCount = 0;
        }

    private:
        long count, allocatedCount;
        D * array;
    };

/////////////////////////////////////////////////////////////////////////////
// CGflAX
class ATL_NO_VTABLE CGflAX :
    public CComObjectRootEx<CComGlobalsThreadModel>,
    public CComCoClass<CGflAX, &CLSID_GflAx>,
    public ISupportErrorInfo,
    public IDispatchImpl<IGflAx, &IID_IGflAx, &LIBID_GflAx>
{
public:
    CGflAX();
    virtual ~CGflAX();

DECLARE_REGISTRY_RESOURCEID(IDR_GFLAXOBJ)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CGflAX)
    COM_INTERFACE_ENTRY(IGflAx)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()

    // ISupportsErrorInfo
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);

public:
    // IGflAx
    STDMETHOD(get_OriginalXdpi)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_OriginalYdpi)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_UpdateEmbeddedThumbnail)(/*[in]*/ BOOL newVal);
    STDMETHOD(ImportFromClipboard)();
    STDMETHOD(SetMetadataRefFile)(BSTR filename);
    STDMETHOD(get_OriginalHeight)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_OriginalWidth)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_UseEmbeddedThumbnail)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_UseDPIFromEXIF)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_UseDPIFromEXIF)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_ScaleToGrey)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_ScaleToGrey)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_Zoom)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_Zoom)(/*[in]*/ long newVal);
#ifdef __TWAIN_SUPPORT__
    STDMETHOD(Acquire)();
    STDMETHOD(get_UseTwainInterface)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_UseTwainInterface)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_TwainAppName)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(put_TwainAppName)(/*[in]*/ BSTR newVal);
    STDMETHOD(get_TwainConnected)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(get_TwainDeviceName)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_CurrentTwainDevice)(/*[out, retval]*/ long *pVal);
    STDMETHOD(SelectTwainDevice)();
#endif
    STDMETHOD(GetTextHeight)(BSTR string, long * pVal);
    STDMETHOD(GetTextWidth)(BSTR string, long * pVal);
    STDMETHOD(IPTCSuppCatDelete)(long index);
    STDMETHOD(IPTCSuppCatClear)();
    STDMETHOD(get_IPTCSuppCat)(long index, /*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCSuppCatCount)(/*[out, retval]*/ long *pVal);
    STDMETHOD(IPTCKeywordsDelete)(long index);
    STDMETHOD(IPTCKeywordsClear)();
    STDMETHOD(get_HasIPTC)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(get_IPTCKeywords)(long index, /*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCKeywordsCount)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_IPTCDateCreated)(/*[out, retval]*/ DATE *pVal);
    STDMETHOD(get_IPTCCopyrightNotice)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCOTR)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCCountryName)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCProvinceState)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCCity)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCObjectName)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCSource)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCCredit)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCBylineTitle)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCByline)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCCategory)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCSpecialinstructions)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCHeadline)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCCaptionWriter)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_IPTCCaption)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(put_IPTCDateCreated)(/*[out, retval]*/ DATE pVal);
    STDMETHOD(put_IPTCCopyrightNotice)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCOTR)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCCountryName)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCProvinceState)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCCity)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCObjectName)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCSource)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCCredit)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCBylineTitle)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCByline)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCCategory)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCSpecialinstructions)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCHeadline)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCCaptionWriter)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_IPTCCaption)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(put_Ydpi)(/*[in]*/ short newVal);
    STDMETHOD(put_Xdpi)(/*[in]*/ short newVal);
    STDMETHOD(IPTCSuppCatAdd)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(IPTCKeywordsAdd)(/*[out, retval]*/ BSTR pVal);
    STDMETHOD(EndPaint)();
    STDMETHOD(BeginPaint)();
    STDMETHOD(DrawImage)(BSTR filename, long x, long y);
    STDMETHOD(SetPicture)(IPicture * pict);
    STDMETHOD(put_SaveKeepMetadata)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_EXIFDateTaken)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_EXIFGetByID)(unsigned long id, /*[out, retval]*/BSTR *pVal);
    STDMETHOD(ExportToClipboard)();
    STDMETHOD(get_MaskColor)(/*[out, retval]*/ OLE_COLOR *pVal);
    STDMETHOD(put_MaskColor)(/*[in]*/ OLE_COLOR newVal);
    STDMETHOD(get_BackColor)(/*[out, retval]*/ OLE_COLOR *pVal);
    STDMETHOD(put_BackColor)(/*[in]*/ OLE_COLOR newVal);
    STDMETHOD(get_UseTransparency)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_UseTransparency)(/*[in]*/ BOOL newVal);
    STDMETHOD(GetPicture)(/*[out, retval]*/ IPicture **);
    STDMETHOD(PreviousPage)(/*[out, retval]*/ long *);
    STDMETHOD(NextPage)(/*[out, retval]*/ long *);
    STDMETHOD(Clone)(/*[out, retval]*/ IGflAx **ppImage);
    STDMETHOD(get_NumberOfColorUsed)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_SaveFormatDescription)(/*[out, retval]*/ VARIANT *pVal);
    STDMETHOD(put_SaveFormatName)(/*[in]*/ BSTR newVal);
    STDMETHOD(LoadThumbnail)(BSTR filename, long width, long height);
    STDMETHOD(EmbossMore)();
    STDMETHOD(Emboss)();
    STDMETHOD(EdgeDetectHeavy)();
    STDMETHOD(EdgeDetectMedium)();
    STDMETHOD(EdgeDetectLight)();
    STDMETHOD(FocusRestoration)();
    STDMETHOD(EnhanceFocus)();
    STDMETHOD(EnhanceDetail)();
    STDMETHOD(Sharpen)(long value);
    STDMETHOD(MedianCross)(long value);
    STDMETHOD(MedianBox)(long value);
    STDMETHOD(Minimum)(long value);
    STDMETHOD(Maximum)(long value);
    STDMETHOD(GaussianBlur)(long value);
    STDMETHOD(Blur)(long value);
    STDMETHOD(Soften)(long value);
    STDMETHOD(Average)(long value);
    STDMETHOD(EqualizeOnLuminance)();
    STDMETHOD(Equalize)();
    STDMETHOD(Normalize)();
    STDMETHOD(LogCorrection)();
    STDMETHOD(Contrast)(long value);
    STDMETHOD(Brightness)(long value);
    STDMETHOD(Negative)();
    STDMETHOD(MergeClear)();
    STDMETHOD(Merge)();
    STDMETHOD(MergeAddFile)(BSTR filename, long opacity, long x, long y);
    STDMETHOD(FreeVertex)();
    STDMETHOD(get_LineColor)(/*[out, retval]*/ OLE_COLOR *pVal);
    STDMETHOD(put_LineColor)(/*[in]*/ OLE_COLOR newVal);
    STDMETHOD(get_FillColor)(/*[out, retval]*/ OLE_COLOR *pVal);
    STDMETHOD(put_FillColor)(/*[in]*/ OLE_COLOR newVal);
    STDMETHOD(get_LineWidth)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_LineWidth)(/*[in]*/ long newVal);
    STDMETHOD(DrawPolyline)(void);
    STDMETHOD(DrawPolygon)(void);
    STDMETHOD(AddVertex)(long x, long y);
    STDMETHOD(DrawFillCircle)(long x, long y, long radius);
    STDMETHOD(DrawCircle)(long x, long y, long radius);
    STDMETHOD(DrawFillRectangle)(long x, long y, long width, long height);
    STDMETHOD(DrawRectangle)(long x, long y, long width, long height);
    STDMETHOD(DrawLine)(long x0, long y0, long x1, long y1);
    STDMETHOD(DrawPoint)(long x, long y);
    STDMETHOD(FreeBitmap)();
    STDMETHOD(GetBlob)(VARIANT newVal);
    STDMETHOD(ReceiveBinary)(VARIANT newVal);
    STDMETHOD(SetBlob)(/*[out, retval]*/ SAFEARRAY **pVal);
    STDMETHOD(SendBinary)(/*[out, retval]*/ SAFEARRAY **pVal);
    STDMETHOD(get_NumberOfPages)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_Page)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_Page)(/*[in]*/ long newVal);
    STDMETHOD(TextOut)(BSTR string, long x, long y, OLE_COLOR color);
    STDMETHOD(get_FontOrientation)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_FontOrientation)(/*[in]*/ long newVal);
    STDMETHOD(get_FontSize)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_FontSize)(/*[in]*/ long newVal);
    STDMETHOD(get_FontName)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(put_FontName)(/*[in]*/ BSTR newVal);
    STDMETHOD(get_FontUnderline)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_FontUnderline)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_FontAntialias)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_FontAntialias)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_FontStrikeOut)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_FontStrikeOut)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_FontBold)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_FontBold)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_FontItalic)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_FontItalic)(/*[in]*/ BOOL newVal);
    STDMETHOD(Sepia)(/*[optional]*/ long percent, /*[optional]*/ OLE_COLOR color);
    STDMETHOD(Saturation)(long saturation);
    STDMETHOD(Lightness)(long lightness);
    STDMETHOD(Hue)(long value);
    STDMETHOD(AdjustHLS)(long hue, long lightness, long saturation);
    STDMETHOD(Adjust)(long brightness, long contrast, double gamma);
    STDMETHOD(Balance)(OLE_COLOR color);
    STDMETHOD(Gamma)(double gamma);
    STDMETHOD(ReplaceColor)(OLE_COLOR color, OLE_COLOR new_color, /*[optional]*/ long tolerance);
    STDMETHOD(ChangeColorDepth)(AX_Mode mode, AX_Dither dither, AX_Palette palette);
    STDMETHOD(SwapColors)(AX_SwapModel model);
    STDMETHOD(Rotate)(double angle, OLE_COLOR back_color);
    STDMETHOD(GetColorAt)(long x, long y, OLE_COLOR * color);
    STDMETHOD(ResizeCanvas)(long width, long height, AX_CanvasMode canvas_mode, OLE_COLOR color);
    STDMETHOD(AutoCrop)(OLE_COLOR color, long tolerance);
    STDMETHOD(Crop)(long x, long y, long width, long height);
    STDMETHOD(Resize)(long width, long height);
    STDMETHOD(FlipHorizontal)();
    STDMETHOD(FlipVertical)();
    STDMETHOD(get_OriginalSize)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_ColorModel)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(get_BitmapType)(/*[out, retval]*/ AX_Type *pVal);
    STDMETHOD(get_NumberOfImages)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_EnableLZW)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_EnableLZW)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_Ydpi)(/*[out, retval]*/ short *pVal);
    STDMETHOD(get_Xdpi)(/*[out, retval]*/ short *pVal);
    STDMETHOD(get_Height)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_Width)(/*[out, retval]*/ long *pVal);
    STDMETHOD(get_EpsDpi)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_EpsDpi)(/*[in]*/ long newVal);
    STDMETHOD(get_EpsHeight)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_EpsHeight)(/*[in]*/ long newVal);
    STDMETHOD(get_EpsWidth)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_EpsWidth)(/*[in]*/ long newVal);
    STDMETHOD(get_SavePNGCompression)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_SavePNGCompression)(/*[in]*/ long newVal);
    STDMETHOD(get_SaveJPEGProgressive)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_SaveJPEGProgressive)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_SaveGIFInterlaced)(/*[out, retval]*/ BOOL *pVal);
    STDMETHOD(put_SaveGIFInterlaced)(/*[in]*/ BOOL newVal);
    STDMETHOD(get_SaveJPEGQuality)(/*[out, retval]*/ long *pVal);
    STDMETHOD(put_SaveJPEGQuality)(/*[in]*/ long newVal);
    STDMETHOD(put_SetPluginsPathname)(/*[in]*/ BSTR newVal);
    STDMETHOD(get_SaveFormat)(/*[out, retval]*/ AX_SaveFormats *pVal);
    STDMETHOD(put_SaveFormat)(/*[in]*/ AX_SaveFormats newVal);
    STDMETHOD(get_SaveCompression)(/*[out, retval]*/ AX_SaveCompressions *pVal);
    STDMETHOD(put_SaveCompression)(/*[in]*/ AX_SaveCompressions newVal);
    STDMETHOD(SaveBitmap)(BSTR filename);
    STDMETHOD(ReloadBitmap)();
    STDMETHOD(NewBitmap)(long width, long height, OLE_COLOR back_color);
    STDMETHOD(LoadBitmap)(BSTR filename);
    STDMETHOD(get_Language)(/*[out, retval]*/ AX_Language *pVal);
    STDMETHOD(put_Language)(/*[in]*/ AX_Language newVal);
    STDMETHOD(About)(VARIANT *);
private:
    GFL_UINT8 * UploadFilename(BSTR url, DWORD * length);
    BOOL m_useEXIFDPI;
    long GetCompression(long index);
    void GetTextExtent(BSTR str, SIZE * size);
    void CGflAX::GetIPTC(GFL_UINT32 id, BSTR *);
    void SetIPTC(int id, BSTR value);
    void SetIPTC(int id, const char* value);
    BOOL m_keepMetadata;
    BOOL m_useEmbeddedThumbnail;
    void FreeCurrentBitmap(void);
    const char * GetErrorString(GFL_ERROR error);
    BOOL IsImageLoaded(void);
    GFL_COLOR OLEToColor(OLE_COLOR color);
    OLE_COLOR ColorToOLE(GFL_COLOR & color);

    GFL_BOOL m_enableLZW;
    AX_Language m_errorLanguage;
    BOOL m_updateEmbeddedThumbnail;

    GFL_INT32 m_pageIndex;
    AX_SaveCompressions m_saveCompression;
    GFL_UINT32 m_JPEGQuality;
    GFL_BOOL m_JPEGProgressive;
    GFL_BOOL m_GIFInterlaced;
    GFL_INT16 m_PNGCompression;
    GFL_INT32 m_saveFormatIndex;
    long m_epsWidth;
    long m_epsHeight;
    long m_epsDpi;

    HBITMAP m_hBitmap;
    LPVOID m_pBits;

    // Text
    GFL_BOOL m_fontBold;
    GFL_BOOL m_fontItalic;
    GFL_BOOL m_fontStrikeOut;
    GFL_BOOL m_fontUnderline;
    GFL_BOOL m_fontAntiAlias;
    OLECHAR m_fontName[LF_FACESIZE];
    long m_fontSize;
    long m_fontOrientation;

    // Drawing
    OLE_COLOR m_fillColor;
    OLE_COLOR m_lineColor;
    long m_lineWidth;
    GFL_ARRAY<GFL_POINT> m_vertexArray;
    GFL_ARRAY<GFL_MERGE> m_mergeArray;

    BOOL m_useTransparency;
    OLE_COLOR m_maskColor;
    OLE_COLOR m_backColor;
    INT m_currentZoom;
    BOOL m_scaleToGrey;

    GFL_BITMAP * m_bitmap;
    GFL_FILE_INFORMATION m_fileInformations;
    OLECHAR m_bitmapFilename[MAX_PATH];
};

OBJECT_ENTRY_AUTO(__uuidof(GflAx), CGflAX)

#endif // __GFLAXOBJ_H_
