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

class Node:
    __slots__ = '_subnodes'

    def __init__(self, *subnodes):
        self._subnodes = subnodes

    def draw(self, time):
        for subnode in self._subnodes:
            subnode.draw(time)

class SceneNode(Node):
    pass

class TextureNode(Node):
    __slots__ = '_textures'

    def __init__(self, textures, *subnodes):
        Node.__init__(self, *subnodes)
        self._textures = textures

    def draw(self, time):
        items = self._textures.items()
        for slot, texture in items:
            texture.select(slot)
        Node.draw(self, time)
        for slot, texture in items:
            texture.unselect(slot)

class ShaderNode(Node):
    __slots__ = '_shader'

    def __init__(self, shader, *subnodes):
        Node.__init__(self, *subnodes)
        self._shader = shader

    def draw(self, time):
        self._shader.select()
        Node.draw(self, time)
        self._shader.unselect()

class InputNode:
    __slots__ = '_shader', '_inputs'

    def __init__(self, shader, *inputs):
        self._shader = shader
        self._inputs = inputs

    def draw(self, time):
        shader = self._shader
        for input in self._inputs:
            input.set_inputs(shader)

class DrawNode:
    __slots__ = '_drawable'

    def __init__(self, drawable):
        self._drawable = drawable

    def draw(self, time):
        self._drawable.draw()

class FuncNode:
    __slots__ = '_func', '_params'

    def __init__(self, func, params):
        self._func = func
        self._params = params

    def draw(self, time):
        self._func(time, *self._params)
