functions/dev.ps1


#TODO process multiple months
#TODO test with positioning
Param(
    [datetime]$start = (Get-Date),
    [datetime[]]$highlightDates
)

#create a month object
$mo = $start.month
$yr = $start.year
$max = (Get-Culture).DateTimeFormat.Calendar.GetDaysInMonth($yr, $mo)
$end = Get-Date -Year $yr -Month $mo -Day $max

$dateTimeFormat = (Get-Culture).DateTimeFormat
$fd = $dateTimeFormat.FirstDayOfWeek.value__

$currentDay = $start
#Write-Host "Currentday initialized: $currentDay" -ForegroundColor green
$day0 = @()
$day1 = @()
$day2 = @()
$day3 = @()
$day4 = @()
$day5 = @()
$day6 = @()

#Write-Host "adjust for the beginning of the month"
#while ($currentDay.DayOfWeek -ne $dateTimeFormat.FirstDayOfWeek) {
while ($currentDay.DayOfWeek.value__ -ne $fd) {
    #Write-Host $currentDay.DayOfWeek -ForegroundColor green
    #Write-Host "Subtracting a day" -ForegroundColor yellow
    $currentDay = $currentDay.AddDays(-1)
}

#Write-Host "Current day is now $currentDay" -ForegroundColor cyan
While ($currentDay.date -le $end.date) {
    [datetime]$aDay = $currentDay
    Switch ($aDay.DayOfWeek.value__) {
        0 { $day0 += $aday }
        1 { $day1 += $aday }
        2 { $day2 += $aday }
        3 { $day3 += $aday }
        4 { $day4 += $aday }
        5 { $day5 += $aday }
        6 { $day6 += $aday }
    }
    $currentDay = $currentDay.AddDays(1)
}

#add enough days to finish the week
While ($currentDay.DayOfWeek.value__ -ne 0) {
    [datetime]$aDay = $currentDay
    #Write-Host "Adding $aday" -ForegroundColor MAGENTA

    Switch ($aDay.DayOfWeek.value__) {
        0 { $day0 += $aday }
        1 { $day1 += $aday }
        2 { $day2 += $aday }
        3 { $day3 += $aday }
        4 { $day4 += $aday }
        5 { $day5 += $aday }
        6 { $day6 += $aday }
    }
     $Currentday = $currentDay.AddDays(1)
}


if ($fd -eq 0) {

    $mo = [pscustomobject]@{
        PSTypeName = "PSCalendarMonth"
        Month      = "{0:MMMM}" -f $start
        Year       = $start.year
        D0        = $day0
        D1        = $day1
        D2        = $day2
        D3        = $day3
        D4        = $day4
        D5        = $day5
        D6        = $day6
    }
}
else {
    $mo = [pscustomobject]@{
        PSTypeName = "PSCalendarMonth"
        Month      = "{0:MMMM}" -f $start
        Year       = $start.year
        D1         = $day1
        D2         = $day2
        D3         = $day3
        D4         = $day4
        D5         = $day5
        D6         = $day6
        D0         = $day0
    }
}

$dow = $mo.psobject.Properties.name | Where-Object { $_ -notmatch "Month|Year" }

$abbreviated = (Get-Culture).DateTimeFormat.AbbreviatedDayNames

$days = @()
#write-host "building dayname header from $($abbreviated -join ',')"
if ($fd -eq 0 ) {
  for ($n = 0;$n -lt $abbreviated.count;$n++) {
        $d = $abbreviated[$n].padleft(4, " ")
        $days += "`e[1;4;36m$d`e[0m"
  }
}
else {
    for ($n = 1; $n -lt $abbreviated.count; $n++) {
        $d = $abbreviated[$n].padleft(4, " ")
        $days += "`e[1;4;36m$d`e[0m"
    }
     $d = $abbreviated[0].padleft(4, " ")
    $days += "`e[1;4;36m$d`e[0m"
}


$plainHead = "$($mo.Month) $($mo.Year)"
$head = "`e[93m$plainhead`e[0"
$dayhead = $days -join ' '

