/*
 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2012, 2013 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER “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 HOLDER 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.
 */

#include "config.h"
#include "TransformFunctions.h"

#include "CSSFunctionValue.h"
#include "CSSPrimitiveValueMappings.h"
#include "CSSValueList.h"
#include "Matrix3DTransformOperation.h"
#include "MatrixTransformOperation.h"
#include "PerspectiveTransformOperation.h"
#include "RotateTransformOperation.h"
#include "ScaleTransformOperation.h"
#include "SkewTransformOperation.h"
#include "TranslateTransformOperation.h"
#include <wtf/text/StringConcatenateNumbers.h>

namespace WebCore {

static TransformOperation::OperationType transformOperationType(CSSValueID type)
{
    switch (type) {
    case CSSValueScale:
        return TransformOperation::SCALE;
    case CSSValueScaleX:
        return TransformOperation::SCALE_X;
    case CSSValueScaleY:
        return TransformOperation::SCALE_Y;
    case CSSValueScaleZ:
        return TransformOperation::SCALE_Z;
    case CSSValueScale3d:
        return TransformOperation::SCALE_3D;
    case CSSValueTranslate:
        return TransformOperation::TRANSLATE;
    case CSSValueTranslateX:
        return TransformOperation::TRANSLATE_X;
    case CSSValueTranslateY:
        return TransformOperation::TRANSLATE_Y;
    case CSSValueTranslateZ:
        return TransformOperation::TRANSLATE_Z;
    case CSSValueTranslate3d:
        return TransformOperation::TRANSLATE_3D;
    case CSSValueRotate:
        return TransformOperation::ROTATE;
    case CSSValueRotateX:
        return TransformOperation::ROTATE_X;
    case CSSValueRotateY:
        return TransformOperation::ROTATE_Y;
    case CSSValueRotateZ:
        return TransformOperation::ROTATE_Z;
    case CSSValueRotate3d:
        return TransformOperation::ROTATE_3D;
    case CSSValueSkew:
        return TransformOperation::SKEW;
    case CSSValueSkewX:
        return TransformOperation::SKEW_X;
    case CSSValueSkewY:
        return TransformOperation::SKEW_Y;
    case CSSValueMatrix:
        return TransformOperation::MATRIX;
    case CSSValueMatrix3d:
        return TransformOperation::MATRIX_3D;
    case CSSValuePerspective:
        return TransformOperation::PERSPECTIVE;
    default:
        break;
    }
    return TransformOperation::NONE;
}

Length convertToFloatLength(const CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData)
{
    return primitiveValue ? primitiveValue->convertToLength<FixedFloatConversion | PercentConversion | CalculatedConversion>(conversionData) : Length(LengthType::Undefined);
}

bool transformsForValue(const CSSValue& value, const CSSToLengthConversionData& conversionData, TransformOperations& outOperations)
{
    ASSERT(!outOperations.size());
    if (!is<CSSValueList>(value))
        return false;

    auto& operations = outOperations.operations();
    for (auto& currentValue : downcast<CSSValueList>(value)) {
        if (!is<CSSFunctionValue>(currentValue))
            continue;

        auto& transformValue = downcast<CSSFunctionValue>(currentValue.get());
        if (!transformValue.length())
            continue;

        bool haveNonPrimitiveValue = false;
        for (unsigned j = 0; j < transformValue.length(); ++j) {
            if (!is<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(j))) {
                haveNonPrimitiveValue = true;
                break;
            }
        }
        if (haveNonPrimitiveValue)
            continue;

        auto& firstValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(0));

