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

#include <vcl/canvastools.hxx>

#include <vcl/bitmap.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <tools/diagnose_ex.h>

#include "dx_impltools.hxx"
#include <basegfx/numeric/ftools.hxx>

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/rendering/XIntegerBitmap.hpp>

#include <boost/scoped_array.hpp>

#include "dx_vcltools.hxx"

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

namespace dxcanvas
{
    namespace tools
    {
        namespace
        {
            /// Calc number of colors in given BitmapInfoHeader
			sal_Int32 calcDIBColorCount( const BITMAPINFOHEADER& rBIH )
            {
                if( rBIH.biSize != sizeof( BITMAPCOREHEADER ) )
                {
                    if( rBIH.biBitCount <= 8 )
                    {
                        if( rBIH.biClrUsed )
                            return rBIH.biClrUsed;
                        else
                            return 1L << rBIH.biBitCount;
                    }
                }
                else 
                {
                    BITMAPCOREHEADER* pCoreHeader = (BITMAPCOREHEADER*)&rBIH;

                    if( pCoreHeader->bcBitCount <= 8 )
                        return 1L << pCoreHeader->bcBitCount;
                }
                
                return 0; // nothing known
            }

            /// Draw DI bits to given Graphics
            bool drawDIBits( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics, 
                             const void* 									 hDIB )
            {
                bool 			bRet( false );
                BitmapSharedPtr pBitmap;

                const BITMAPINFO* pBI = (BITMAPINFO*)GlobalLock( (HGLOBAL)hDIB );

                if( pBI )
                {
                    const BITMAPINFOHEADER*	pBIH = (BITMAPINFOHEADER*)pBI;
                    const BYTE*				pBits = (BYTE*) pBI + *(DWORD*)pBI +
                        calcDIBColorCount( *pBIH ) * sizeof( RGBQUAD );

                    // forward to outsourced GDI+ rendering method
                    // (header clashes)
                    bRet = tools::drawDIBits( rGraphics, *pBI, (void*)pBits );

                    GlobalUnlock( (HGLOBAL)hDIB );
                }

                return bRet;
            }

            /** Draw VCL bitmap to given Graphics

            	@param rBmp
                Reference to bitmap. Might get modified, in such a way
                that it will hold a DIB after a successful function call.
             */
            bool drawVCLBitmap( const ::boost::shared_ptr< Gdiplus::Graphics >&	rGraphics, 
                                ::Bitmap& 										rBmp )
            {
                BitmapSystemData aBmpSysData;

                if( !rBmp.GetSystemData( aBmpSysData ) ||
                    !aBmpSysData.pDIB )
                {
                    // first of all, ensure that Bitmap contains a DIB, by
                    // acquiring a read access
                    BitmapReadAccess* pReadAcc = rBmp.AcquireReadAccess();

                    // TODO(P2): Acquiring a read access can actually
                    // force a read from VRAM, thus, avoiding this
                    // step somehow will increase performance
                    // here.
                    if( pReadAcc )
                    {
                        // try again: now, WinSalBitmap must have
                        // generated a DIB
                        if( rBmp.GetSystemData( aBmpSysData ) &&
                            aBmpSysData.pDIB )
                        {
                            return drawDIBits( rGraphics,
                                               aBmpSysData.pDIB );
                        }

                        rBmp.ReleaseAccess( pReadAcc );
                    }
                }
                else
                {
                    return drawDIBits( rGraphics,
                                       aBmpSysData.pDIB );
                }

                // failed to generate DIBits from vcl bitmap
                return false;
            }