#write-host "Today is $((Get-Date).date)" -ForegroundColor magenta
$month = for ($i = 0; $i -lt 5; $i++) {
  # #Write-Host "I = $i" -ForegroundColor green
    $wk = for ($k = 0; $k -lt $dow.count; $k++) {
     # #Write-Host "K = $k" -ForegroundColor green
        $theDay = ($mo.$($dow[$k])[$i])
        if ($theDay) {
            $d = $theDay.day
            #Write-Host $theDay -ForegroundColor cyan
            $value = $d.tostring().padleft(4, ' ')
            if ($theDay.date -eq (Get-Date).date) {
                "`e[91m$Value`e[0m"
            }
            elseif ( $highlightDates -contains $theDay.date) {
                "`e[92m$Value`e[0m"
            }
            else {
                $value
            }
        }
    }
    $wk -join ' '
}


#writing a single string object
Function makemonth {
    #this is a hack function to write all the strings to the pipeline
    #separately
    [int]$pad = (40 - $plainhead.Length)/2 + 1
    $p = " "*$pad
    "`n$p$head`n"
    $dayhead
    $month
}
#join all the strings into a single string
makemonth | Out-String

<# #We may need to backpedal a bit if the first day of the month
            #falls in the middle of the week
            while ($currentDay.DayOfWeek -ne $dateTimeFormat.FirstDayOfWeek) {
                $currentDay = $currentDay.AddDays(-1)
            }
 
            #Prepare to store information about this date range
            Write-Verbose "Initializing currentweek"
            $currentWeek = New-Object -typename PsObject
            $dayNames = @()
            $weeks = @()
 
            Write-Verbose "Go until we've hit the end of the month."
            #Even once we've done that, continue until we fill up the week
            #with days from the next month.
            while (($currentDay -lt $start.AddMonths(1)) -or
                ($currentDay.DayOfWeek -ne $dateTimeFormat.FirstDayOfWeek)) {
                #Figure out the day names we'll be using to label the columns
                $dowlen = $dateTimeFormat.FirstDayOfWeek.length + 3
                $dayName = ("{0:ddd}" -f $currentDay).padleft($dowlen, ' ')
                if ($dayNames -notcontains $dayName) {
                    Write-Verbose "Adding $dayname"
                    $dayNames += $dayName
                }
 
                #Pad the day number for display, highlighting if necessary
                #get the length of the abbreviated weekday to know how much to pad
                $daypad = $daynames[0].length
 
                Write-Verbose "Padding $daypad"
                $displayDay = "{0,$daypad} " -f $currentDay.Day
 
                #See if we should highlight a specific date
                if ($highlightDates) {
                    $compareDate = New-Object DateTime $currentDay.Year, $currentDay.Month, $currentDay.Day
                    if ($highlightDates -contains $compareDate) {
                        $displayDay = "*" + ("{0,$($daypad-1)}" -f $currentDay.Day) + "*"
                    }
                }
 
                #Add in the day of week and day number as note properties.
                $currentWeek | Add-Member NoteProperty $dayName $displayDay
 
                # Write-Verbose "Move to the next day in the month"
                $currentDay = $currentDay.AddDays(1)
 
                #If we've reached the next week, store the current week
                #in the week list and continue on.
                if ($currentDay.DayOfWeek -eq $dateTimeFormat.FirstDayOfWeek) {
                    $weeks += $currentWeek
                    $currentWeek = New-Object -typename PsObject
                }
            }
 
            Write-Verbose "Format our weeks into a table"
            Write-Verbose ($weeks | Out-String)
            $calendar = $weeks | Format-Table -property $dayNames | Out-String
 
            Write-Verbose "Add a centered header"
            $width = ($calendar.Split("`n") | Measure-Object -Max Length).Maximum
            $header = "{0:MMMM yyyy}" -f $start
            Write-Verbose $header
            $padding = " " * (($width - $header.Length) / 2)
            #use this line to insert a blank line before the calendar
            Write-Verbose "Adding calendar"
            Write-Verbose $calendar
            $displayCalendar = " `n" + $padding + $header + "`n " + $calendar
 
            #use this line to not insert a blank line before the calendar
            #$displayCalendar = $padding + $header + "`n " + $calendar
            $displayCalendar.TrimEnd()
 #>