# Path: lib/colors.py
# def hls_blend(start, end, out, progress, mode, fade_length=1.0, ease_power=0.5):
#     p = abs(progress)
# 
#     startPower = (1.0 - p) / fade_length
#     startPower = clip(0.0, startPower, 1.0)
#     startPower = pow(startPower, ease_power)
# 
#     endPower = p / fade_length
#     endPower = clip(0.0, endPower, 1.0)
#     endPower = pow(endPower, ease_power)
# 
#     l1clipped = np.empty_like(start['light'])
#     l2clipped = np.empty_like(end['light'])
#     np.clip(start['light'],0,1,l1clipped)
#     np.clip(end['light'],0,1,l2clipped)
#     np.clip(start['sat'],0,1,start['sat'])
#     np.clip(end['sat'],0,1,end['sat'])
# 
#     startWeight = (1.0 - 2 * np.abs(0.5 - l1clipped)) * start['sat']
#     endWeight = (1.0 - 2 * np.abs(0.5 - l2clipped)) * end['sat']
# 
#     s = (start['sat'] * startPower + end['sat'] * endPower)
#     x1 = np.cos(2 * np.pi * start['hue']) * startPower * startWeight
#     x2 = np.cos(2 * np.pi * end['hue']) * endPower * endWeight
#     y1 = np.sin(2 * np.pi * start['hue']) * startPower * startWeight
#     y2 = np.sin(2 * np.pi * end['hue']) * endPower * endWeight
#     x = x1 + x2
#     y = y1 + y2
# 
#     if progress >= 0:
#         l = np.maximum(start['light'] * startPower, end['light'] * endPower)
#         opposition = np.sqrt(np.square((x1-x2) / 2) + np.square((y1-y2) / 2))
#         if mode == 'multiply':
#             l = np.minimum(start['light'] * startPower, end['light'] * endPower)
#             #l -= opposition
#         elif mode == 'add':
#             l = np.maximum(l, opposition, l)
#     else: # hacky support for old blend
#         l = np.sqrt(np.square(x) + np.square(y)) / 2
# 
#     h = np.arctan2(y, x) / (2*np.pi)
# 
#     nocolor = (x * y == 0)
#     np.where(nocolor, h, 0)
#     np.where(nocolor, s, 0)
# 
#     np.clip(l, 0, 1, l)
# 
#     if out is None:
#         out = np.empty_like(start)
# 
#     out['hue'] = h
#     out['light'] = l
#     out['sat'] = s
# 
#     return out
# 
# Path: lib/transition.py
# class Transition(object):
#     """
#     Defines the interface for a transition.
# 
#     Given two numpy arrays and a progress (0 to 1.0), it produces one output array.
#     """
# 
#     def __init__(self, app):
#         self._app = app
# 
#     def __repr__(self):
#         """
#         Override this with the screen-friendly name of your transition
#         """
#         return "Transition"
# 
#     def setup(self):
#         """
#         This method will be called once when the transition is loaded
#         """
#         pass
# 
#     def reset(self):
#         """
#         This method will be called right before the transition is scheduled to start.
#         """
#         pass
# 
#     def render(self, start, end, progress, out):
#         """
#         This method will render a frame to `out` that is between `start` and
#         `end`, according to `progress`
#         """
#         pass


import numpy as np
from lib.colors import hls_blend
from lib.transition import Transition
#
# Copyright 2013-2016 Jonathan Evans <jon@craftyjon.com>
#
# Firemix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Firemix 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Firemix.  If not, see <http://www.gnu.org/licenses/>.



class MultiplyBlend(Transition):
    """
    This approximates color subtraction for the HLS color space.
    """

    def __init__(self, app):
        Transition.__init__(self, app)

    def __str__(self):
        return "Multiply Blend"

    def render(self, start, end, progress, out):

# Path: lib/colors.py
# def hls_blend(start, end, out, progress, mode, fade_length=1.0, ease_power=0.5):
#     p = abs(progress)
# 
#     startPower = (1.0 - p) / fade_length
#     startPower = clip(0.0, startPower, 1.0)
#     startPower = pow(startPower, ease_power)
# 
#     endPower = p / fade_length
#     endPower = clip(0.0, endPower, 1.0)
#     endPower = pow(endPower, ease_power)
# 
#     l1clipped = np.empty_like(start['light'])
#     l2clipped = np.empty_like(end['light'])
#     np.clip(start['light'],0,1,l1clipped)
#     np.clip(end['light'],0,1,l2clipped)
#     np.clip(start['sat'],0,1,start['sat'])
#     np.clip(end['sat'],0,1,end['sat'])
# 
#     startWeight = (1.0 - 2 * np.abs(0.5 - l1clipped)) * start['sat']
#     endWeight = (1.0 - 2 * np.abs(0.5 - l2clipped)) * end['sat']
# 
#     s = (start['sat'] * startPower + end['sat'] * endPower)
#     x1 = np.cos(2 * np.pi * start['hue']) * startPower * startWeight
#     x2 = np.cos(2 * np.pi * end['hue']) * endPower * endWeight
#     y1 = np.sin(2 * np.pi * start['hue']) * startPower * startWeight
#     y2 = np.sin(2 * np.pi * end['hue']) * endPower * endWeight
#     x = x1 + x2
#     y = y1 + y2
# 
#     if progress >= 0:
#         l = np.maximum(start['light'] * startPower, end['light'] * endPower)
#         opposition = np.sqrt(np.square((x1-x2) / 2) + np.square((y1-y2) / 2))
#         if mode == 'multiply':
#             l = np.minimum(start['light'] * startPower, end['light'] * endPower)
#             #l -= opposition
#         elif mode == 'add':
#             l = np.maximum(l, opposition, l)
#     else: # hacky support for old blend
#         l = np.sqrt(np.square(x) + np.square(y)) / 2
# 
#     h = np.arctan2(y, x) / (2*np.pi)
# 
#     nocolor = (x * y == 0)
#     np.where(nocolor, h, 0)
#     np.where(nocolor, s, 0)
# 
#     np.clip(l, 0, 1, l)
# 
#     if out is None:
#         out = np.empty_like(start)
# 
#     out['hue'] = h
#     out['light'] = l
#     out['sat'] = s
# 
#     return out
# 
# Path: lib/transition.py
# class Transition(object):
#     """
#     Defines the interface for a transition.
# 
#     Given two numpy arrays and a progress (0 to 1.0), it produces one output array.
#     """
# 
#     def __init__(self, app):
#         self._app = app
# 
#     def __repr__(self):
#         """
#         Override this with the screen-friendly name of your transition
#         """
#         return "Transition"
# 
#     def setup(self):
#         """
#         This method will be called once when the transition is loaded
#         """
#         pass
# 
#     def reset(self):
#         """
#         This method will be called right before the transition is scheduled to start.
#         """
#         pass
# 
#     def render(self, start, end, progress, out):
#         """
#         This method will render a frame to `out` that is between `start` and
#         `end`, according to `progress`
#         """
#         pass


# Path: plugins/multiply.py
import numpy as np
from lib.colors import hls_blend
from lib.transition import Transition

#
# Copyright 2013-2016 Jonathan Evans <jon@craftyjon.com>
#
# Firemix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Firemix 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Firemix.  If not, see <http://www.gnu.org/licenses/>.



class MultiplyBlend(Transition):
    """
    This approximates color subtraction for the HLS color space.
    """

    def __init__(self, app):
        Transition.__init__(self, app)

    def __str__(self):
        return "Multiply Blend"

    def render(self, start, end, progress, out):

        hls_blend(start, end, out, progress, 'multiply', 0.5, 0.5)