if (!require("jsonlite")) {
    install.packages("jsonlite")
    library("jsonlite")
}

computeScIAT = function(json) {
    res = data.frame(row.names = as.character(1:length(json)))
    res$SC.D = NA
    res$SC.D1 = NA
    res$SC.D2 = NA
    res$SC.D3 = NA
    
    
    computeDScore = function(b2, b4) {
        times2 = computeTimes(b2);
        times4 = computeTimes(b4);
        mean2 = computeMean(times2);
        mean4 = computeMean(times4);
        q = mean4 - mean2;  # MW(b5,b6,b7) - MW(b1,b2,b3)
        
        # "This quantity was divided by the standard deviation
        # of all correct response times within Blocks 2 and 4."
        bRel = rbind(b2, b4);
        timesC = computeTimesCorrect(bRel);
        sdC = sd(timesC);
        
        return (q / sdC);
    }
    
    computeFails = function(a) {
        fails = 0;
        for (i in 1:nrow(a)) {
            if (a[i,2] == 0) {
                fails = fails+1;
            }
        }
        return(fails);
    }
    
    computeMean = function(a) {
        sum = 0;
        len = 0;
        for (i in 1:length(a)) {
            if (a[i] != F) {
                sum = sum + a[i];
                len = len + 1;
            }
        }
        if (len == 0) {
            return(F);
        }
        return(sum / len);
    }
    
    computeTimes = function(a) {
        r = c();
        for (i in 1:nrow(a)) {
            if (a[i,1] == F) {
                r[i] = F;
            } else {
                r[i] = a[i,1];
            }
        }
        return(r);
    }
    
    computeTimesCorrect = function(a) {
        r = c();
        for (i in 1:nrow(a)) {
            if (a[i,2] == 1) {
                r = c(r, a[i,1]);
            }
        }
        return(r);
    }
    
    
    
    for (cs in 1:length(json)) {
        iatData = fromJSON(json[[cs]])
        res[cs,] = c(NA,NA,NA,NA)
        
        # Ensure every block is an array
        for (i in 1:8) {
            if (length(iatData[i,,]) == 0) {
                warning(paste("Notice: Missing block", i, "for SC-IAT in case", cs))
                iatData[i] = matrix(nrow=0, ncol=2)
            }
        }
            
        # D-Score based on Karpinski & Steinman
        # Using blocks 1,2,3 and 5,6,7
        # (skip trial blocks 0 and 4)
            
        # "Participants with an error rate greater than 20% ... were excluded from analysis"
        #  Note: Assume that error rate is computed for all blocks, incl. practice blocks
        bAll = rbind(
                 iatData[1,,],
                 iatData[2,,],
                 iatData[3,,],
                 iatData[4,,],
                 iatData[5,,],
                 iatData[6,,],
                 iatData[7,,],
                 iatData[8,,]
        )
        
        failRate = computeFails(bAll) / nrow(bAll)
        if (failRate > 0.2) {
            next;
        }
            
        # "Because the 24 practice trials in each stage were truly practice, data from the practice blocks were discarded"
        b = list(
            "1" = iatData[2,,],
            "2" = iatData[3,,],
            "3" = iatData[4,,],
            "4" = iatData[6,,],
            "5" = iatData[7,,],
            "6" = iatData[8,,]
        );
            
        bv = list();  # Valid responses
        bc = list();  # Valid responses with penalty
        for (bi in 1:length(b)) {
            bis = as.character(bi)
            bv[[bis]] = matrix(nrow=0, ncol=2);

            for (ti in 1:nrow(b[[bis]])) {
                trial = b[[bis]][ti,];
                # "Responses less than 350 ms were eliminated"
                if (trial[1] < 350) {
                    next;
                }
                # "nonresponses were eliminated"
                if (trial[2] == 2) {
                    next;
                }
                # otherwise use
                bv[[bis]] = rbind(bv[[bis]], trial);
            }
            # "error responses were replaced with the block mean plus an error penalty of 400 ms."
            # Need the block mean
            # Note: Assume that the block mean is computed on all responses (incl. fails but excl. nonresponses and <350 ms)
            times = computeTimes(bv[[bis]]);
            meanTime = computeMean(times);
            bc[[bis]] = matrix(nrow=0, ncol=2);
            for (ti in 1:nrow(bv[[bis]])) {
                trial = bv[[bis]][ti,];
                if (trial[2] == 0) {
                    bc[[bis]][ti,] = c(meanTime + 400, 0);
                } else {
                    bc[[bis]][ti,] = c(trial[1], 1);
                }
            }
        }
        
        # "The average response times of Block 2 were subtracted from the
        # average response times of Block 4."
        b2 = rbind(bc[["1"]], bc[["2"]], bc[["3"]]);
        b4 = rbind(bc[["4"]], bc[["5"]], bc[["6"]]);
        
        res[cs, "SC.D"] = computeDScore(b2, b4);
        res[cs, "SC.D1"] = computeDScore(bc[1], bc[4]);
        res[cs, "SC.D2"] = computeDScore(bc[2], bc[5]);
        res[cs, "SC.D3"] = computeDScore(bc[3], bc[6]);
    }
    
    return(res)
}

computeScIAT(data$AA45i0)
