
/*
 * 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 "../private/SkTArray.h"
#include "SkPoint3.h"
#include "SkRefCnt.h"

class SkReadBuffer;
class SkWriteBuffer;
class SkImage;

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)
            , fShadowMap(other.fShadowMap)
            , fIsRadial(other.fIsRadial) {
        }

        Light(Light&& other)
            : fType(other.fType)
            , fColor(other.fColor)
            , fDirOrPos(other.fDirOrPos)
            , fIntensity(other.fIntensity)
            , fShadowMap(std::move(other.fShadowMap))
            , fIsRadial(other.fIsRadial)  {
        }

        static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir,
                                     bool isRadial = false) {
            Light light(kDirectional_LightType, color, dir, isRadial);
            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,
                               bool isRadial = false) {
            return Light(kPoint_LightType, color, pos, intensity, isRadial);
        }

        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;
        }

        void setShadowMap(sk_sp<SkImage> shadowMap) {
            fShadowMap = std::move(shadowMap);
        }

        SkImage* getShadowMap() const {
            return fShadowMap.get();
        }

        bool isRadial() const { return fIsRadial; }

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

            fColor = b.fColor;
            fType = b.fType;
            fDirOrPos = b.fDirOrPos;
            fIntensity = b.fIntensity;
            fShadowMap = b.fShadowMap;
            fIsRadial = b.fIsRadial;
            return *this;
        }

        bool operator== (const Light& b) {
            if (this == &b) {
                return true;
            }

            return (fColor     == b.fColor) &&
                   (fType      == b.fType) &&
                   (fDirOrPos  == b.fDirOrPos) &&
                   (fShadowMap == b.fShadowMap) &&
                   (fIntensity == b.fIntensity) &&
                   (fIsRadial  == b.fIsRadial);
        }

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

    private:
        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.
        sk_sp<SkImage> fShadowMap;
        bool        fIsRadial;        // Whether the light is radial or not. Radial lights will
                                      // cast shadows and lights radially outwards.

        Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
              SkScalar intensity = 0.0f, bool isRadial = false) {
            fType = type;
            fColor = color;
            fDirOrPos = dirOrPos;
            fIntensity = intensity;
            fIsRadial = isRadial;
        }
    };

    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;
    };

    int numLights() const {
        return fLights.count();
    }

    const Light& light(int index) const {
        return fLights[index];
    }

    Light& light(int index) {
        return fLights[index];
    }

    const SkColor3f& ambientLightColor() const {
        return fAmbientLightColor;
    }

    static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);

    void flatten(SkWriteBuffer& buf) const;

private:
    SkLights() {
        fAmbientLightColor.set(0.0f, 0.0f, 0.0f);
    }
    SkTArray<Light> fLights;
    SkColor3f fAmbientLightColor;
    typedef SkRefCnt INHERITED;
};

#endif
