#version 420 core
// UNIFORM BLOCK

#define USE_COLOR_PROP BOOL_COLOR_PROP

#define WELL_GL_PATCH_SIZE  16
#define WELL_LOG_NO_VALUE (1e19)
layout(quads, equal_spacing, cw) in;

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

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 vObjPos;
out float rDiscard;
out vec4 cUV;

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 = gl_TessCoord.x;
  
  rDiscard = 1.0;

  // are we at novalue?
  if (rRadiusLog > WELL_LOG_NO_VALUE)
  {
    rInnerOuterRadiusFac = 0.0;
    rDiscard = 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));

  vec3
    cView = gl_ModelViewMatrixInverse[3].xyz - cCurrVertex,
    cViewOrthographic = gl_ModelViewMatrixInverse[2].xyz;

  cView = mix(cView, cViewOrthographic, min(0.999999, proj33));

  mat3 
    cMat;

  cMat[2] = normalize(vec3(cAzimuthVector.xy * sin(cAziIncl.y), -cos(cAziIncl.y))  / cSceneScale);
  cMat[0] = normalize(cross(cMat[2], vec3(cView / cSceneScale) + vec3(1e-16)));
  cMat[1] = cross(cMat[2], cMat[0]);
 

  // radius
  float
    rInnerRadius = mix(cRadiusScale.x,cRadiusScale.y,rRadiusLog),
    rOuterRadius = mix(cRadiusScale.z,cRadiusScale.w,rRadiusLog);

  float
    rRadius = mix(rInnerRadius, rOuterRadius, rInnerOuterRadiusFac);

  //2DLOG code will be replace here

  // for line drawing

  rTexU = gl_TessCoord.x;

  cUV.xy = vec2(rInnerRadius, rOuterRadius);
  cUV.z = rRadius;
  cUV.w = 0.0;

  if (rInnerOuterRadiusFac > 0.5)
  {
    cUV.w = 1.0;
  }

  vec3 cPos = cMat * vec3(-rRadius, 0.0, 0.0);
  cPos *= cSceneScale;
  cPos += cCurrVertex;

  vObjPos = vec4(gl_ModelViewMatrix * vec4(cPos,1.0)).xyz;
  gl_Position = gl_ModelViewProjectionMatrix * vec4(cPos, 1.0);

  // CLIPPLANE CODE

}
