# TODO: Add comment
# 
# Author: E.Korsching 11.2022
# Dependencies: plot.bar.point.segment
###############################################################################


hist.plot.p.l.curve <- function(x, x.range=NULL, bin.num=10, norm=F, lty=1, lwd=1, type="l",
		xlab="", ylab="", xlim=NULL, y.max=NULL, x.at=NULL, y.at=NULL, ylog=F, offset=0, digits=2,
		col.f="blue", cex=1, p.cex=1, pch=20, h.title="", add=F, rC=F){
	# will apply bin() and plot a point or line or spline curve  (not for categorical variables)
	# x: vector of values (normally a not bin_ed raw data collection)
	# x.range: NULL: data range by x -else- assumed data range of x,  xlim: plot range
	# bin.num: number of intervals see - bin() sort increasing
	# norm: normalization to sum=1
	# line-type: lty,  line-width: lwd,  (graph)type: l: line, p: point, spl: spline line, or: a pch number
	# xlab,ylab: axis label,  y.max: set max y scale value,  x.at,y.at: tick positions and at the same time text
	# offset: free place on the left and right from the distribution
	# digits: decimal digits on the x/y scale label,  cex: character size
	# col.f: curve color  you might select by  palette()[i]
	# h.title: title,  add: T: the bars or lines will be added to the active plot
	# rC:T: return bin counts
	
	# density: via:  dx <- density(x); plot(dx, lwd=2, col="blue"); rug(jitter(x))
	
	# ini
	if(mode(x)=="character"){ stop("stop -real values assumed-  \n") }
	source("../0functions/0general/bin.R")
	
	# apply bin() function
	tmp <- bin(x=x, x.range=x.range, bin.num=bin.num)
	erg <- tmp[[1]]		# matrix: counts,start,end
	bin.num <- tmp[[2]]["bin.n"]
	min.x <- tmp[[2]]["min"]			# x : range of values
	max.x <- tmp[[2]]["max"]
	diff.x <- tmp[[2]]["range.eff"]
	
	# total counts    -- check count size
	dist.sum <- sum(erg[,1])
	cat("\n Total counts of histogram : ",dist.sum)			# not full area
	cat("\n Bin number : ",bin.num,"\n")
	
	# normalize distribution, all counts =1
	if(norm){
		erg[,1] <- erg[,1]/dist.sum
	}
	# y log scale
	if(ylog){
		sylog <- erg[,1]<1
		if(sum(sylog>0)){
			warning(paste("bin content smaller 1 - set to 1",sep=""))
			erg[sylog, 1] <- 1
			erg[,1] <- log(erg[,1], base=10)
		}
	}
	min.y <- min(erg[,1])		# y
	max.y <- max(erg[,1])
	
	# plot
	if(is.null(xlim)){
		xlim <- c(min.x-offset, max.x+offset)				# set x range + offset
	}else{
		xlim <- c(xlim[1]-offset, xlim[2]+offset)
	}
	ylim <- c(0, if(is.null(y.max)){ max.y }else{ y.max })		# set y range
	# axis labels
	if(xlab==""){
		xlab <- paste( deparse(substitute(x)), collapse="" )	# data name
		xlab.len <- nchar(xlab)
		if(xlab.len>20){ xlab <- paste(substr(xlab, start=1, stop=20),".. ; ") }	# restrict to 20 character
	}
	if(ylab==""){
		if(ylog){
			if(norm){ ylab="log10(norm_counts)" }else{ ylab="log10(counts)" }
		}else{
			if(norm){ ylab="norm_counts" }else{ ylab="counts" }
		}
	}
	
	# define plot area and layout
	if(!add){	# not for add
		plot(c(0, 1), c(0, 1), type="n", xlim=xlim, ylim=ylim, axes=F, xlab=xlab, ylab=ylab, cex.lab=cex)
		if(is.null(x.at)){
			axis(1, at=c(round(min.x,digits=digits), round(min.x+(diff.x/3),digits=digits), round(min.x+(diff.x/3*2),digits=digits), round(max.x,digits=digits)), cex.axis=cex )
		}else{
			axis(1, at=x.at, cex.axis=cex)
		}
		if(is.null(y.at)){
			tmp <- c(ylim[1], ylim[2]/2, ylim[2])
			axis(2, at=tmp, labels=paste(round(tmp,digits=digits),sep=""), adj=0.5, srt=90, cex.axis=cex)
		}else{
			axis(2, at=y.at, labels=y.at, adj=0.5, srt=90, cex.axis=cex)
		}
	}
	
	# plot curve
	ra <- as.vector( ((erg[,3]-erg[,2])/2)+erg[,2] )
	if(type=="l"){
		lines(x=ra, y=erg[,1], col=col.f, lty=lty, lwd=lwd)
	}
	if(type=="p"){
		points(x=ra, y=erg[,1], col=col.f, cex=p.cex, pch=pch)
	}
	if(type=="spl"){
		lines(spline(x=ra, y=erg[,1]), col=col.f, lty=lty, lwd=lwd)		# normal spline fn
	}
	if(is.numeric(type)){	# pch number
		points(x=ra, y=erg[,1], col=col.f, lty=lty, lwd=lwd, pch=type)
	}
	# title and text
	mtext(text=h.title, line=2.2, side=3, cex=cex*0.9)
	
	if(rC){
		return(erg[,1])		# raw counts
	}else{
		return()
	}
}




