/*
 * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 *
 * 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. 
 */

#pragma once

#include "CanvasGradient.h"
#include "CanvasPattern.h"
#include "Color.h"
#include <wtf/Variant.h>

namespace WebCore {

class Document;
class GraphicsContext;
class CanvasBase;

class CanvasStyle {
public:
    CanvasStyle();
    CanvasStyle(Color);
    CanvasStyle(float grayLevel, float alpha);
    CanvasStyle(float r, float g, float b, float alpha);
    CanvasStyle(float c, float m, float y, float k, float alpha);
    CanvasStyle(CanvasGradient&);
    CanvasStyle(CanvasPattern&);

    static CanvasStyle createFromString(const String& color);
    static CanvasStyle createFromStringWithOverrideAlpha(const String& color, float alpha);

    bool isValid() const { return !WTF::holds_alternative<Invalid>(m_style); }
    bool isCurrentColor() const { return WTF::holds_alternative<CurrentColor>(m_style); }
    bool hasOverrideAlpha() const { return isCurrentColor() && WTF::get<CurrentColor>(m_style).overrideAlpha; }
    float overrideAlpha() const { return WTF::get<CurrentColor>(m_style).overrideAlpha.value(); }

    String color() const;
    RefPtr<CanvasGradient> canvasGradient() const;
    RefPtr<CanvasPattern> canvasPattern() const;

    void applyFillColor(GraphicsContext&) const;
    void applyStrokeColor(GraphicsContext&) const;

    bool isEquivalentColor(const CanvasStyle&) const;
    bool isEquivalentRGBA(float red, float green, float blue, float alpha) const;
    bool isEquivalentCMYKA(float cyan, float magenta, float yellow, float black, float alpha) const;

private:
    struct Invalid { };

    struct CMYKAColor {
        Color color;
        float c { 0 };
        float m { 0 };
        float y { 0 };
        float k { 0 };
        float a { 0 };

        CMYKAColor(const CMYKAColor&) = default;
    };

    struct CurrentColor {
        Optional<float> overrideAlpha;
    };

    CanvasStyle(CurrentColor);

    Variant<Invalid, Color, CMYKAColor, RefPtr<CanvasGradient>, RefPtr<CanvasPattern>, CurrentColor> m_style;
};

Color currentColor(CanvasBase*);
Color parseColorOrCurrentColor(const String& colorString, CanvasBase*);

inline CanvasStyle::CanvasStyle()
    : m_style(Invalid { })
{
}

inline RefPtr<CanvasGradient> CanvasStyle::canvasGradient() const
{
    if (!WTF::holds_alternative<RefPtr<CanvasGradient>>(m_style))
        return nullptr;
    return WTF::get<RefPtr<CanvasGradient>>(m_style);
}

inline RefPtr<CanvasPattern> CanvasStyle::canvasPattern() const
{
    if (!WTF::holds_alternative<RefPtr<CanvasPattern>>(m_style))
        return nullptr;
    return WTF::get<RefPtr<CanvasPattern>>(m_style);
}

inline String CanvasStyle::color() const
{
    auto& color = WTF::holds_alternative<Color>(m_style) ? WTF::get<Color>(m_style) : WTF::get<CMYKAColor>(m_style).color;
    return color.serialized();
}

} // namespace WebCore
