
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkLights_DEFINED
#define SkLights_DEFINED

#include "include/core/SkPoint3.h"
#include "include/core/SkRefCnt.h"
#include "include/private/SkTArray.h"

class SkReadBuffer;
class SkWriteBuffer;

/** \class SkLights
    SkLights encapsulates a set of directional, point and ambient lights for use with the
    SkLightingShader.
*/
class SK_API SkLights  : public SkRefCnt {
public:
    class Light {
    public:
        enum LightType {
            kDirectional_LightType,
            kPoint_LightType
        };

        Light(const Light& other)
                : fType(other.fType)
                , fColor(other.fColor)
                , fDirOrPos(other.fDirOrPos)
                , fIntensity(other.fIntensity) {}

        Light(Light&& other)
                : fType(other.fType)
                , fColor(other.fColor)
                , fDirOrPos(other.fDirOrPos)
                , fIntensity(other.fIntensity) {}

        static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir) {
            Light light(kDirectional_LightType, color, dir, 0.0f);
            if (!light.fDirOrPos.normalize()) {
                light.fDirOrPos.set(0.0f, 0.0f, 1.0f);
            }
            return light;
        }

        static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity) {
            return Light(kPoint_LightType, color, pos, intensity);
        }

        LightType type() const { return fType; }
        const SkColor3f& color() const { return fColor; }
        const SkVector3& dir() const {
            SkASSERT(kDirectional_LightType == fType);
            return fDirOrPos;
        }
        const SkPoint3& pos() const {
            SkASSERT(kPoint_LightType == fType);
            return fDirOrPos;
        }
        SkScalar intensity() const {
            SkASSERT(kPoint_LightType == fType);
            return fIntensity;
        }

        Light& operator=(const Light& other) {
            if (this == &other) {
                return *this;
            }

            fType = other.fType;
            fColor = other.fColor;
            fDirOrPos = other.fDirOrPos;
            fIntensity = other.fIntensity;
            return *this;
        }

        bool operator==(const Light& other) {
            return (fType      == other.fType) &&
                   (fColor     == other.fColor) &&
                   (fDirOrPos  == other.fDirOrPos) &&
                   (fIntensity == other.fIntensity);
        }

        bool operator!=(const Light& other) { return !(this->operator==(other)); }

    private:
        friend class SkLights;

        Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
              SkScalar intensity)
                : fType(type)
                , fColor(color)
                , fDirOrPos(dirOrPos)
                , fIntensity(intensity) {}

        LightType   fType;
        SkColor3f   fColor;           // linear (unpremul) color. Range is 0..1 in each channel.

        SkVector3   fDirOrPos;        // For directional lights, holds the direction towards the
                                      // light (+Z is out of the screen).
                                      // If degenerate, it will be replaced with (0, 0, 1).
                                      // For point lights, holds location of point light

        SkScalar    fIntensity;       // For point lights, dictates the light intensity.
                                      // Simply a multiplier to the final light output value.
    };

    class Builder {
    public:
        Builder() : fLights(new SkLights) {}

        void add(const Light& light) {
            if (fLights) {
                fLights->fLights.push_back(light);
            }
        }

        void add(Light&& light) {
            if (fLights) {
                fLights->fLights.push_back(std::move(light));
            }
        }

        void setAmbientLightColor(const SkColor3f& color) {
            if (fLights) {
                fLights->fAmbientLightColor = color;
            }
        }

        sk_sp<SkLights> finish() {
            return std::move(fLights);
        }

    private:
        sk_sp<SkLights> fLights;
    };

    /** Returns number of lights not including the ambient light.

        @return number of lights not including the ambient light
    */
    int numLights() const { return fLights.count(); }

    /** Returns the index-th light.

        @param index  the index of the desired light
        @return       the index-th light
    */
    const Light& light(int index) const { return fLights[index]; }

    /** Returns the ambient light.

        @return the ambient light
    */
    const SkColor3f& ambientLightColor() const {
        return fAmbientLightColor;
    }

    /**
     *  Recreate an SkLights object that was serialized into a buffer.
     *
     *  @param  SkReadBuffer Serialized blob data.
     *  @return A new SkLights representing the serialized data, or NULL if the buffer is
     *          invalid.
     */
    static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);

    /**
     *  Serialize to a buffer.
     *
     *  @param  buffer the write buffer to write out to
     */
    void flatten(SkWriteBuffer& buf) const;

private:
    friend class SkLightingShaderImpl;

    SkLights() : fAmbientLightColor(SkColor3f::Make(0.0f, 0.0f, 0.0f)) {}

    SkTArray<Light> fLights;
    SkColor3f       fAmbientLightColor;

    typedef SkRefCnt INHERITED;
};

#endif
