/*
 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2005-2008, 2017 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include "TransformOperation.h"
#include <wtf/Ref.h>

namespace WebCore {

struct BlendingContext;

class RotateTransformOperation final : public TransformOperation {
public:
    static Ref<RotateTransformOperation> create(double angle, OperationType type)
    {
        return adoptRef(*new RotateTransformOperation(0, 0, 1, angle, type));
    }

    static Ref<RotateTransformOperation> create(double x, double y, double z, double angle, OperationType type)
    {
        return adoptRef(*new RotateTransformOperation(x, y, z, angle, type));
    }

    Ref<TransformOperation> clone() const override
    {
        return adoptRef(*new RotateTransformOperation(m_x, m_y, m_z, m_angle, type()));
    }

    double x() const { return m_x; }
    double y() const { return m_y; }
    double z() const { return m_z; }
    double angle() const { return m_angle; }

    // The 2D rotation primitive doesn't handle any direction vectors other than [0, 0, 1],
    // so even if the rotation is representable in 2D, it might be a 3D rotation.
    OperationType primitiveType() const final { return (isRepresentableIn2D() && z() == 1.0) ? ROTATE : ROTATE_3D; }

    bool operator==(const RotateTransformOperation& other) const { return operator==(static_cast<const TransformOperation&>(other)); }
    bool operator==(const TransformOperation&) const override;

    Ref<TransformOperation> blend(const TransformOperation* from, const BlendingContext&, bool blendToIdentity = false) final;

    bool isIdentity() const final { return !m_angle; }

    bool isRepresentableIn2D() const final { return (!m_x && !m_y) || !m_angle; }

private:
    bool isAffectedByTransformOrigin() const override { return !isIdentity(); }

    bool apply(TransformationMatrix& transform, const FloatSize& /*borderBoxSize*/) const override
    {
        if (type() == TransformOperation::ROTATE)
            transform.rotate(m_angle);
        else
            transform.rotate3d(m_x, m_y, m_z, m_angle);
        return false;
    }

    void dump(WTF::TextStream&) const final;

    RotateTransformOperation(double x, double y, double z, double angle, OperationType type)
        : TransformOperation(type)
        , m_x(x)
        , m_y(y)
        , m_z(z)
        , m_angle(angle)
    {
        ASSERT(isRotateTransformOperationType());
    }

    double m_x;
    double m_y;
    double m_z;
    double m_angle;
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::RotateTransformOperation, isRotateTransformOperationType())
