#ifndef _CHECKER_CG_
#define _CHECKER_CG_

#include "material.cg"

struct CheckerBlinn : Material {
    Blinn mats[2];
    float csize;

    bool isEven(float f) {
        float x = floor(f);
        float r = floor(f/2.f);
        return x == 2.f*r;
    }

    float checker(float csize, float3 p) {
        bool isx = isEven(p.x*csize);
        bool isy = isEven(p.y*csize);
        return ((isx && isy) || !(isx || isy));
    }

    float3 evaluate(vertexOutput IN, Light lights[]) {
        float3 result = 0;
        float3 Ln;
        float3 Nn = normalize(IN.Neye);
        float3 Vn = normalize(-IN.Peye);
        float  lval = checker(csize, IN.Pmodel);
        float3 ambient  = lerp(mats[0].ambient, mats[1].ambient, lval);
        float3 diffuse  = lerp(mats[0].diffuse, mats[1].diffuse, lval);
        float3 specular = lerp(mats[0].specular, mats[1].specular, lval);
        float3 sexp     = lerp(mats[0].sexp, mats[1].sexp, lval);
        for (int i = 0; i < lights.length; i++) {
            if (lights[i].isEnabled()) {
                float3 lcolor = lights[i].illuminate(IN.Peye, Ln);
                float3 Hn = normalize(Vn + Ln);
                float ldn = dot(Ln,Nn);
                float hdn = dot(Hn,Nn);
                float4 litV = lit(ldn, hdn, sexp);
                float3 diffContrib = lcolor * (diffuse * litV.y + ambient);
                float3 specContrib = litV.y*litV.z * lcolor * specular;
                result.rgb += diffContrib + specContrib;
            }
        }
        return result;
    }
};

#endif // _CHECKER_CG_
