### fn.variable.width.R
###------------------------------------------------------------------------------------------
### What: function to calculate variable width using format.info
###     : Number of decimal places should be considered while calculating the width of numeric values 
###     : if variable is factor, get the width of category values and get the max
### Time-stamp: <2018-6-28 11:08:27 panapps>
###-------------------------------------------------------------------------------------------

varibale.width <- function(variable,
                      type,  
                      catValues,                   
                      ...)
{
    ## --- Setup ---
    # if all values of that variable is NA then set length 1
    # when wrting to CSV we write all empty string or NA ('' | NA) to '*', when reading we convert * to NA
    if(all(is.na(variable))) {
        variable.length <- 1
    } else {        
        # TO DO: Check the internal logic of fn: format.info
        variable.length <- format.info(variable)
    }

    # If variable is a factor include category values in the width calculation
    if(!(is.na(catValues) || length(catValues) == 0)) {
        # calculate max of category value length
        # fomat.info is not used here, unicode issue may not come expecting category values as numeric
        catvalue.length <- max(nchar(as.character(catValues)), na.rm = TRUE)
        variable.length <- max(catvalue.length, variable.length)
    } 

    return (variable.length)    
}

format.num <- function( x,
                dcml=0,
                ...)
{
    
    # function to convert numeric vector to string format with correct decimal precisions 
    # to handle the scenario where dcml greater than the length of the variable   
    # for ex: value =  1, dcml = 2, then value will be converted to 1.00'  

    dcml <- as.numeric(dcml)

    # format function returns 'NA' and not na and the length of vector become 2 instead of 1
    # excluded na while applying format.
    is_na <- is.na(x)  
    # round to the number of decimal places if dcml > 0   
    if(dcml > 0) {  
        x[!is_na] <- format(round(x[!is_na],dcml),nsmall=dcml)
    } else {
        # remove trailing zeros, came from csv read with options digits=22
        # used format option digits=15 to make sure the precision is not lost for large numbers
        # using too large a value of digits may lead to representation errors in the calculation of the number of significant digits and the decimal representation: these are likely for digits >= 16
        x[!is_na] <- format(x[!is_na], digits=15, drop0trailing=TRUE)       
    }  

    # trim white spaces introduced by format fn, to get the exact width
    x <- trimws(x, which = c("both", "left", "right"))

    return (x);
}


