/*
 * Copyright (C) 2008, 2010 Apple 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 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 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. 
 */

// FIXME: This should be removed and made an alias to DOMRect.
[
    ImplementationLacksVTable,
] interface WebKitCSSMatrix {
    [MayThrowException] constructor(optional DOMString cssValue);

    // These attributes are simple aliases for certain elements of the 4x4 matrix
    attribute unrestricted double a; // alias for m11
    attribute unrestricted double b; // alias for m12
    attribute unrestricted double c; // alias for m21
    attribute unrestricted double d; // alias for m22
    attribute unrestricted double e; // alias for m41
    attribute unrestricted double f; // alias for m42

    attribute unrestricted double m11;
    attribute unrestricted double m12;
    attribute unrestricted double m13;

    attribute unrestricted double m14;
    attribute unrestricted double m21;
    attribute unrestricted double m22;
    attribute unrestricted double m23;
    attribute unrestricted double m24;
    attribute unrestricted double m31;
    attribute unrestricted double m32;
    attribute unrestricted double m33;
    attribute unrestricted double m34;
    attribute unrestricted double m41;
    attribute unrestricted double m42;
    attribute unrestricted double m43;
    attribute unrestricted double m44;

    // FIXME: Using "undefined" as default parameter value is wrong.
    [MayThrowException] void setMatrixValue(optional DOMString string = "undefined");
    
    // Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix)
    WebKitCSSMatrix multiply(optional WebKitCSSMatrix? secondMatrix = null);
    
    // Return the inverse of this matrix. Throw an exception if the matrix is not invertible
    [MayThrowException] WebKitCSSMatrix inverse();
    
    // Return this matrix translated by the passed values.
    // Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations
    WebKitCSSMatrix translate(optional unrestricted double x = NaN, optional unrestricted double y = NaN, optional unrestricted double z = NaN);
    
    // Returns this matrix scaled by the passed values.
    // Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN 
    // makes it the same as scaleX. This allows the 3D form to used for 2D operations
    WebKitCSSMatrix scale(optional unrestricted double scaleX = NaN, optional unrestricted double scaleY = NaN, optional unrestricted double scaleZ = NaN);
    
    // Returns this matrix rotated by the passed values.
    // If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX).
    // Otherwise use a rotation value of 0 for any passed NaN.    
    WebKitCSSMatrix rotate(optional unrestricted double rotX = NaN, optional unrestricted double rotY = NaN, optional unrestricted double rotZ = NaN);
    
    // Returns this matrix rotated about the passed axis by the passed angle.
    // Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value
    // of (0,0,1).
    WebKitCSSMatrix rotateAxisAngle(optional unrestricted double x = NaN, optional unrestricted double y = NaN, optional unrestricted double z = NaN, optional unrestricted double angle = NaN);

    // Returns this matrix skewed along the X axis by the passed values.
    // Passing a NaN will use a value of 0.
    WebKitCSSMatrix skewX(optional unrestricted double angle = NaN);

    // Returns this matrix skewed along the Y axis by the passed values.
    // Passing a NaN will use a value of 0.
    WebKitCSSMatrix skewY(optional unrestricted double angle = NaN);

    [MayThrowException] stringifier;
};
