uniform sampler2D Texture;
uniform sampler2D PickID;

uniform sampler2D StartRay;
uniform sampler2D StopRay;
uniform sampler3D volumeData;
uniform sampler1D transferData;

uniform mat4x4 NormalMatrix;

uniform bool MIP;

varying vec3 position;

float stepsize = 0.001;



vec4 transfer(float scalar){
    float pos = (scalar*255.0/256.0 + 1/256.0/2);
    //return vec4(scalar);
    //return vec4(pos);
    return texture1D(transferData,pos);
}

vec3 phong(vec3 color, vec3 normal){
    vec3 V = normalize(-position);
    vec3 N = normalize(normal);
    vec3 L = normalize(gl_LightSource[0].position.xyz-position);
    vec3 R = normalize(reflect(-L,N));

    vec4 diffuse = vec4(max(dot(L,N),0.0));
    float specular = pow(max(dot(R,V),0.0),16);

    return (color * diffuse+ color * specular);
}

vec3 volumeNormal(vec3 uvw){
    float stepsize = 0.01;
    vec4 res = vec4(
                texture3D(volumeData,uvw- vec3(stepsize,0,0)).r
                -texture3D(volumeData,uvw+ vec3(stepsize,0,0)).r,

                texture3D(volumeData, uvw- vec3(0,stepsize,0)).r
                -texture3D(volumeData, uvw+ vec3(0,stepsize,0)).r,

                texture3D(volumeData, uvw- vec3(0,0,stepsize)).r
                -texture3D(volumeData, uvw+ vec3(0,0,stepsize)).r
                , 0);
   res = NormalMatrix * res; //TODO Normal Matrix
    return normalize(res.xyz);

}

void main(void)
{
    vec3 front = texture2D(StartRay,gl_TexCoord[0].st).xyz;
    vec3 back = texture2D(StopRay,gl_TexCoord[0].st).xyz;

    if(front == back){
        gl_FragColor = vec4(texture2D(Texture,gl_TexCoord[0].st).xyz,1);
    }else{
        vec3 ray = back-front;
       // vec3 ray = front-back;
        float rayLength = length(ray);
        vec3 stepVector = stepsize * ray/rayLength;

        vec3 pos = front;
        vec4 dst = vec4(0);

        float maxfloat = 0;
        vec3 normalMax = vec3(0);

        while ((dst.a < 1 || MIP) && rayLength > 0) {

            float density = texture3D(volumeData, pos).x;
            maxfloat = max(density,maxfloat);

            vec4 src = transfer(density);
            vec3 normal = volumeNormal(pos);

            src.xyz = phong(src.xyz,normal);
           // src.rgb *= src.a;

           // dst = dst * (1.0f - src.a) + src;// * src.a;
           // dst = (1.0 - dst.a) * src + dst ;
            dst =  dst + src*src.a ;

            if(density>maxfloat){
                maxfloat = density;
                normalMax = normal;
            }

            pos += stepVector;
            rayLength -= stepsize;
        }

        if(MIP) {
            //gl_FragColor = vec4(maxfloat) ;
            gl_FragColor = vec4(transfer(maxfloat));
           // gl_FragColor = vec4(normalMax,1);
           // gl_FragColor = vec4(phong(transfer(maxfloat).xyz,normalMax),1) ;
        }else{
            gl_FragColor = dst;
        }


        //gl_FragColor = vec4(texture1D(transferData,front.x));

        //gl_FragColor = vec4(gl_TexCoord[0].xyz,1);
        //gl_FragColor = vec4(texture3D(volumeData,vec3(front.xy,0.5)).x);
    }
}


