#version 420 core
// UNIFORM BLOCK

#define USE_COLOR_PROP BOOL_COLOR_PROP
#define USE_OVERRIDE_NORMAL BOOL_OVERRIDE_NORMAL

#define WELL_GL_PATCH_SIZE 3
#define WELL_LOG_NO_VALUE (1e19)

layout(quads, equal_spacing, cw) in;

uniform vec4 cRadiusScale;
uniform vec3 cSceneScale;
uniform float proj33;
uniform float proj1length;
uniform vec3 uniOverrideNormal;

in vec4 outpos_ES_in[];
in vec2 outAziIncl_ES_in[];

#if USE_COLOR_PROP
in float outProp_ES_in[];
out float rLogValueTransferFunction;
#endif

out float rTexU;

out vec3 vDelta;
out vec3 vCenter;
out float vLength;

void main()
{
  float
    rIndex = gl_TessCoord.y * float(WELL_GL_PATCH_SIZE - 1);

  int
    iIndex = int(floor(rIndex + 0.01f));

  vec3
    cCurrVertex = outpos_ES_in[iIndex].xyz;

  vec2
    cAziIncl = outAziIncl_ES_in[iIndex];

#if USE_COLOR_PROP
  rLogValueTransferFunction = outProp_ES_in[iIndex];
#endif

  float
    rRadiusLog = outpos_ES_in[iIndex].w;

  float
    rInnerOuterRadiusFac = 1.0;

  // are we at novalue?
  if (rRadiusLog > WELL_LOG_NO_VALUE)
  {
    rInnerOuterRadiusFac = 0.0;

    int
      iReadIndex = iIndex;

    // get previous
    if (iIndex > 0)
    {
      rRadiusLog = outpos_ES_in[iIndex - 1].w;
      iReadIndex = iIndex - 1;
    }

    // If not valid, try to get next.
    if (rRadiusLog > WELL_LOG_NO_VALUE)
    {
      if (iIndex < (WELL_GL_PATCH_SIZE - 1))
      {
        rRadiusLog = outpos_ES_in[iIndex + 1].w;
        iReadIndex = iIndex + 1;
      }

      if (rRadiusLog > WELL_LOG_NO_VALUE)
      {
        rRadiusLog = 0.0;
      }
    }

    cCurrVertex = outpos_ES_in[iReadIndex].xyz;
    cAziIncl = outAziIncl_ES_in[iReadIndex];
#if USE_COLOR_PROP
    rLogValueTransferFunction = outProp_ES_in[iReadIndex];
#endif
  }

  vec2
    cAzimuthVector = vec2(sin(cAziIncl.x), cos(cAziIncl.x));

  mat3 
    cMat;

#if USE_OVERRIDE_NORMAL
  cMat[2] = uniOverrideNormal;
  cMat[0] = normalize(cross(cMat[2], vec3(0.0, 0.0, 1.0)));
  cMat[1] = normalize(cross(cMat[2], cMat[0]));
#else
  cMat[2] = normalize(vec3(cAzimuthVector.xy * sin(cAziIncl.y), -cos(cAziIncl.y))  / cSceneScale);
  cMat[0] = vec3(cAzimuthVector.y, -cAzimuthVector.x, 0.0);
  cMat[1] = cross(cMat[2], cMat[0]);
#endif
 

  // Handle novalues
  float
    rInnerRadius = cRadiusScale.x,
    rOuterRadius = cRadiusScale.w;

  float
    rFac = gl_TessCoord.x * 3.14159265 * 2.0;

  rFac -= 0.5 * 3.14159265;

  float
    rRadius = mix(rInnerRadius, rOuterRadius, rInnerOuterRadiusFac);
  
  vec2 cDir = vec2(sin(rFac), cos(rFac));

  //2DLOG code will be replace here

  vec3 cPos = cMat * vec3(cDir * rRadius, 0.0);

  cPos *= cSceneScale;
  cPos += cCurrVertex.xyz;

  vCenter = vec3(gl_ModelViewMatrix* vec4(cCurrVertex.xyz , 1.0));
  vDelta = vec3(gl_ModelViewMatrix * vec4(cPos.xyz, 1.0)) - vCenter;
  vLength = length(vDelta);
 
  gl_Position = gl_ModelViewProjectionMatrix * vec4(cPos, 1.0);

  // CLIPPLANE CODE


}
