/**************************************************************
 * 
 * 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 <tools/prex.h>
#include <X11/extensions/Xrender.h>
#include <X11/Xlib.h>
#include <tools/postx.h>

#include "cairo_xlib_cairo.hxx"

#include <vcl/sysdata.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/virdev.hxx>
#include <basegfx/vector/b2isize.hxx>

namespace cairo
{

#include <cairo-xlib.h>
#include <cairo-xlib-xrender.h>

    // TODO(F3): svp headless case!

    bool IsCairoWorking( OutputDevice* pOutDev )
    {
        if( !pOutDev )
            return false;

        Display* pDisplay = (Display*)pOutDev->GetSystemGfxData().pDisplay;
        int nDummy;
        return XQueryExtension( pDisplay, "RENDER", &nDummy, &nDummy, &nDummy );
	}

    X11SysData::X11SysData() :
        pDisplay(NULL),
        hDrawable(0),
        pVisual(NULL),
        nScreen(0),
        nDepth(-1),
        aColormap(-1),
        pRenderFormat(NULL)
    {}

    X11SysData::X11SysData( const SystemGraphicsData& pSysDat ) :
        pDisplay(pSysDat.pDisplay),
        hDrawable(pSysDat.hDrawable),
        pVisual(pSysDat.pVisual),
        nScreen(pSysDat.nScreen),
        nDepth(pSysDat.nDepth),
        aColormap(pSysDat.aColormap),
        pRenderFormat(pSysDat.pRenderFormat)
    {}

    X11SysData::X11SysData( const SystemEnvData& pSysDat ) :
        pDisplay(pSysDat.pDisplay),
        hDrawable(pSysDat.aWindow),
        pVisual(pSysDat.pVisual),
        nScreen(pSysDat.nScreen),
        nDepth(pSysDat.nDepth),
        aColormap(pSysDat.aColormap),
        pRenderFormat(NULL)
    {}

    X11Pixmap::~X11Pixmap()
    {
        if( mpDisplay && mhDrawable )
            XFreePixmap( (Display*)mpDisplay, mhDrawable );
    }

    /**
     * Surface::Surface:   Create Canvas surface with existing data
     * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
     * @param pSurface Cairo surface
     *
     * pSysData contains the platform native Drawable reference
     * This constructor only stores data, it does no processing.
     * It is used by e.g. Surface::getSimilar()
     *
     * Set the mpSurface as pSurface
     **/
    X11Surface::X11Surface( const X11SysData&            rSysData, 
                            const X11PixmapSharedPtr&    rPixmap, 
                            const CairoSurfaceSharedPtr& pSurface ) :
        maSysData(rSysData),
        mpPixmap(rPixmap),
        mpSurface(pSurface)
    {}

    /**
     * Surface::Surface:     Create generic Canvas surface using given Cairo Surface
     *
     * @param pSurface Cairo Surface
     *
     * This constructor only stores data, it does no processing.
     * It is used with e.g. cairo_image_surface_create_for_data()
     * Unlike other constructors, mpSysData is set to NULL
     *
     * Set the mpSurface as pSurface
     **/
    X11Surface::X11Surface( const CairoSurfaceSharedPtr& pSurface ) : 
        maSysData(),
        mpPixmap(),
        mpSurface(pSurface)
    {}

    /**
     * Surface::Surface:   Create Canvas surface from Window reference.
     * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
     * @param x horizontal location of the new surface
     * @param y vertical location of the new surface
     * @param width width of the new surface
     * @param height height of the new surface
     *
     * pSysData contains the platform native Window reference.
     *
     * pSysData is used to create a surface on the Window
     *
     * Set the mpSurface to the new surface or NULL
     **/
	X11Surface::X11Surface( const X11SysData& rSysData, int x, int y, int width, int height ) :
        maSysData(rSysData),
        mpPixmap(),
        mpSurface(
            cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
                                       rSysData.hDrawable,
                                       (Visual*)rSysData.pVisual,
                                       width + x, height + y ),
            &cairo_surface_destroy)
	{
        cairo_surface_set_device_offset(mpSurface.get(), x, y );
    }

    /**
     * Surface::Surface:   Create platform native Canvas surface from BitmapSystemData
     * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
     * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
     * @param width width of the new surface
     * @param height height of the new surface
     *
     * The pBmpData provides the imagedata that the created surface should contain.
     *
     * Set the mpSurface to the new surface or NULL
     **/
	X11Surface::X11Surface( const X11SysData&       rSysData, 
                            const BitmapSystemData& rData ) :
        maSysData( rSysData ),
        mpPixmap(),
        mpSurface(
            cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
                                       (Drawable)rData.aPixmap,
                                       (Visual*) rSysData.pVisual,
                                       rData.mnWidth, rData.mnHeight ),
            &cairo_surface_destroy)
	{
    }

    /**
     * Surface::getCairo:  Create Cairo (drawing object) for the Canvas surface
     *
     * @return new Cairo or NULL
     **/
	CairoSharedPtr X11Surface::getCairo() const
    {
        return CairoSharedPtr( cairo_create(mpSurface.get()),
                               &cairo_destroy );
    }

    /**
     * Surface::getSimilar:  Create new similar Canvas surface 
     * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
     * @param width width of the new surface
     * @param height height of the new surface
     *
     * Creates a new Canvas surface. This normally creates platform native surface, even though
     * generic function is used.
     *
     * Cairo surface from aContent (cairo_content_t)
     *
     * @return new surface or NULL
     **/     
	SurfaceSharedPtr X11Surface::getSimilar( Content aContent, int width, int height ) const
	{
		Pixmap hPixmap;

		if( maSysData.pDisplay && maSysData.hDrawable ) 
        {
			XRenderPictFormat* pFormat;
			int	nFormat;

			switch (aContent) 
            {
                case CAIRO_CONTENT_ALPHA:
                    nFormat = PictStandardA8;
                    break;
                case CAIRO_CONTENT_COLOR:
                    nFormat = PictStandardRGB24;
                    break;
                case CAIRO_CONTENT_COLOR_ALPHA:
                default:
                    nFormat = PictStandardARGB32;
                    break;
			}

			pFormat = XRenderFindStandardFormat( (Display*)maSysData.pDisplay, nFormat );
			hPixmap = XCreatePixmap( (Display*)maSysData.pDisplay, maSysData.hDrawable,
									 width > 0 ? width : 1, height > 0 ? height : 1,
									 pFormat->depth );

            X11SysData aSysData(maSysData);
            aSysData.pRenderFormat = pFormat;
            return SurfaceSharedPtr(
                new X11Surface( aSysData, 
                                X11PixmapSharedPtr(
                                    new X11Pixmap(hPixmap, maSysData.pDisplay)),
                                CairoSurfaceSharedPtr(
                                    cairo_xlib_surface_create_with_xrender_format( 
                                        (Display*)maSysData.pDisplay, 
                                        hPixmap,
                                        ScreenOfDisplay((Display *)maSysData.pDisplay, maSysData.nScreen),
                                        pFormat, width, height ),
                                    &cairo_surface_destroy) ));
		} 
        else
			return SurfaceSharedPtr(
                new X11Surface( maSysData, 
                                X11PixmapSharedPtr(),
                                CairoSurfaceSharedPtr(
                                    cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
                                    &cairo_surface_destroy )));
	}

    boost::shared_ptr<VirtualDevice> X11Surface::createVirtualDevice() const
    {
		SystemGraphicsData aSystemGraphicsData;

		aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
		aSystemGraphicsData.hDrawable = getDrawable();
		aSystemGraphicsData.pRenderFormat = getRenderFormat();

		return boost::shared_ptr<VirtualDevice>(
            new VirtualDevice( &aSystemGraphicsData, getDepth() ));
    }

    /**
     * Surface::Resize:  Resizes the Canvas surface.
     * @param width new width of the surface
     * @param height new height of the surface
     *
     * Only used on X11.
     *
     * @return The new surface or NULL
     **/
	void X11Surface::Resize( int width, int height )
	{
		cairo_xlib_surface_set_size( mpSurface.get(), width, height );
	}

    void X11Surface::flush() const
    {
        XSync( (Display*)maSysData.pDisplay, false );
    }

    /**
     * Surface::getDepth:  Get the color depth of the Canvas surface.
     *
     * @return color depth 
     **/
	int X11Surface::getDepth() const
	{
		if( maSysData.pRenderFormat )
			return ((XRenderPictFormat*) maSysData.pRenderFormat)->depth;

		return -1;
	}

    SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface )
    {
        return SurfaceSharedPtr(new X11Surface(rSurface));
    }

    static X11SysData getSysData( const Window& rWindow )
    {
        const SystemEnvData* pSysData = GetSysData(&rWindow);

        if( !pSysData )
            return X11SysData();
        else
            return X11SysData(*pSysData);
    }

    static X11SysData getSysData( const VirtualDevice& rVirDev )
    {
        return X11SysData( rVirDev.GetSystemGfxData() );
    }

    SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice,
                                    int x, int y, int width, int height )
    {
        if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
            return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice),
                                                   x,y,width,height));
        else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
            return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice),
                                                   x,y,width,height));
        else
            return SurfaceSharedPtr();
    }

    SurfaceSharedPtr createBitmapSurface( const OutputDevice&     rRefDevice,
                                          const BitmapSystemData& rData, 
                                          const Size&             rSize )
    {
        OSL_TRACE( "requested size: %d x %d available size: %d x %d", 
                   rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
        if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
        {
            if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
                return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice), rData ));
            else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
                return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice), rData ));
        }

        return SurfaceSharedPtr();
    }
}
