/*
 * Copyright (c) 2004 Nokia. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of Nokia nor the names of its contributors may be
 * used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef GdkXftContext_h
#define GdkXftContext_h

#include <gdk/gdk.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>

#include "NRCore/KWIQCGContext.h"

class CGContextProvider;
class Path;
class PathElement;

class GdkXftContext : public CGContext
{
public:
    GdkXftContext(CGContextProvider* provider, GdkDrawable *drawable);
    ~GdkXftContext();

    GdkDrawable* realDrawable();
    void realTranslate(int* x, int* y);
    
    void addClip(GdkRectangle* rect);
    void saveGraphicsState();
    void restoreGraphicsState();

    void clearClip();

    XftDraw* xftDraw() { return xftdraw; }


    Visual* XVisual() { return xvisual;}
    Colormap XColormap() {return xcmap;}
    void regionExpiresAt(GTimeVal* moment, GdkRectangle* rect);

    CGImageRef createImage();
    void drawImage(const GdkRectangle * rect, const CGImageRef image);
    
    void flush();
    
    void setLineCap (CGLineCap cap);
    void setLineJoin (CGLineJoin join);
    void setLineWidth (float width);
    void setMiterLimit (float limit);

    void setRGBStrokeColor(float red, float green, float blue, float alpha);
    void setRGBFillColor(float red, float green, float blue, float alpha);

    void setGrayStrokeColor(float gray, float alpha);
    void setGrayFillColor(float gray, float alpha);
    
    void setCMYKStrokeColor(float c, float m, float y, float k, float a);
    void setCMYKFillColor(float c, float m, float y, float k, float a);
    
    void addArc (float x, float y, float radius,
                         float startAngle, float endAngle, int clockwise);

    void addArcToPoint (float x1, float y1,
                                float x2, float y2, float radius);

    void addCurveToPoint (float cp1x, float cp1y,
                                  float cp2x, float cp2y, float x, float y);

    void addLineToPoint (float x, float y);
    
    void addQuadCurveToPoint (float cpx, float cpy,
                                      float x, float y);

    void addRect (const GdkRectangle * rect);

    void beginPath();
    void closePath();

    void moveToPoint (float x, float y);

    void clearRect (const GdkRectangle * rect);
    void fillPath ();
    void fillRect (const GdkRectangle * rect);
    void strokePath ();
    void strokeRect (const GdkRectangle * rect);
    void strokeRectWithWidth (const GdkRectangle * rect, float width);

    void clip ();

    void setAlpha (float a);
    void setShadow (CGSize offset, float blur);
    void setShadowWithColor (CGSize offset, float blur, CGColorRef colorRef);

    void rotateCTM (float angle);
    void scaleCTM (float sx, float sy);
    void translateCTM (float tx, float ty);

    GdkColor * fillColor() { return _fillColor; }
    GdkColor * strokeColor() { return _strokeColor; }
    
private:
    void updateXftDraw();
    GdkRegion *savedClip;   

    XftDraw* xftdraw;
    GdkDrawable* xftGdkDraw;
    GdkColor* _fillColor;
    GdkColor* _strokeColor;
    Colormap xcmap;    
    Visual *xvisual;
    int xftxoff, xftyoff;

    bool iswindow;
    CGContextProvider *provider;
    Path* path;
    
    float lineWidth, miterLimit, alpha;
    CGLineCap lineCap;
    CGLineJoin lineJoin;
};

#endif
