import os
import sys

from bge import logic

from . import custom_shader_base

shader_utils = custom_shader_base.shader_utils
shader_lib = custom_shader_base.shader_lib

       
class WindShader(custom_shader_base.CustomShader):
    """Create a wind shader for a material."""
    
    def __init__(self, material, texture=None, scale=[1, 1], vertex_lighting=False, normalmap=None, normal_factor=0.0):
        super().__init__(material)
        self.texture = texture
        self.normalmap = normalmap
        self.normal_factor = normal_factor
        self.scale = scale       
        
        # Set shaders            
        self._vertex_lighting = vertex_lighting     
        if not self._vertex_lighting:            
            if normalmap != None:
                vs = open(shader_lib + "wind_pixel_lighting_normal.vert").read()
                if texture != None:
                    fs = open(shader_lib + "wind_pixel_lighting_normal.frag").read()
                else:
                    fs = open(shader_lib + "wind_pixel_lighting_color_normal.frag").read()

            else:
                vs = open(shader_lib + "wind_pixel_lighting.vert").read()
                if texture != None:
                    fs = open(shader_lib + "wind_pixel_lighting.frag").read()
                else:
                    fs = open(shader_lib + "wind_pixel_lighting_color.frag").read()
        
        else:
            vs = open(shader_lib + "wind_vertex_lighting.vert").read()
            if texture != None:             
                fs = open(shader_lib + "wind_vertex_lighting.frag").read()
            else:
                fs = open(shader_lib + "wind_vertex_lighting_color.frag").read()
            
                    
        self.shader.setSource(vs, fs, True)
        
        # Set uniforms
        self.shader.setUniformDef('time', logic.CONSTANT_TIMER)
        self.shader.setUniformDef('ModelMatrix', logic.MODELMATRIX)
        self.shader.setUniformDef('ViewMatrix', logic.VIEWMATRIX)
        
        if normalmap != None:
            self.shader.setAttrib(logic.SHD_TANGENT)
            self.shader.setSampler('normalmap', self.normalmap)
            self.shader.setUniform1f('normalFactor', self.normal_factor)
            self.shader.setUniform2f('scale1', *self.scale) 
        
        if texture != None:
            self.shader.setSampler('diffuse1', self.texture)
            self.shader.setUniform2f('scale1', *self.scale)     
        
        # Initialise wind uniforms
        self._strength = 1.0
        self._speed = 1.0
        self.direction = [0, 1]
        self._deforming = 0.0
        self._bending = 0.0
        self._ground = 0.0 
        
        self.shader.setUniform1f('strength', self.strength)
        self.shader.setUniform1f('speed', self.speed)
        self.shader.setUniform2f('direction', *self.direction)
        self.shader.setUniform1f('deforming', self.deforming)
        self.shader.setUniform1f('bending', self.bending)
        self.shader.setUniform1f('ground', self.ground)

    @property
    def strength(self):
        return self._strength

    @strength.setter
    def strength(self, value):
        self._strength = value
        self.shader.setUniform1f('strength', self._strength)
    
    @property
    def speed(self):
        return self._speed

    @strength.setter
    def speed(self, value):
        self._speed = value
        self.shader.setUniform1f('speed', self._speed)
    
    @property
    def deforming(self):
        return self._deforming

    @deforming.setter
    def deforming(self, value):
        self._deforming = value
        self.shader.setUniform1f('deforming', self._deforming)
    
    @property
    def bending(self):
        return self._bending

    @bending.setter
    def bending(self, value):
        self._bending = value
        self.shader.setUniform1f('bending', self._bending)
        
    @property
    def ground(self):
        return self._ground

    @ground.setter
    def ground(self, value):
        self._ground = value
        self.shader.setUniform1f('ground', self._ground)
    
    def update(self):
        """Update shader uniforms."""
        scene = logic.getCurrentScene()
        
        #shader_utils.update_mist(self.shader, scene)
        #shader_utils.update_ambient_color(self.shader, scene)
        if self.texture == None:
            shader_utils.update_diffuse_color(self.shader, self.material)
            
        shader_utils.update_world(self.shader, scene)
        shader_utils.update_emission(self.shader, self.material)
        shader_utils.update_specular(self.shader, self.material)        
        shader_utils.update_light_settings(self.shader, scene)      
        shader_utils.update_light_transform(self.shader, scene)
        