library(foreach)
library(parallel)
library(doParallel)
library(raster)
library(rgeos)

print("Packages loaded")

PredExtr <- function(x.shp, myfunction=c("robust.mean", "robust.mode"), output,  toextract, typp=c("raster", "shp"), ncores){
  print("Loading data")
  print(toextract)
  if(typp=="raster"){ mypredictor <- raster(toextract)} else
    mypredictor <- readOGR(toextract)
  load(x.shp)

#  print("test, cutting to first 50 rows")
#  header.shp <- header.shp[1:50,]	
  robust.mean <- function(x){mean(x, rm.na=T)}
  robust.mode <- function(x){if(any(x!=0)) {
 	 a <- x[which(x!=0)] #exclude zero (i.e. NAs)
  	return(as.numeric(names(sort(table(a), decreasing=T))[1]))} else
	    return(NA)                          }

  print("go parallel")
  cl <- makeForkCluster(ncores, outfile="" )
  registerDoParallel(cl)

  print("start main foreach loop")
  if(typp=="raster"){
  out <- foreach(i=1:length(header.shp), .packages=c('raster'), .combine=rbind) %dopar% { 
    tmp <- raster::extract(mypredictor, header.shp[i,], 
                         buffer=min(10000,  max(250, header.shp@data$loc.uncert[i])), fun=robust.mean) 
    }
  write.csv(out, file = output)
  } else {
    ecoreg.out <- sp::over(x=header.shp, y=mypredictor) 
    toassign <- header.shp[which(is.na(ecoreg.out$ECO_NAME)),]
    
    nearestEcoreg <- foreach(i=1:length(toassign), .packages=c('raster'), .combine=rbind) %dopar% { 
      nearestEcoreg.tmp <- geosphere::dist2Line(toassign[i,], mypredictor)
      return(nearestEcoreg.tmp)
      }
    ecoreg.out[which(is.na(ecoreg.out$ECO_NAME)),] <- ecoreg@data[nearestEcoreg[,"ID"],]
    save(ecoreg.out, "../sPlot/_predictors/ecoreg.out.RData")
    } 
  }
}