/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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.
 */

// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasrenderingcontext2d

// FIXME: float => double throughout
typedef (HTMLImageElement or
         HTMLVideoElement or
         HTMLCanvasElement or
         // CanvasRenderingContext2D or
         ImageBitmap) CanvasImageSource;

enum CanvasFillRule { "nonzero", "evenodd" };

[
    SetWrapperReferenceFrom=canvas,
    TypeChecking=Interface,
    WillBeGarbageCollected,
] interface CanvasRenderingContext2D {
    // back-reference to the canvas
    readonly attribute HTMLCanvasElement canvas;

    // state
    void save(); // push state on state stack
    void restore(); // pop state stack and restore state

    // transformations (default transform is the identity matrix)
    [RuntimeEnabled=ExperimentalCanvasFeatures] attribute SVGMatrix currentTransform;
    void scale(unrestricted float x, unrestricted float y);
    void rotate(unrestricted float angle);
    void translate(unrestricted float x, unrestricted float y);
    void transform(unrestricted float a, unrestricted float b, unrestricted float c, unrestricted float d, unrestricted float e, unrestricted float f);
    void setTransform(unrestricted float a, unrestricted float b, unrestricted float c, unrestricted float d, unrestricted float e, unrestricted float f);
    void resetTransform();

    // compositing
    attribute unrestricted float globalAlpha; // (default 1.0)
    [TreatNullAs=NullString] attribute DOMString globalCompositeOperation; // (default source-over)

    // image smoothing
    [ImplementedAs=imageSmoothingEnabled, DeprecateAs=PrefixedImageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
    [MeasureAs=UnprefixedImageSmoothingEnabled] attribute boolean imageSmoothingEnabled;

    // colors and styles (see also the CanvasDrawingStyles interface)
    attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black)
    attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
    CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
    [RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
    [RaisesException] CanvasPattern createPattern(CanvasImageSource image, DOMString? repetitionType);

    // shadows
    attribute unrestricted float shadowOffsetX;
    attribute unrestricted float shadowOffsetY;
    attribute unrestricted float shadowBlur;
    [TreatNullAs=NullString] attribute DOMString shadowColor;

    // rects
    void clearRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
    void fillRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
    void strokeRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);

    // path API (see also CanvasPathMethods)
    void beginPath();
    void fill(optional CanvasFillRule winding);
    void fill(Path2D path, optional CanvasFillRule winding);
    void stroke();
    void stroke(Path2D path);
    // Focus rings
    void drawFocusIfNeeded(Element element);
    void drawFocusIfNeeded(Path2D path, Element element);

    [RuntimeEnabled=ExperimentalCanvasFeatures] void scrollPathIntoView(optional Path2D path);
    void clip(optional CanvasFillRule winding);
    void clip(Path2D path, optional CanvasFillRule winding);
    boolean isPointInPath(unrestricted float x, unrestricted float y, optional CanvasFillRule winding);
    boolean isPointInPath(Path2D path, unrestricted float x, unrestricted float y, optional CanvasFillRule winding);
    boolean isPointInStroke(unrestricted float x, unrestricted float y);
    boolean isPointInStroke(Path2D path, unrestricted float x, unrestricted float y);

    // text (see also the CanvasDrawingStyles interface)
    void fillText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
    void strokeText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
    TextMetrics measureText(DOMString text);

    // drawing images
    [RaisesException] void drawImage(CanvasImageSource image, unrestricted float x, unrestricted float y);
    [RaisesException] void drawImage(CanvasImageSource image, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
    [RaisesException] void drawImage(CanvasImageSource image, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);

    // hit regions
    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void addHitRegion(optional HitRegionOptions options);
    [RuntimeEnabled=ExperimentalCanvasFeatures] void removeHitRegion(DOMString id);
    [RuntimeEnabled=ExperimentalCanvasFeatures] void clearHitRegions();

    // pixel manipulation
    ImageData createImageData(ImageData imagedata);
    [RaisesException] ImageData createImageData(float sw, float sh);
    [RaisesException] ImageData getImageData(float sx, float sy, float sw, float sh);
    void putImageData(ImageData imagedata, float dx, float dy);
    void putImageData(ImageData imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);

    // Context state
    // Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental
    [RuntimeEnabled=ExperimentalCanvasFeatures] boolean isContextLost();

    Canvas2DContextAttributes getContextAttributes();

    // FIXME: factor out to CanvasDrawingStyles
    // line caps/joins
    attribute unrestricted float lineWidth; // (default 1)
    [TreatNullAs=NullString] attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
    [TreatNullAs=NullString] attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
    attribute unrestricted float miterLimit; // (default 10)

    // dashed lines
    void setLineDash(sequence<unrestricted float> dash);
    sequence<unrestricted float> getLineDash();
    attribute unrestricted float lineDashOffset;

    // text
    attribute DOMString font; // (default 10px sans-serif)
    attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
    attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
    [RuntimeEnabled=ExperimentalCanvasFeatures] attribute DOMString direction; // "inherit", "rtl", "ltr" (default: "inherit")

};

CanvasRenderingContext2D implements CanvasPathMethods;