            /** Create a chunk of raw RGBA data GDI+ Bitmap from VCL BbitmapEX
             */
            RawRGBABitmap bitmapFromVCLBitmapEx( const ::BitmapEx& rBmpEx )
            {
                // TODO(P2): Avoid temporary bitmap generation, maybe
                // even ensure that created DIBs are copied back to
                // BmpEx (currently, every AcquireReadAccess() will
                // make the local bitmap copy unique, effectively
                // duplicating the memory used)

                ENSURE_OR_THROW( rBmpEx.IsTransparent(),
                                  "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                  "BmpEx not transparent" );

                // convert transparent bitmap to 32bit RGBA
                // ========================================

                const ::Size aBmpSize( rBmpEx.GetSizePixel() );

                RawRGBABitmap aBmpData;
                aBmpData.mnWidth	 = aBmpSize.Width();
                aBmpData.mnHeight	 = aBmpSize.Height();
                aBmpData.mpBitmapData.reset( new sal_uInt8[ 4*aBmpData.mnWidth*aBmpData.mnHeight ] );

                Bitmap aBitmap( rBmpEx.GetBitmap() );

                ScopedBitmapReadAccess pReadAccess( aBitmap.AcquireReadAccess(),
                                                    aBitmap );
                    
                const sal_Int32 nWidth( aBmpSize.Width() );
                const sal_Int32 nHeight( aBmpSize.Height() );

                ENSURE_OR_THROW( pReadAccess.get() != NULL,
                                  "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                  "Unable to acquire read acces to bitmap" );

                if( rBmpEx.IsAlpha() )
                {
                    Bitmap aAlpha( rBmpEx.GetAlpha().GetBitmap() );

                    ScopedBitmapReadAccess pAlphaReadAccess( aAlpha.AcquireReadAccess(),
                                                             aAlpha );

                    // By convention, the access buffer always has
                    // one of the following formats:
                    // 
                    //    BMP_FORMAT_1BIT_MSB_PAL
                    //	  BMP_FORMAT_4BIT_MSN_PAL
                    //	  BMP_FORMAT_8BIT_PAL
                    //	  BMP_FORMAT_16BIT_TC_LSB_MASK
                    //	  BMP_FORMAT_24BIT_TC_BGR
                    //	  BMP_FORMAT_32BIT_TC_MASK
                    // 
                    // and is always BMP_FORMAT_BOTTOM_UP
                    //
                    // This is the way
                    // WinSalBitmap::AcquireBuffer() sets up the
                    // buffer

                    ENSURE_OR_THROW( pAlphaReadAccess.get() != NULL,
                                      "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                      "Unable to acquire read acces to alpha" );

                    ENSURE_OR_THROW( pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
                                      pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
                                      "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                      "Unsupported alpha scanline format" );

                    BitmapColor		aCol;
                    const sal_Int32 nWidth( aBmpSize.Width() );
                    const sal_Int32 nHeight( aBmpSize.Height() );
                    sal_uInt8* 		pCurrOutput( aBmpData.mpBitmapData.get() );
                    int 			x, y;

                    for( y=0; y<nHeight; ++y )
                    {
                        switch( pReadAccess->GetScanlineFormat() )
                        {
                            case BMP_FORMAT_8BIT_PAL:
                            {
                                Scanline pScan  = pReadAccess->GetScanline( y );
                                Scanline pAScan = pAlphaReadAccess->GetScanline( y );

                                for( x=0; x<nWidth; ++x )
                                {
                                    aCol = pReadAccess->GetPaletteColor( *pScan++ );

                                    *pCurrOutput++ = aCol.GetBlue();
                                    *pCurrOutput++ = aCol.GetGreen();
                                    *pCurrOutput++ = aCol.GetRed();

                                    // out notion of alpha is
                                    // different from the rest
                                    // of the world's
                                    *pCurrOutput++ = 255 - (BYTE)*pAScan++;
                                }
                            }
                            break;

                            case BMP_FORMAT_24BIT_TC_BGR:
                            {
                                Scanline pScan  = pReadAccess->GetScanline( y );
                                Scanline pAScan = pAlphaReadAccess->GetScanline( y );

                                for( x=0; x<nWidth; ++x )
                                {
                                    // store as RGBA
                                    *pCurrOutput++ = *pScan++;
                                    *pCurrOutput++ = *pScan++;
                                    *pCurrOutput++ = *pScan++;

                                    // out notion of alpha is
                                    // different from the rest
                                    // of the world's
                                    *pCurrOutput++ = 255 - (BYTE)*pAScan++;
                                }
                            }
                            break;

                            // TODO(P2): Might be advantageous
                            // to hand-formulate the following
                            // formats, too.
                            case BMP_FORMAT_1BIT_MSB_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_4BIT_MSN_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_16BIT_TC_LSB_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_MASK:
                            {
                                Scanline pAScan = pAlphaReadAccess->GetScanline( y );

                                // using fallback for those
                                // seldom formats
                                for( x=0; x<nWidth; ++x )
                                {
                                    // yes. x and y are swapped on Get/SetPixel
                                    aCol = pReadAccess->GetColor(y,x);

                                    *pCurrOutput++ = aCol.GetBlue();
                                    *pCurrOutput++ = aCol.GetGreen();
                                    *pCurrOutput++ = aCol.GetRed();

                                    // out notion of alpha is
                                    // different from the rest
                                    // of the world's
                                    *pCurrOutput++ = 255 - (BYTE)*pAScan++;
                                }
                            }
                            break;

                            case BMP_FORMAT_1BIT_LSB_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_4BIT_LSN_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_8BIT_TC_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_24BIT_TC_RGB:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_24BIT_TC_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_16BIT_TC_MSB_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_ABGR:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_ARGB:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_BGRA:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_RGBA:
                                // FALLTHROUGH intended
                            default:
                                ENSURE_OR_THROW( false,
                                                  "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                                  "Unexpected scanline format - has "
                                                  "WinSalBitmap::AcquireBuffer() changed?" );
                        }
                    }
                }
                else
                {
                    Bitmap aMask( rBmpEx.GetMask() );

                    ScopedBitmapReadAccess pMaskReadAccess( aMask.AcquireReadAccess(),
                                                            aMask );

                    // By convention, the access buffer always has
                    // one of the following formats:
                    // 
                    //    BMP_FORMAT_1BIT_MSB_PAL
                    //	  BMP_FORMAT_4BIT_MSN_PAL
                    //	  BMP_FORMAT_8BIT_PAL
                    //	  BMP_FORMAT_16BIT_TC_LSB_MASK
                    //	  BMP_FORMAT_24BIT_TC_BGR
                    //	  BMP_FORMAT_32BIT_TC_MASK
                    // 
                    // and is always BMP_FORMAT_BOTTOM_UP
                    //
                    // This is the way
                    // WinSalBitmap::AcquireBuffer() sets up the
                    // buffer

                    ENSURE_OR_THROW( pMaskReadAccess.get() != NULL,
                                      "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                      "Unable to acquire read acces to mask" );

                    ENSURE_OR_THROW( pMaskReadAccess->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL,
                                      "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                      "Unsupported mask scanline format" );

                    BitmapColor		aCol;
                    int 			nCurrBit;
                    const int		nMask( 1L );
                    const int 		nInitialBit(7);
                    sal_uInt8* 		pCurrOutput( aBmpData.mpBitmapData.get() );
                    int 			x, y;

                    // mapping table, to get from mask index color to
                    // alpha value (which depends on the mask's palette)
                    sal_uInt8 aColorMap[2];

                    const BitmapColor& rCol0( pMaskReadAccess->GetPaletteColor( 0 ) );
                    const BitmapColor& rCol1( pMaskReadAccess->GetPaletteColor( 1 ) );

                    // shortcut for true luminance calculation
                    // (assumes that palette is grey-level). Note the
                    // swapped the indices here, to account for the
                    // fact that VCL's notion of alpha is inverted to
                    // the rest of the world's.
                    aColorMap[0] = rCol1.GetRed();
                    aColorMap[1] = rCol0.GetRed();

                    for( y=0; y<nHeight; ++y )
                    {
                        switch( pReadAccess->GetScanlineFormat() )
                        {
                            case BMP_FORMAT_8BIT_PAL:
                            {
                                Scanline pScan  = pReadAccess->GetScanline( y );
                                Scanline pMScan = pMaskReadAccess->GetScanline( y );

                                for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
                                {
                                    aCol = pReadAccess->GetPaletteColor( *pScan++ );

                                    *pCurrOutput++ = aCol.GetBlue();
                                    *pCurrOutput++ = aCol.GetGreen();
                                    *pCurrOutput++ = aCol.GetRed();

                                    *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ];
                                    nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
                                }
                            }
                            break;

                            case BMP_FORMAT_24BIT_TC_BGR:
                            {
                                Scanline pScan  = pReadAccess->GetScanline( y );
                                Scanline pMScan = pMaskReadAccess->GetScanline( y );

                                for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
                                {
                                    // store as RGBA
                                    *pCurrOutput++ = *pScan++;
                                    *pCurrOutput++ = *pScan++;
                                    *pCurrOutput++ = *pScan++;

                                    *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ];
                                    nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
                                }
                            }
                            break;

                            // TODO(P2): Might be advantageous
                            // to hand-formulate the following
                            // formats, too.
                            case BMP_FORMAT_1BIT_MSB_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_4BIT_MSN_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_16BIT_TC_LSB_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_MASK:
                            {
                                Scanline pMScan = pMaskReadAccess->GetScanline( y );

                                // using fallback for those
                                // seldom formats
                                for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
                                {
                                    // yes. x and y are swapped on Get/SetPixel
                                    aCol = pReadAccess->GetColor(y,x);                            

                                    // store as RGBA
                                    *pCurrOutput++ = aCol.GetBlue();
                                    *pCurrOutput++ = aCol.GetGreen();
                                    *pCurrOutput++ = aCol.GetRed();

                                    *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ];
                                    nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
                                }
                            }
                            break;

                            case BMP_FORMAT_1BIT_LSB_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_4BIT_LSN_PAL:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_8BIT_TC_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_24BIT_TC_RGB:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_24BIT_TC_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_16BIT_TC_MSB_MASK:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_ABGR:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_ARGB:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_BGRA:
                                // FALLTHROUGH intended
                            case BMP_FORMAT_32BIT_TC_RGBA:
                                // FALLTHROUGH intended
                            default:
                                ENSURE_OR_THROW( false,
                                                  "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
                                                  "Unexpected scanline format - has "
                                                  "WinSalBitmap::AcquireBuffer() changed?" );
                        }
                    }
                }

                return aBmpData;
            }

            bool drawVCLBitmapEx( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics, 
                                  const ::BitmapEx& 							  rBmpEx )
            {
                if( !rBmpEx.IsTransparent() ) 
                {
                    Bitmap aBmp( rBmpEx.GetBitmap() );
                    return drawVCLBitmap( rGraphics, aBmp );
                }
                else
                {
                    return drawRGBABits( rGraphics,
                                         bitmapFromVCLBitmapEx( rBmpEx ) );
                }
            }
        }

        bool drawVCLBitmapFromXBitmap( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics, 
                                       const uno::Reference< rendering::XBitmap >&	   xBitmap )
        {
            // TODO(F2): add support for floating point bitmap formats
            uno::Reference< rendering::XIntegerReadOnlyBitmap > xIntBmp( 
                xBitmap, uno::UNO_QUERY );

            if( !xIntBmp.is() )
                return false;

            ::BitmapEx aBmpEx = ::vcl::unotools::bitmapExFromXBitmap( xIntBmp );
            if( !aBmpEx )
                return false;

            return drawVCLBitmapEx( rGraphics, aBmpEx );
        }
    }
}
