/*
 *  SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org>
 *
 *  SPDX-License-Identifier: LGPL-2.1-or-later
 */

#ifndef RGBCOMPOSITEOPBUMPMAP_H
#define RGBCOMPOSITEOPBUMPMAP_H

#include <KoCompositeOpAlphaBase.h>

template<class _CSTraits>
class RgbCompositeOpBumpmap : public KoCompositeOpAlphaBase<_CSTraits, RgbCompositeOpBumpmap<_CSTraits>, true >
{
    typedef typename _CSTraits::channels_type channels_type;
    typedef typename KoColorSpaceMathsTraits<typename _CSTraits::channels_type>::compositetype compositetype;

public:

    RgbCompositeOpBumpmap(KoColorSpace *cs)
        : KoCompositeOpAlphaBase<_CSTraits, RgbCompositeOpBumpmap<_CSTraits>, true >(cs, COMPOSITE_BUMPMAP, KoCompositeOp::categoryMisc())
    {
    }

    inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha)
    {
        return qMin(srcAlpha, dstAlpha);
    }

    inline static void composeColorChannels(channels_type srcBlend,
                                            const channels_type *src,
                                            channels_type *dst,
                                            bool allChannelFlags,
                                            const QBitArray &channelFlags)
    {
        qreal intensity;

        // And I'm not sure whether this is correct, either.
        intensity = ((qreal)306.0 * src[_CSTraits::red_pos] +
                     (qreal)601.0 * src[_CSTraits::green_pos] +
                     (qreal)117.0 * src[_CSTraits::blue_pos]) / 1024.0;

        for (uint i = 0; i < _CSTraits::channels_nb; i++) {
            if ((int)i != _CSTraits::alpha_pos  && (allChannelFlags || channelFlags.testBit(i))) {
                channels_type srcChannel = (channels_type)(((qreal)
                                           intensity * dst[i]) / NATIVE_OPACITY_OPAQUE + 0.5);
                channels_type dstChannel = dst[i];

                dst[i] = KoColorSpaceMaths<channels_type>::blend(srcChannel, dstChannel, srcBlend);
            }
        }
    }

};

#endif
