# TODO: Add comment
# 
# Author: E.Korsching, 19.10.2011  2016
# Dependencies: agnes.cl, library("cluster"), library("mclust")
###############################################################################

local.cluster.optimum <- function(x, chunksize=3, overlap=0.5, ref, translation.tab){
	#x: global cluster matrix
	#chunksize: number of rows to be considered at once
	#overlap: 0..1: 0.5: 50%: forward step size of the gliding test window
	#ref: cluster order reference vec; categories
	# exactly the length of the variable$order vector produced by the given x matrix/data.frame
	#translation.tab: translation table for categories (i.e. grading) to col position numbers in matrix
	
	#ini
	require("mclust")
	
	nr <- nrow(x)
	nc <- ncol(x)
	frac.forward.step <- 1-overlap
	
	chunknumber <- floor(nr / chunksize)
	ch.rest <- nr - (chunknumber * chunksize)
	ch.step.size <- floor(chunksize * frac.forward.step) # floor supports the greater overlap in all cases
	if(ch.step.size<=1){ ch.step.size <- 1 } # min step =1
	cat("\n Used chunk number: ", chunknumber, ", chunk length: ", chunksize,
			" overlap: ", chunksize - ch.step.size, ", last chunk size: ", chunksize + ch.rest)
	
	
	# check global order and order length
	tmp1 <- agnes.cl(x,
			label=NULL,
			extension=F,
			dissmat="cor",
			cl.method="average",
			mirrorsym.sym=F,
			cex=0.6,
			jitter.on=F,
			plot=F)
	
	global.o.len <- length(tmp1$order)
	
	if( global.o.len != length(ref) ) { cat("\n reference vector has wrong length"); break }
	
	#create data structure
	#rows: pos1: ref order, pos2: global order, pos3..chunknumber+2: local orders
	#cols: pos1: meta-info compactness index, pos2..length(order)+1: order
	erg <- matrix(0,chunknumber+2,global.o.len+1)	#for category data
	#rows: pos1: ref order [no one here], pos2: global order [but no positions here], pos3..chunknumber+2: local orders
	#cols: pos1: chunk start position, pos2: chunk end position, pos3..length(order)+1: cluster $order order
	erg2 <- matrix(0,chunknumber+2,global.o.len+2)	#for meta data link
	
	#save link to meta data in initial data set
	erg2[2,3:(global.o.len+2)] <- tmp1$order
	#translate global initial order
	tmp2 <- translation.tab[order(tmp1$order),1]
	
	erg[1,2:(global.o.len+1)] <- ref
	erg[2,2:(global.o.len+1)] <- tmp2
	cat.stat <- category.basics(x=ref) # small statistics for categories
	erg[2,1] <- category.compactness(x=cat.stat, y=tmp2, non.cat.id=(-1))[1]
	
	#start analysis
	position <- 1
	for(i in 1:chunknumber){
		if(i==chunknumber) { chunksize <- chunksize + ch.rest }
		tmp1 <- agnes.cl(x=x[position:(position+chunksize-1),,drop=F],
			label=NULL,
			extension=F,
			dissmat="cor",
			cl.method="average",
			mirrorsym.sym=F,
			cex=0.6,
			jitter.on=F,
			plot=F)
		
		#save link to meta data in initial data set
		erg2[i+2,1] <- position # chunk start
		erg2[i+2,2] <- position+chunksize-1 # chunk end
		erg2[i+2,3:(global.o.len+2)] <- tmp1$order
		
		#translate global initial order
		tmp2 <- translation.tab[order(tmp1$order),1]
			
		erg[i+2,2:(global.o.len+1)] <- tmp2
		erg[i+2,1] <- category.compactness(x=cat.stat, y=tmp2, non.cat.id=(-1))[1] #adjustedRandIndex(tmp2, ref)
		
		position <- position + ch.step.size
	}
	
	return(list(erg,erg2))
}



