@ctype mat4 mat4
@ctype vec4 vec4
@ctype vec3 vec3
@ctype vec2 vec2

@module forwardRender

@vs vs
#define NR_POINTLIGHTS 2
in vec4 v_position;
in vec4 v_color;
in vec4 v_norm;
in vec2 v_uv;

// in vec4 v_bone;
// in vec4 v_weight;

uniform vs_params {
  mat4 mvp;
  mat4 modelMatrix;
  mat4 viewMatrix;
  mat4 poseMatrixArray[32];

  vec4 mainColor;
  // vec3 playerPosition;
  // vec3 cameraPosition;
  vec3 fadePoint;

  // float playerSpeed;
  float wobble;
  float time;
  float skellyman;
  // float wire;
  float onion;
  float layer;
  float fadeDist;
  float outline;

  int vector;
};

out vec2 uv;
out vec4 color;
out vec3 normal;
out float pointFade;
out float vertexID;
out vec3 worldSpace;

void main(){
  vec4 vp = v_position;

  vertexID = float(gl_VertexIndex);

  if (outline>0){
    normal = vec3(0);//vec3(v_norm.xy,0);
    // vp.xyz += vec3((v_norm.xy+vec2(0.25))*vec2(1.5+sin(time*4)*0.2)*outline*2,0);
  }
  if (skellyman==1) {
    // mat4 a = poseMatrixArray[int(v_bone.x*255.0)] * v_weight.x +
    // poseMatrixArray[int(v_bone.y*255.0)] * v_weight.y +
    // poseMatrixArray[int(v_bone.z*255.0)] * v_weight.z +
    // poseMatrixArray[int(v_bone.w*255.0)] * v_weight.w;
    // mat4 skeleton = a;
    // vp = skeleton*vp;
  }

  // if (wobble>0) {
  //   vp[0] = vp[0]+sin(wobble+vp[0])*0.2;
  //   vp[1] = vp[1]+cos(wobble+vp[1])*0.2;
  //   vp[2] = vp[2]+sin(wobble+vp[2])*0.2;
  //   vp[3] = vp[3];
  // }

  pointFade = (fadeDist>1) ? (distance(fadePoint,vec3(modelMatrix*vp))+50)/fadeDist : 1;

  vec4 end = mvp*vp;
  
  if (layer>0){
    end.z+=layer*0.001;
  }

  color = mainColor* ((vector==1) ? (v_color/255):v_color);
  uv = (vector==1) ? v_norm.zw : v_uv;
  gl_Position = end;
}
@end

@fs fs
#define NR_POINTLIGHTS 2
in vec2 uv;
in vec4 color;
in vec3 normal;
in float pointFade;
in float vertexID;
in vec3 worldSpace;

out vec4 frag_color;  

uniform texture2D texture0;
uniform sampler smp;

uniform texture2D gradient;
uniform texture2D underlay;
uniform texture2D dynamicShadow;
uniform texture2D staticShadow;


uniform fs_params{
  vec3 colID;
  float select;
  float onion;
  float vector;
  float outline;
  float brush;
  vec4  tint;

  float sampleUnderlay;
  int drawingShadow;
  float stripe;
  float time;
  float alpha;
  float dither;
  float polka;
  vec2 canvasSize;
  int has_tex;
};

float stripeMul = 1;
mat4 thresholdMatrix = mat4(
1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
);

vec3 hsv2rgb(vec3 c) {
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
float map(float value, float min1, float max1, float min2, float max2) {
  return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}

vec4 main0() {
  // TODO screen coords
  vec2 screen_coords = gl_FragCoord.xy*vec2(100,100);
  vec4 texel = (has_tex==1) ? texture(sampler2D(texture0,smp), uv):vec4(1);
  if (1==1){
    return texel*color;
  }
  if (outline>0){
    return vec4(hsv2rgb(vec3(sin(time*4)*0.1*cos(time*4)*0.2+0.58,0.8,1)),1);
  }

  if (sampleUnderlay>0){
    vec4 und = texture(sampler2D(underlay,smp), uv);
    return und;
    // if (und.a>0){
    //   return und;
    // }
  }
  
  if (drawingShadow==1) {
    if (texel.a==1){
      // return vec4(1);
    }else{
      // discard;
    }
  }

  stripeMul = 1;
  if (polka==0 && stripe!=0) {
    float strip = (screen_coords.x*2024+screen_coords.y*2024);
    stripeMul = fract(sin(strip+time));
    stripeMul = ((stripeMul+0.1)/1.1);
    if (stripe==-1) {
      return vec4(vec3(stripeMul),1);
    }else{
      stripeMul*=stripe;
      stripeMul-=0.5;
      return vec4(vec3(stripeMul),1);
    }
  }

  if (select==1) {
    // return vec4(colID[0],colID[1],colID[2],w>0 ? w : 1 );
  }

  if (onion>0) {
    texel.a = tint.a*color.a*texel.a;
    texel.rgb = ((color.rgb*texel.rgb+tint.rgb*3)/4);
    return texel;
  }

 
  if (dither>=1){
    if ((mod(int(gl_FragCoord.x),4) == 1) && (mod(int(gl_FragCoord.y),4) == 1)) {
      return vec4(1,1,1,1);
    }
  }else if (dither>0 ){
    if ((0 - thresholdMatrix[int(mod(screen_coords.x/2+time*dither,4))][int(mod(screen_coords.y/2+time*dither,4))] )+0.1>0){
      discard;
    }
  }

  vec3 result = texel.rgb*color.rgb;
  result =   stripeMul<1 ? result + vec3( (1.0/pow(4-length(result)+1,4))*10*stripeMul ) : result;
  float a = color.a*texel.a;
  // a=(a<0.5)?pow(a,1.1):1-pow(1-a,1.5);

  // if (brush>0){
  // }else if (vector>0){
  //   a=color.a;
  //   result=color.rgb;
  // }

  if (polka>0){
    // if (mod(screen_coords.x*100,2)==0) {
      // result.rgb = vec3(1);//-result.rgb;
    // }
     if ((0 - thresholdMatrix
        [int(mod(gl_FragCoord.x+stripe*time*4,4))]
        [int(mod(gl_FragCoord.y+stripe*time*4,4))] )+polka/2>0){
      result.rgb = ((vec3(1)-result.rgb)+result.rgb)/1;
    }
    // result.rg = vec2(screen_coords.x,screen_coords.y);
  }

  return vec4(result,a);
}

void main(){
  frag_color = main0();
}
@end

@program main vs fs

