Write-Pretty--v1-0.psm1

$FunctionScriptName = "Write-Pretty--v1-0"
Write-Verbose "Import-Start| [$($FunctionScriptName)]"

function Write-Pretty {
    <#
    .SYNOPSIS
    Prettyfy human readable output
     
    .DESCRIPTION
    Formats Output and put it in a box
     
    Defaults:
        Pre/Suffix: "##"
        lineChar: '-'
        Header: None
        Out-Host
     
    .PARAMETER Message
    The text - Array is fine
 
    .PARAMETER Input
    Same as Message - just piped
     
    .PARAMETER prefix
    Prefix before each line
    Multiple characters possible
    Default: '##'
     
    .PARAMETER suffix
    Suffix after each line
    Multiple characters possible
    Default: '##'
     
    .PARAMETER lineChar
    Filler character in First / Last row
    Multiple characters possible
    Default: '-'
 
    .PARAMETER Header
    Source of the data
    Will be listed in first row after Start
     
    .PARAMETER ShortHeader
    Source of the data - Short form
    If Header & ShortHeader is provided - only Short will be in brackets
     
    .PARAMETER HeaderPrefix
    Prefix directly infront of the Header
    Default: 'Source:'
     
    .PARAMETER HeaderSuffix
    Suffix directly behind the Header
    Default: ''
 
    .PARAMETER HeaderVersion
    Suffix directly behind the Header & HeaderSuffix
    Default: ''
 
    .PARAMETER HeaderVersionPrefix
    Prefix before HeaderVersion
    Default: 'v'
 
    .PARAMETER HeaderinBrackets
    Puts Header in '[ ]'
 
    .PARAMETER HeaderNoSpaces
    No spaces between Headerpre/suffix
     
    .PARAMETER OutputNoSpaces
    No extra spaces between pre/suffix and text
     
    .PARAMETER FirstLastNoSpaces
    No extra spaces between pre/suffix and First / Last row
     
    .PARAMETER FirstLastNoPreSuffix
    No Pre/Suffix on First / Last row
     
    .PARAMETER FirstLastSkip
    No First / Last row
         
    .PARAMETER OutOutput
    Outputs in 'Write-Output'
     
    .PARAMETER OutHost
    Outputs in 'Write-Host'
     
    .PARAMETER OutVerbose
    Outputs in 'Write-Verbose'
     
    .PARAMETER OutDebug
    Outputs in 'Write-Debug'
     
    .PARAMETER OutInformation
    Outputs in 'Write-Information'
     
    .PARAMETER OutVar
    Outputs in return
     
    .PARAMETER OutConfig
    Config var that sets the param - Overrides direct param
    Default: $OutConfig
        e.G.: $OutConfig.OutVar = $True
     
    Extra switch param can be added
 
    .PARAMETER ignoreConfig
    ignores provided Config - only use direct and default param
 
    .PARAMETER EmptyLinesBeforeAfter
    Adds 1 empty line before and after the First/Last line
     
    .EXAMPLE
    $text = @("Hello","World")
    $text | Write-Pretty -OutHost -OutDebug
    $text | Write-Pretty -Header "MyRunbook" -HeaderSuffix "Version: 1.0"
    $text,$text2 | Write-Pretty -Header "Header"
 
    Output:
        ## --------------------##
        ## Source: [MyRunbook] ##
        ## $Text1 input ##
        ## $Text2 input ##
        ## --------------------##
 
    .NOTES
    AUTHOR: Ken Dobrunz // Ken.Dobrunz@Direkt-Gruppe.de | Direkt Gruppe
    WEBSITE: http://kensmagic.site
 
    LASTEDIT: 30.05.2020
    #>

    [cmdletbinding()]
    Param(
        # Pipe or direct vars
        [parameter(ValueFromPipeline)]$pipe,
        [parameter()]$message,

        [Parameter()]$prefix = "##",
        [Parameter()]$suffix = "##",
        [Parameter()]$lineChar = "-",

        #* Header
        [Parameter()]$Header, 
        [Parameter()][Alias('ID')]$ShortHeader,
        [Parameter()]$HeaderPrefix = "Source:",
        [Parameter()]$HeaderSuffix = "",
        [Parameter()][Alias('Version')]$HeaderVersion = "",
        [Parameter()][Alias('VersionPrefix')]$HeaderVersionPrefix = "v",
        [Parameter()][switch]$HeaderinBrackets,
        [Parameter()][switch]$HeaderNoSpaces,


        #* Output param
        [Parameter()][switch]$OutputNoSpaces,

        [Parameter()][switch]$FirstLastNoSpaces,
        [Parameter()][switch]$FirstLastNoPreSuffix,
        [Parameter()][switch]$FirstLastSkip,

        #* Output selectors
        [Parameter()][switch]$OutOutput,
        [Parameter()][switch]$OutHost,
        [Parameter()][switch]$OutVerbose,
        [Parameter()][switch]$OutDebug,
        [Parameter()][switch]$OutInformation,
        [Parameter()][switch]$OutVar,

        #* Config
        [Parameter()]$OutConfig = $OutConfig,
        [Parameter()][switch]$ignoreConfig,
        [Parameter()][switch]$EmptyLinesBeforeAfter
    )
    begin {
        Write-Debug "[WOPretty] Start pretty output"

        #* Check param
        $OutVars = @($OutOutput, $OutHost, $OutVerbose, $OutDebug, $OutInformation, $OutVar)
        if (!($OutVars) -and !$OutConfig) { 
            $OutHost = $true
        } elseif ($OutConfig -and !$ignoreConfig) {
            $OutConfig.Keys | ForEach-Object {
                Set-Variable -Name $_ -Value $OutConfig.$_
            }
        }

        #* Set arrays
        $maxChar = @()
        $out = @()
        $return = @()

        #* Set Header
        if ($Header -or $ShortHeader) {
            $space = if ($OutputNoSpaces) { "" } else { " " }
            $Hspace = if ($HeaderNoSpaces) { "" } else { " " }
            $Hpre = $prefix + $space + $HeaderPrefix + $Hspace
            if ($HeaderinBrackets -and $Header -and !$ShortHeader) { $Header = "[" + $Header + "]" }
            if ($HeaderinBrackets -and $ShortHeader) { $ShortHeader = "[" + $ShortHeader + "]" }
            if ($Header -and $ShortHeader) { $ShortHeader = $Hspace + $ShortHeader }

            if ($HeaderVersionPrefix -and $HeaderSuffix) { $HeaderVersionPrefix = $Hspace + $HeaderVersionPrefix }
            $HVersion = if ($HeaderVersion) { $HeaderVersionPrefix + $HeaderVersion }

            $pret = $Hpre + $Header + $ShortHeader + $Hspace + $HeaderSuffix + $HVersion
            $out += $pret
            $maxChar += ($pret | Measure-Object -Character).Characters
        }
    }
    process {
        if ($message) { $pipe = $message; $message = $null }
        $pipe | ForEach-Object {
            $space = if ($OutputNoSpaces) { $null } else { " " }
            $pret = $prefix + $space + $input
            $out += $pret
            $maxChar += ($pret | Measure-Object -Character).Characters
        }
    }
    end {
        #* Set count vars
        $countprefix = ($prefix | Measure-Object -Character).Characters
        $countsuffix = ($suffix | Measure-Object -Character).Characters
        $countlineChar = ($lineChar | Measure-Object -Character).Characters
        $countOutMax = ($maxChar | Measure-Object -Maximum).Maximum

        #* Set/Count Suffix for OUT
        $outSuffix = if ($suffix) { $space + $suffix } else { $null }
        $countOutSuffix = ($outSuffix | Measure-Object -Character).Characters

        if (!$FirstLastSkip) {
            #* Set FirstLast
            $FLspace = if ($FirstLastNoSpaces -or $OutputNoSpaces -or $FirstLastNoPreSuffix) { $null } else { " " }
            $FLprefix = if ($FirstLastNoPreSuffix) { $null } else { $prefix }
            $FLsuffix = if ($FirstLastNoPreSuffix) { $null } else { $suffix }

            $FLAddChars = $countOutMax + $countOutSuffix
            if ($FLspace -and $FLprefix) { $FLAddChars = $FLAddChars - 1 }
            if ($FLspace -and $FLsuffix) { $FLAddChars = $FLAddChars - 1 }
            if ($FLprefix) { $FLAddChars = $FLAddChars - $countprefix }
            if ($FLsuffix) { $FLAddChars = $FLAddChars - $countsuffix }

            $FLAddInstances = if ($countlineChar -gt 1) { [math]::floor($FLAddChars / $countlineChar) } else { $FLAddChars }

            $FirstLast = $FLprefix + $FLspace + ($lineChar * $FLAddInstances) + $FLspace + $FLsuffix    
        }

        #* create return var
        if ($EmptyLinesBeforeAfter) { $return += " " }
        $return += $FirstLast
        if (!$outSuffix) {
            $return += $out
        } else { 
            $out | ForEach-Object {
                $outaddchars = $countOutMax - (($_ | Measure-Object -Character).Characters)
                $return += $_ + (" " * $outaddchars) + $outSuffix
            }
        }
        $return += $FirstLast
        if ($EmptyLinesBeforeAfter) { $return += " " }

        #* Output
        if ($OutOutput) { $return | Write-Output }
        if ($OutHost) { $return | Write-Output }
        if ($OutVerbose) { $return | Write-Verbose }
        if ($OutDebug) { $return | ForEach-Object { Write-Debug -Message $_ } }
        if ($OutInformation) { $return | ForEach-Object { Write-Information -Message $_ } }
        if ($OutVar) { return $return }

        Write-Debug "[WOPretty] END pretty output"
    }
} #v1.0

Export-ModuleMember -Function *
Write-Verbose "Import-END| [$($FunctionScriptName)]"