# TODO: Add comment
# 
# Author: E.Korsching 10.9.2009, 2023
###############################################################################

adaptScale <- function(x, minS=NULL, maxS=NULL, minT=1, maxT=4, r2int=F, verbose=F){
	# transform scale [it has limits if machine integer limits are touched]
	# linear scaling e.g. source scale: -2 to 1 -- transform scale to e.g. 1 to 2
	# minS,maxS: theoretical range of measurement
	#   useful if the observed values might not fill the known range
	# minT,maxT: theoretical target range
	# if minS / maxS is not defined, min / max will be based on the input data
	# r2int : after scaling round to next integer
	# column wise : apply(data,2,adaptScale,minT=0,maxT=4)
	
	if(is.null(minS)){ minS<-min(x, na.rm=T) }
	if(is.null(maxS)){ maxS<-max(x, na.rm=T) }
	
	if(verbose){ cat("\n linear scaling: min source ",minS," max source ",maxS," min target ",minT," max target ",maxT,"\n") }
	
	if(maxS-minS==0 | maxT-minT==0){
		cat("\n Error in input:  maxS-minS =0 and/or maxT-minT =0 \n")
		stop("\n minS: ", minS, " maxS: ", maxS, " minT: ", minT, " maxT: ", maxT)
	}
	
	y <- ((x-minS)*(maxT-minT)/(maxS-minS))+minT
	
	if(r2int){ y <- round(y, digits=0) }
	
	row.names(y) <- row.names(x)
	names(y) <- names(x)
	
	return(y)
}

#adaptScale(c(-1,2,4,5,7),minS=-1,maxS=7,minT=-1,maxT=1)
#adaptScale(c(-1,2,4,5,7),minS=-1,maxS=8,minT=-1,maxT=1)
#adaptScale(c(-1,2,4,5,7),minS=-1,maxS=7,minT=0,maxT=1)
#adaptScale(c(-1,2,4,5,7),minS=-1,maxS=7,minT=1,maxT=2)
#adaptScale(c(-1,-2,-4,-5,-7),minS=-7,maxS=-1,minT=1,maxT=2)



# https://www.rdocumentation.org/packages/SciencesPo/versions/1.3.5/topics/normalize
# package:SciencesPo (version 1.3.5), Unity-based normalization
# generalization: X′= a + (x−xmin)*(b−a) / (xmax−xmin)
# identical to my approach

