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 + 0.5*256.0);
    return vec4(scalar);
    //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 && 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 =  src + dst*src.a ;

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

            pos += stepVector;
            rayLength -= stepsize;
        }

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


        // gl_FragColor = vec4(gl_TexCoord[0].xyz,1);
        //gl_FragColor = vec4(vec3(count),1);
        //gl_FragColor = vec4(normalize(step),1);
        //gl_FragColor = vec4(normalize(gl_ModelViewProjectionMatrixInverse*vec4(0,1,0,0.0)));
        //gl_FragColor = vec4(texture3D(volumeData,vec3(front.xy,0.5)).x);
    }
}


