#version 150

struct vertex_fragment
 {
   vec4 Position;
   vec4 TexCoord;
   vec4 Pos;
   vec4 Color;
};


in vertex_fragment IN;
in vec3 fL;
in vec3 fV;
in vec4 ambient2;

struct llum
{
    vec4 pos;
    vec3 dir;
    vec4 int_ambient;
    vec4 int_difusa;
    vec4 int_especular;
    float ang;
};

struct material
{

    vec4 comp_ambient;
    vec4 comp_difusa;
    vec4 comp_especular;
    float coef;
};

uniform llum l;
uniform material matPrimari;
uniform material matSecundari;
uniform float a;
uniform float b;
uniform float c;
uniform vec4 obs;
uniform vec3 vrp;
uniform vec3 dirVec;

//uniform sampler1D texturaLut;
uniform sampler2D backface;
uniform sampler3D texturaVolum;
uniform sampler3D texturaMask;

uniform float stepsize;
uniform float umbralOpacitat;
uniform float anchura;
uniform float altura;
uniform float profundidad;
uniform float umbralSaturacio;
uniform int colorMode;
uniform int rcMode;
uniform float crem;

uniform float cx;
uniform float cy;
uniform float cz;
uniform float alpha;
uniform float k;
uniform bool background;

uniform vec4 colorMask;
out vec4 fColor;

bool mascara;

vec4 getColorSample(int mode, vec3 texCoord, vec4 colorMax){
    vec4 color = vec4(0.0,0.0,0.0,0.0);
    vec4 mask = vec4(0.0,0.0,0.0,0.0);

    color = texture(texturaVolum, texCoord);
    mask = texture(texturaMask, texCoord);

    float alfacolor = color.a;
    if (mask.x > 0.0){
        mascara = true;

        // mascara opaca sense blending
      //  color = vec4(cx,cy,cz,alpha);

        // mascara trasnparent sense blending
       // color= vec4(cx,cy,cz,0.0);

        // mascara transparent amb blending
      //  color = k*vec4(cx,cy,cz,0.0)+(1.0-k)*color;
     //   color.a= (1.0-k)*alfacolor;//color.a = k*0.0+(1.0-k)*alfacolor;

      // blending general
       color = k*vec4(cx,cy,cz,1.0)+(1.0-k)*color;// composar amb el color (blending a*color + (1-a)*(cx, cy,cz, alpha))
       color.a = k*alpha+(1.0-k)*alfacolor;
    }
    if(color.x < umbralSaturacio){
        color = vec4(1.0,1.0,1.0,0.0);
     //   color = vec4(0.0,1.0,0.0,1.0);
    }
    return color;
}

void main(void)
{

    mascara = false;
      vec4 start = IN.TexCoord; // the start position of the ray is stored in the texturecoordinate

      vec3 dir = vec3(0,0,0);
      float len = 0.0;
      dir = dirVec;
      len = length(normalize(dir.xyz));

     vec3 norm_dir = normalize(dir);
      float delta = stepsize;
      vec3 delta_dir = norm_dir * delta;
      float delta_dir_len = length(delta_dir);
      vec3 vec = vec3(start.x, start.y, start.z);
      vec4 col_acc = vec4(1,1,1,1);
      float alpha_acc = 1.0;
      float length_acc = 0;
      vec4 color_sample = vec4(0.0,0.0,0.0,0.0);

      float alpha_sample = 0.0;
      int i = 0;

      for(i; i < 1024; i++)
        {
          color_sample = getColorSample(colorMode, vec, color_sample);
           alpha_sample = color_sample.a*umbralOpacitat;
          //          alpha_sample = color_sample.a * umbralOpacitat * 128* (stepsize); //* 400.0*sqrt(3.0);
          col_acc   -= (1.0 - alpha_acc) * color_sample * alpha_sample; /** umbralOpacitat*//**128*/;
          alpha_acc = alpha_acc -(1.0-alpha_acc)*alpha_sample; //  alpha_acc += alpha_sample /*+ (1.0-alpha_acc)*alpha_sample*/;
          if (alpha_acc > 1.0 ) alpha_acc = 1.0;

          vec += delta_dir;
          length_acc += delta_dir_len;
          if(length_acc >= len || alpha_acc > 1.0) break; // terminate if opacity > 1 or the ray is outside the volume
          if((vec.x<0.00001 || vec.x>0.999999 || vec.y<0.00001 || vec.y>0.999999 ||
          vec.z<0.000001|| vec.z>0.999999) || alpha_acc > 0.99999999 ) break; // terminate

        }

}
