/*
 * 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 KWIQCGContext_h
#define KWIQCGContext_h

#include <gdk/gdk.h>

#include "KWIQCGImage.h"
#include "KWIQCGColor.h"

#define CGRectMake(x, y, width, height) x, y, width, height


enum CGLineCap {
    kCGLineCapButt,
    kCGLineCapRound,
    kCGLineCapSquare
};
typedef enum CGLineCap CGLineCap;

enum CGLineJoin {
   kCGLineJoinMiter,
   kCGLineJoinRound,
   kCGLineJoinBevel
};
typedef enum CGLineJoin CGLineJoin;

struct CGSize {
   float width;
   float height;
};
typedef struct CGSize CGSize;


class CGContext
{
public:
    GdkDrawable* drawable;
    GdkGC* gc;
    GdkRegion* _clip;

    virtual ~CGContext() {};

    virtual GdkDrawable* realDrawable();
    virtual void realTranslate(int *x, int *y);
    
    virtual CGImageRef createImage() = 0;
    virtual void drawImage(const GdkRectangle * rect, const CGImageRef image) = 0;
    
    virtual void addClip(GdkRectangle* rect) = 0;

    virtual void saveGraphicsState() = 0;
    virtual void restoreGraphicsState() = 0;

    virtual void flush() = 0;
    
    virtual void setLineCap (CGLineCap cap) = 0;
    virtual void setLineJoin (CGLineJoin join) = 0;
    virtual void setLineWidth (float width) = 0;
    virtual void setMiterLimit (float limit) = 0;

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

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

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

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

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

    virtual void addRect (const GdkRectangle * rect) = 0;

    virtual void beginPath() = 0;
    virtual void closePath() = 0;

    virtual void moveToPoint (float x, float y) = 0;

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

    virtual void clip () = 0;

    virtual void setAlpha (float a) = 0;


    virtual void setShadow (CGSize offset, float blur) = 0;
    virtual void setShadowWithColor (CGSize offset, float blur, CGColorRef colorRef) = 0;
    

    virtual void rotateCTM (float angle) = 0;
    virtual void scaleCTM (float sx, float sy) = 0;
    virtual void translateCTM (float tx, float ty) = 0;    
};

typedef CGContext* CGContextRef;

enum NSCompositingOperation {
    NSCompositeClear = 0,
    NSCompositeCopy,
    NSCompositeSourceOver ,
    NSCompositeSourceIn,
    NSCompositeSourceOut, 
    NSCompositeSourceAtop, 
    NSCompositeDestinationOver,
    NSCompositeDestinationIn,
    NSCompositeDestinationOut,
    NSCompositeDestinationAtop,
    NSCompositeXOR,
    NSCompositePlusDarker,
    NSCompositeHighlight,
    NSCompositePlusLighter
};

CGSize CGSizeMake(float width, float height);

CGContextRef CGBitmapContextCreate(int cWidth, int cHeight, int depth);
CGImageRef CGBitmapContextCreateImage(CGContextRef c);
void CGContextDrawImage (CGContextRef context, float x, float y, float width, float height, CGImageRef image);
void CGContextFlush(CGContextRef ref);

void CGContextSaveGState(CGContextRef ref);
void CGContextRestoreGState(CGContextRef ref);

void CGContextSetLineCap (CGContextRef ref, CGLineCap cap);
void CGContextSetLineJoin (CGContextRef ref, CGLineJoin join);
void CGContextSetLineWidth (CGContextRef ref, float width);
void CGContextSetMiterLimit (CGContextRef ref, float limit);

void CGContextSetRGBStrokeColor(CGContextRef ref, float red, float green, float blue, float alpha);
void CGContextSetRGBFillColor(CGContextRef ref, float red, float green, float blue, float alpha);

void CGContextSetGrayStrokeColor(CGContextRef ref, float gray, float alpha);
void CGContextSetGrayFillColor(CGContextRef ref, float gray, float alpha);

void CGContextSetCMYKStrokeColor(CGContextRef ref, float c, float m, float y, float k, float alpha);
void CGContextSetCMYKFillColor(CGContextRef ref, float c, float m, float y, float k, float alpha);

void CGContextAddArc (CGContextRef ref, float x, float y, float radius,
                      float startAngle, float endAngle, int clockwise);
void CGContextAddArcToPoint (CGContextRef ref, float x1, float y1,
                             float x2, float y2, float radius);
void CGContextAddCurveToPoint (CGContextRef ref, float cp1x, float cp1y,
                               float cp2x, float cp2y, float x, float y);
void CGContextAddLineToPoint (CGContextRef ref, float x, float y);
void CGContextAddQuadCurveToPoint (CGContextRef ref, float cpx, float cpy,
                                   float x, float y);
void CGContextAddRect (CGContextRef ref, float x, float y, float width, float height);
void CGContextBeginPath(CGContextRef ref);
void CGContextClosePath(CGContextRef ref);

void CGContextMoveToPoint (CGContextRef ref, float x, float y);

void CGContextClearRect (CGContextRef ref, float x, float y, float width, float height);
void CGContextFillPath (CGContextRef ref);
void CGContextFillRect (CGContextRef ref, float x, float y, float width, float height);
void CGContextStrokePath (CGContextRef ref);
void CGContextStrokeRect (CGContextRef ref, float x, float y, float width, float height);
void CGContextStrokeRectWithWidth (CGContextRef ref, float x, float y, float rectWidth, float rectHeight, float strokeWidth);

void CGContextClip (CGContextRef ref);

void CGContextSetAlpha (CGContextRef ref, float alpha);
void CGContextSetShadow (CGContextRef ref, CGSize offset, float blur);
void CGContextSetShadowWithColor (CGContextRef ref, CGSize offset, float blur, CGColorRef colorRef);

void CGContextRotateCTM (CGContextRef ref, float angle);
void CGContextScaleCTM (CGContextRef ref, float sx, float sy);
void CGContextTranslateCTM (CGContextRef ref, float tx, float ty);


#endif