        switch (transformValue.name()) {
        case CSSValueScale:
        case CSSValueScaleX:
        case CSSValueScaleY: {
            double sx = 1.0;
            double sy = 1.0;
            if (transformValue.name() == CSSValueScaleY)
                sy = firstValue.doubleValueDividingBy100IfPercentage();
            else {
                sx = firstValue.doubleValueDividingBy100IfPercentage();
                if (transformValue.name() != CSSValueScaleX) {
                    if (transformValue.length() > 1) {
                        auto& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
                        sy = secondValue.doubleValueDividingBy100IfPercentage();
                    } else
                        sy = sx;
                }
            }
            operations.append(ScaleTransformOperation::create(sx, sy, 1.0, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueScaleZ:
        case CSSValueScale3d: {
            double sx = 1.0;
            double sy = 1.0;
            double sz = 1.0;
            if (transformValue.name() == CSSValueScaleZ)
                sz = firstValue.doubleValueDividingBy100IfPercentage();
            else if (transformValue.name() == CSSValueScaleY)
                sy = firstValue.doubleValueDividingBy100IfPercentage();
            else {
                sx = firstValue.doubleValueDividingBy100IfPercentage();
                if (transformValue.name() != CSSValueScaleX) {
                    if (transformValue.length() > 2) {
                        auto& thirdValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(2));
                        sz = thirdValue.doubleValueDividingBy100IfPercentage();
                    }
                    if (transformValue.length() > 1) {
                        auto& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
                        sy = secondValue.doubleValueDividingBy100IfPercentage();
                    } else
                        sy = sx;
                }
            }
            operations.append(ScaleTransformOperation::create(sx, sy, sz, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueTranslate:
        case CSSValueTranslateX:
        case CSSValueTranslateY: {
            Length tx = Length(0, LengthType::Fixed);
            Length ty = Length(0, LengthType::Fixed);
            if (transformValue.name() == CSSValueTranslateY)
                ty = convertToFloatLength(&firstValue, conversionData);
            else {
                tx = convertToFloatLength(&firstValue, conversionData);
                if (transformValue.name() != CSSValueTranslateX) {
                    if (transformValue.length() > 1) {
                        auto& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
                        ty = convertToFloatLength(&secondValue, conversionData);
                    }
                }
            }

            if (tx.isUndefined() || ty.isUndefined()) {
                operations.clear();
                return false;
            }

            operations.append(TranslateTransformOperation::create(tx, ty, Length(0, LengthType::Fixed), transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueTranslateZ:
        case CSSValueTranslate3d: {
            Length tx = Length(0, LengthType::Fixed);
            Length ty = Length(0, LengthType::Fixed);
            Length tz = Length(0, LengthType::Fixed);
            if (transformValue.name() == CSSValueTranslateZ)
                tz = convertToFloatLength(&firstValue, conversionData);
            else if (transformValue.name() == CSSValueTranslateY)
                ty = convertToFloatLength(&firstValue, conversionData);
            else {
                tx = convertToFloatLength(&firstValue, conversionData);
                if (transformValue.name() != CSSValueTranslateX) {
                    if (transformValue.length() > 2) {
                        auto& thirdValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(2));
                        tz = convertToFloatLength(&thirdValue, conversionData);
                    }
                    if (transformValue.length() > 1) {
                        auto& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
                        ty = convertToFloatLength(&secondValue, conversionData);
                    }
                }
            }

            if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined()) {
                operations.clear();
                return false;
            }

            operations.append(TranslateTransformOperation::create(tx, ty, tz, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueRotate: {
            double angle = firstValue.computeDegrees();
            operations.append(RotateTransformOperation::create(0, 0, 1, angle, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueRotateX:
        case CSSValueRotateY:
        case CSSValueRotateZ: {
            double x = 0;
            double y = 0;
            double z = 0;
            double angle = firstValue.computeDegrees();

            if (transformValue.name() == CSSValueRotateX)
                x = 1;
            else if (transformValue.name() == CSSValueRotateY)
                y = 1;
            else
                z = 1;
            operations.append(RotateTransformOperation::create(x, y, z, angle, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueRotate3d: {
            if (transformValue.length() < 4)
                break;
            auto& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
            auto& thirdValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(2));
            auto& fourthValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(3));
            double x = firstValue.doubleValue();
            double y = secondValue.doubleValue();
            double z = thirdValue.doubleValue();
            double angle = fourthValue.computeDegrees();
            operations.append(RotateTransformOperation::create(x, y, z, angle, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueSkew:
        case CSSValueSkewX:
        case CSSValueSkewY: {
            double angleX = 0;
            double angleY = 0;
            double angle = firstValue.computeDegrees();
            if (transformValue.name() == CSSValueSkewY)
                angleY = angle;
            else {
                angleX = angle;
                if (transformValue.name() == CSSValueSkew) {
                    if (transformValue.length() > 1) {
                        auto& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
                        angleY = secondValue.computeDegrees();
                    }
                }
            }
            operations.append(SkewTransformOperation::create(angleX, angleY, transformOperationType(transformValue.name())));
            break;
        }
        case CSSValueMatrix: {
            if (transformValue.length() < 6)
                break;
            double a = firstValue.doubleValue();
            double b = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1)).doubleValue();
            double c = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(2)).doubleValue();
            double d = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(3)).doubleValue();
            double e = conversionData.zoom() * downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(4)).doubleValue();
            double f = conversionData.zoom() * downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(5)).doubleValue();
            operations.append(MatrixTransformOperation::create(a, b, c, d, e, f));
            break;
        }
        case CSSValueMatrix3d: {
            if (transformValue.length() < 16)
                break;
            TransformationMatrix matrix(downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(0)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(2)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(3)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(4)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(5)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(6)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(7)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(8)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(9)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(10)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(11)).doubleValue(),
                conversionData.zoom() * downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(12)).doubleValue(),
                conversionData.zoom() * downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(13)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(14)).doubleValue(),
                downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(15)).doubleValue());
            operations.append(Matrix3DTransformOperation::create(matrix));
            break;
        }
        case CSSValuePerspective: {
            std::optional<Length> perspectiveLength;
            if (!firstValue.isValueID()) {
                if (firstValue.isLength())
                    perspectiveLength = convertToFloatLength(&firstValue, conversionData);
                else {
                    // This is a quirk that should go away when 3d transforms are finalized.
                    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=232669
                    // This does not deal properly with calc(), because we aren't passing conversionData here.
                    double doubleValue = firstValue.doubleValue();
                    if (doubleValue < 0) {
                        operations.clear();
                        return false;
                    }
                    perspectiveLength = Length(clampToPositiveInteger(doubleValue), LengthType::Fixed);
                }
            } else
                ASSERT(firstValue.valueID() == CSSValueNone);

            operations.append(PerspectiveTransformOperation::create(perspectiveLength));
            break;
        }
        default:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    return true;
}

RefPtr<TranslateTransformOperation> translateForValue(const CSSValue& value, const CSSToLengthConversionData& conversionData)
{
    if (!is<CSSValueList>(value))
        return nullptr;

    auto& valueList = downcast<CSSValueList>(value);
    if (!valueList.length())
        return nullptr;

    auto type = TransformOperation::TRANSLATE;
    Length tx = Length(0, LengthType::Fixed);
    Length ty = Length(0, LengthType::Fixed);
    Length tz = Length(0, LengthType::Fixed);
    for (unsigned i = 0; i < valueList.length(); ++i) {
        auto* valueItem = valueList.itemWithoutBoundsCheck(i);
        if (!is<CSSPrimitiveValue>(valueItem))
            return nullptr;
        if (!i)
            tx = convertToFloatLength(downcast<CSSPrimitiveValue>(valueItem), conversionData);
        else if (i == 1)
            ty = convertToFloatLength(downcast<CSSPrimitiveValue>(valueItem), conversionData);
        else if (i == 2) {
            type = TransformOperation::TRANSLATE_3D;
            tz = convertToFloatLength(downcast<CSSPrimitiveValue>(valueItem), conversionData);
        }
    }

    return TranslateTransformOperation::create(tx, ty, tz, type);
}

RefPtr<ScaleTransformOperation> scaleForValue(const CSSValue& value)
{
    if (!is<CSSValueList>(value))
        return nullptr;

    auto& valueList = downcast<CSSValueList>(value);
    if (!valueList.length())
        return nullptr;

    auto type = TransformOperation::SCALE;
    double sx = 1.0;
    double sy = 1.0;
    double sz = 1.0;
    for (unsigned i = 0; i < valueList.length(); ++i) {
        auto* valueItem = valueList.itemWithoutBoundsCheck(i);
        if (!is<CSSPrimitiveValue>(valueItem))
            return nullptr;
        if (!i) {
            sx = downcast<CSSPrimitiveValue>(*valueItem).doubleValueDividingBy100IfPercentage();
            sy = sx;
        } else if (i == 1)
            sy = downcast<CSSPrimitiveValue>(*valueItem).doubleValueDividingBy100IfPercentage();
        else if (i == 2) {
            type = TransformOperation::SCALE_3D;
            sz = downcast<CSSPrimitiveValue>(*valueItem).doubleValueDividingBy100IfPercentage();
        }
    }

    return ScaleTransformOperation::create(sx, sy, sz, type);
}

RefPtr<RotateTransformOperation> rotateForValue(const CSSValue& value)
{
    if (!is<CSSValueList>(value))
        return nullptr;

    auto& valueList = downcast<CSSValueList>(value);
    auto numberOfItems = valueList.length();

    // There are three scenarios here since the rotation axis is defined either as:
    //     - no value: implicit 2d rotation
    //     - 1 value: an axis identifier (x/y/z)
    //     - 3 values: three numbers defining an x/y/z vector
    // The angle is specified as the last value.
    if (numberOfItems != 1 && numberOfItems != 2 && numberOfItems != 4)
        return nullptr;

    auto* lastValue = valueList.itemWithoutBoundsCheck(numberOfItems - 1);
    if (!is<CSSPrimitiveValue>(lastValue))
        return nullptr;
    auto angle = downcast<CSSPrimitiveValue>(*lastValue).computeDegrees();

    if (numberOfItems == 1)
        return RotateTransformOperation::create(angle, TransformOperation::ROTATE);

    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
    auto type = TransformOperation::ROTATE;

    if (numberOfItems == 2) {
        // An axis identifier was specified.
        auto* axisIdentifierItem = valueList.itemWithoutBoundsCheck(0);
        if (!is<CSSPrimitiveValue>(axisIdentifierItem))
            return nullptr;
        auto axisIdentifier = downcast<CSSPrimitiveValue>(*axisIdentifierItem).valueID();
        if (axisIdentifier == CSSValueX) {
            type = TransformOperation::ROTATE_X;
            x = 1.0;
        } else if (axisIdentifier == CSSValueY) {
            type = TransformOperation::ROTATE_Y;
            y = 1.0;
        } else if (axisIdentifier == CSSValueZ) {
            type = TransformOperation::ROTATE_3D;
            z = 1.0;
        } else
            return nullptr;
    } else if (numberOfItems == 4) {
        // The axis was specified using a vector.
        type = TransformOperation::ROTATE;
        for (unsigned i = 0; i < 3; ++i) {
            auto* valueItem = valueList.itemWithoutBoundsCheck(i);
            if (!is<CSSPrimitiveValue>(valueItem))
                return nullptr;
            if (!i)
                x = downcast<CSSPrimitiveValue>(*valueItem).doubleValue();
            else if (i == 1)
                y = downcast<CSSPrimitiveValue>(*valueItem).doubleValue();
            else if (i == 2) {
                type = TransformOperation::ROTATE_3D;
                z = downcast<CSSPrimitiveValue>(*valueItem).doubleValue();
            }
        }
    }

    return RotateTransformOperation::create(x, y, z, angle, type);
}

}
