# ///////////////////////////////////
# ////////////// NOTES //////////////
# ///////////////////////////////////
#	
#	Reverting increased delay because of timing issues that need to be solved having to do with increased runtime. Causes script to run longer than expected and alters time per program
#	----Increased keystroke delay to 180ms as per agreement with Intel, via Mike Ash
#
#    Converted all paths to be relative to the Productivity.ps1 file. This should allow Rundown to use
#        the same scripts as the DAQ systems
#    
#    Added $ReplyAddress param to specify a different set of address to reply to as per PLE request.
#        ReplyAddress will default to $Address if not specified to maintain compatability with older setups.
#
#        Version #:        1.0.5
# 
# 
# ///////////////////////////////////
# ///////////////////////////////////
# ///////////////////////////////////

param(  [Int]$RunTime = 1000,
        [switch]$Debug,
        [switch]$screens,
        [switch]$Random,
        [switch]$Trace,
        [string]$TracePath = ".",
        [string]$Address,
        [string]$ReplyAddress = $Address
)

[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# ///////////////////////////////////
# ////////////// Vars ///////////////
# ///////////////////////////////////

$Global:Keycount = 0

$sw = [Diagnostics.Stopwatch]::StartNew()
$ExcelFileName = "TestBook.xlsx"
$PPTFileName = "sample.pptx"
$DocFileName = "test.docx"
$TextFilename = "WordContent.txt"
$CurrentPath = (split-path -parent $MyInvocation.MyCommand.Definition)   #Execution Location
$FilesPath = $CurrentPath + "\content\"   #Resource files location	# Assesment changes

#if($scripts -eq $null){$scripts = (split-path -Parent (split-path -parent $FilesPath)) + "\scripts"}
$scripts = Join-Path $PSSCriptRoot "scripts"	# Assesment changes

if ($TracePath -eq ".") {
    $TracePath = $CurrentPath
}
if (!(Test-Path $TracePath)) {
    Write-Host "Trace path $TracePath doesn't exist.  Creating."
    New-Item -ItemType Directory -Force -Path $TracePath
}

if (!$Random) {
    # Set random seed to constant, for life of powershell session.
    Get-Random -setSeed 0x89245365 | Out-Null
}

# ///////////////////////////////////
# //////////// FUNCTIONS ////////////
# ///////////////////////////////////

function start-trace {
    if ($Trace) {
        $fullpath = $CurrentPath + "\productivity_trace.wprp"
        wpr.exe -start $fullpath -filemode
    }
}

function stop-trace {
    param( [string]$file )
    if ($Trace) {
    	$fullpath = $Tracepath + "\" + $file
    	Write-Host "Saving: $fullpath"
        wpr.exe -stop $fullpath
    }
}

function mark-trace {
    param( [string]$comment )
    if ($Trace) {
        wpr.exe -marker "$comment"
    }
}

#Function requires browser to be open already and in focus, navigates to the page given
function go-to-webpage{
	param( [string]$website )
#	$website = $website.ToCharArray
	start-Sleep -m 500
    [System.Windows.Forms.SendKeys]::SendWait("^l")
	start-Sleep -m 500
	type-string -stringToType $website
	start-Sleep -m 500
	[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
    if($Debug){$Global:Keycount+=2}
}

#Types out the given string at normal human speed
function type-string{
	param( [string]$stringToType )
	$stringArray = $stringToType.ToCharArray()
	start-Sleep -m 1000
	For ($ii = 0; $ii -lt $stringArray.Count; $ii++){
        switch($stringArray[$ii]){
                # Handles all special characters
            "(" {[System.Windows.Forms.SendKeys]::SendWait("{(}")}
            ")" {[System.Windows.Forms.SendKeys]::SendWait("{)}")}
            "+" {[System.Windows.Forms.SendKeys]::SendWait("{+}")}
            "^" {[System.Windows.Forms.SendKeys]::SendWait("{^}")}
            "%" {[System.Windows.Forms.SendKeys]::SendWait("{%}")}
            "~" {[System.Windows.Forms.SendKeys]::SendWait("{~}")}
            default {[System.Windows.Forms.SendKeys]::SendWait($stringArray[$ii])}
        }

		# This delay determines The time between keystrokes (wpm)
        start-sleep -m 80
        
		if($stringArray[$ii] -eq "." -and $stringArray[$ii + 1] -eq " "){
            start-sleep -m 2000
        }
	}
    if($Debug){$Global:Keycount+=$stringArray.Count}
}

#Forward the given email to the address specified with the given message Body
function Forward_Email{
	param( [string]$PathToEmail,
		[string]$AddressToSendTo,
		[string]$Body
	)
	
	start $PathToEmail
	Start-Sleep -s 5
	
	[System.Windows.Forms.SendKeys]::SendWait("^f")
	Start-Sleep -s 2
	
	type-string($AddressToSendTo)
	Start-Sleep -s 1
	[System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}")
	
	Start-Sleep -s 1
	type-string($Body)
	
	Start-Sleep -s 3
	[System.Windows.Forms.SendKeys]::SendWait("%s")
	
    if($Debug){
        $Global:Keycount+=4
        Write-Host Forwarding Message:`t`t`t$PathToEmail
        Write-Host To Address:`t`t`t$AddressToSendTo
    }
}

#Replies to the open email with the given message body
function Reply_Email{
	param(  [string]$Body,
            [string]$AddressToReply
	)
	
	[System.Windows.Forms.SendKeys]::SendWait("^+r")
	Start-Sleep -s 1
    if($AddressToReply -ne $NULL){
        [System.Windows.Forms.SendKeys]::SendWait("+{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("+{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("+{TAB}")
        Start-Sleep -m 500
        [System.Windows.Forms.SendKeys]::SendWait("^a")
        Start-Sleep -m 500
        mark-trace "Outlook-Type Address"
        type-string($AddressToReply)
        Start-Sleep -s 1 
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
        [System.Windows.Forms.SendKeys]::SendWait("{TAB}")        
    }
    Start-Sleep -s 1
    mark-trace "Outlook-Type body"
	type-string($Body)
	
	Start-Sleep -s 2
    mark-trace "Outlook-Send email"
	[System.Windows.Forms.SendKeys]::SendWait("%s")
	
    if($Debug){
        $Global:Keycount+=9
        Write-Host Replying To Email At:`t`t`t$AddressToReply
    }
}

#Send a new email to the address specified with the given message Body, HAVE OUTLOOK OPEN AND IN FOCUS
function New_Email{
	param([string]$AddressToSendTo,
		[string]$Body
	)
    mark-trace "Outlook-Compose new email"
	[System.Windows.Forms.SendKeys]::SendWait("^n")
	Start-Sleep -s 4

    mark-trace "Outlook-Type address"	
	type-string($AddressToSendTo)
	Start-Sleep -s 2
	[System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}")
	Start-Sleep -s 2

    mark-trace "Outlook-Type subject"   
    type-string("Meeting Notes: " + (Get-Date))
    Start-Sleep -s 2
    
	[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
	Start-Sleep -s 2

    mark-trace "Outlook-Type body"   
	type-string($Body)
	
	Start-Sleep -s 2
    mark-trace "Outlook-Send email"
	[System.Windows.Forms.SendKeys]::SendWait("%s")
	
    if($Debug){
        $Global:Keycount+=5
        Write-Host Sending New Mail To:`t`t`t$AddressToSendTo
    }
}

#Send a new email to the address specified with the given message Body, HAVE OUTLOOK OPEN AND IN FOCUS
function HTML_Email{
	param([string]$PathToFiles,
        [string]$AddressToSendTo
	)
    mark-trace "Outlook-Open html message"   
    $msg = "html_" + ((Get-Random -maximum 101 -minimum 0) % 6) + ".msg"
	start ($PathToFiles + $msg)
	Start-Sleep -s 2
	
    mark-trace "Outlook-Forward message"   
	[System.Windows.Forms.SendKeys]::SendWait("^f")    
    
	Start-Sleep -s 2    
    mark-trace "Outlook-Type address"   
	type-string($AddressToSendTo)
	Start-Sleep -s 2
	[System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}")
	Start-Sleep -s 2
	[System.Windows.Forms.SendKeys]::SendWait("^a")    
	Start-Sleep -m 300            
    mark-trace "Outlook-Type subject"   
    type-string("Promotional Material for Review: " + (Get-Date))
    Start-Sleep -s 2
    
	[System.Windows.Forms.SendKeys]::SendWait("{TAB}")

	Start-Sleep -s 2
    mark-trace "Outlook-Send email"
	[System.Windows.Forms.SendKeys]::SendWait("%s")
    Start-Sleep -s 2
	[System.Windows.Forms.SendKeys]::SendWait("{ESC}")

	if($Debug){
        $Global:Keycount+=7
        Write-Host Sending HTML Message:`t`t`t$msg
        Write-Host To Address:`t`t`t`t$AddressToSendTo
    }
}

# splits an array into defined elements or a defined element size
function Split-array {

<#  
  .SYNOPSIS   
    Split an array 
  .PARAMETER inArray
   A one dimensional array you want to split
  .EXAMPLE  
   Split-array -inArray @(1,2,3,4,5,6,7,8,9,10) -parts 3
  .EXAMPLE  
   Split-array -inArray @(1,2,3,4,5,6,7,8,9,10) -size 3
#> 

  param($inArray,[int]$parts,[int]$size)
  
  if ($parts) {
    $PartSize = [Math]::Ceiling($inArray.count / $parts)
  } 
  if ($size) {
    $PartSize = $size
    $parts = [Math]::Ceiling($inArray.count / $size)
  }

  $outArray = @()
  for ($i=1; $i -le $parts; $i++) {
    $start = (($i-1)*$PartSize)
    $end = (($i)*$PartSize) - 1
    if ($end -ge $inArray.count) {$end = $inArray.count}
    $outArray+=,@($inArray[$start..$end])
  }
  return ,$outArray

}

# Generate random data in a two columns, with options for number of data points, data graphing, and random use of formulas 
function Generate_Random_Excel{
	param(  [Bool]$Graph,
            [int]$Size,
            [Bool]$Formulas
	)

    Start-Sleep -m 100
	
	[System.Windows.Forms.SendKeys]::SendWait("^{HOME}")
	Start-Sleep -m 50
	$a = 0
    $b = 0	

	DO{
	    $x = Get-Random -maximum 100 -minimum 0
	    Start-Sleep -m 50
	    $y = Get-Random -maximum 1000 -minimum 0
        
        Start-Sleep -m 50 
        mark-trace "Excel-Type number"
	    type-string -stringToType $x
	    Start-Sleep -m 50
        mark-trace "Excel-Move to next cell right"
	    [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}")
	    Start-Sleep -m 100
        # Insert averaging at random points after run 10, 1/10 chance of formula if enabled
        If ($Formulas -eq $True -AND $a -gt 10 -AND ($y % 10) -eq 0){
            # Average the previous 10 cells
            mark-trace "Excel-Type formula"
            type-string -stringToType "=AVERAGE(OFFSET(INDIRECT(ADDRESS(ROW(),COLUMN())),-10,0,10,1))"
        }else{
            mark-trace "Excel-Type number"
            type-string -stringToType $y
	        Start-Sleep -m 100   
        }
        mark-trace "Excel-Type ENTER and LEFT"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -m 100
	    [System.Windows.Forms.SendKeys]::SendWait("{LEFT}")
	    Start-Sleep -m 50
	    $a++
        if($Debug){$Global:Keycount+=3}
	}While ($a -le $Size)
    
    #If option is set, graph the new data after generating
    If ($Graph -eq $True){
        mark-trace "Excel-Command to graph"
        [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}{UP}")
        Start-Sleep -m 100
	    
        DO{
            
            [System.Windows.Forms.SendKeys]::SendWait("+{UP}")
	        Start-Sleep -m 100
            $b++
            if($Debug){$Global:Keycount++}
        }while ($b -le $Size)
        [System.Windows.Forms.SendKeys]::SendWait("+{LEFT}")
	    Start-Sleep -m 50
	    [System.Windows.Forms.SendKeys]::SendWait("%")
	    Start-Sleep -m 50
	    [System.Windows.Forms.SendKeys]::SendWait("n")
	    Start-Sleep -m 50
	    [System.Windows.Forms.SendKeys]::SendWait("d")
	    Start-Sleep -m 50
	    [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}")
	    Start-Sleep -m 200
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
        mark-trace "Excel-Graph"
	    Start-Sleep -m 50
        if($Debug){$Global:Keycount+=8}
    }
    
}

#Get random Body Text for an email. Uses textfiles named Email_#.txt where # is a number from 0 - 4
function getRandomEmailText{
    param( [string]$PathToFiles)
    
    $i = ((Get-Random -maximum 101 -minimum 0) % 4)

    $body = (Get-Content ($PathToFiles + "Email_" + $i + ".txt"))

    if($Debug){
        Write-Host Random Email Selected:`t`t`t($PathToFiles + "Email_" + $i + ".txt")
    }

    $body
    Return
}

#Sends three page down commands over 15 seconds
function slowPageScroll{
    start-Sleep -s 5
    [System.Windows.Forms.SendKeys]::SendWait("{DOWN}{PGDN}")
    start-Sleep -s 3
    [System.Windows.Forms.SendKeys]::SendWait("{PGDN}")
    start-Sleep -s 4
    [System.Windows.Forms.SendKeys]::SendWait("{PGDN}")
    start-Sleep -s 3
    if($Debug){$Global:Keycount+=4}
}

#Initialization for the switchFocus function
function initFocus{
# add a C# class to access the WIN32 API SetForegroundWindow
Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    public class StartActivateProgramClass {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    }
"@
}

#Changes what application is the primary focus
function switchFocus{
    param(  [string]$ApplicationTitle,
            [string]$ProcessName)

    if ($ProcessName -ne "") {
        $p = Get-Process | Where-Object { $_.ProcessName -eq $ProcessName }
    }
    else {
        $p = Get-Process | Where-Object { $_.MainWindowTitle.ToLower().Contains($ApplicationTitle.ToLower()) -and !$_.MainWindowTitle.ToLower().Contains("command") -and !$_.MainWindowTitle.ToLower().Contains("powershell") }
    }
    if ($Debug) {$p}
    $h = $p[0].MainWindowHandle
    # set the application to foreground
    [void] [StartActivateProgramClass]::SetForegroundWindow($h)
}

#Write in OneNote, note:new tabs or pages will cause permanent filesize increase
function Write_To_OneNote{
    param(  [string]$TextToWrite,
            [string]$Title,
            [switch]$NewTab,
            [switch]$NewPage)
    $placeTitle = $false
    if ($NewTab){
        $placeTitle = $True
        [System.Windows.Forms.SendKeys]::SendWait("^t")
        Start-Sleep -m 400
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
        Start-Sleep -m 800
        if($Debug){$Global:Keycount+=2}
    }
    if ($NewPage){
        $placeTitle = $True
        [System.Windows.Forms.SendKeys]::SendWait("^n")
        Start-Sleep -m 800
        if($Debug){$Global:Keycount++}
    }
    if ($placeTitle){
        type-string -stringToType $Title
        [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
        Start-Sleep -s 5
        if($Debug){$Global:Keycount++}
    }

    [System.Windows.Forms.SendKeys]::SendWait("^a")
    mark-trace "OneNote-Type"
    type-string -stringToType $TextToWrite
    mark-trace "OneNote-Sleep 5s to let sync"
    Start-Sleep -s 5
    if($Debug){$Global:Keycount++}
}

#Funcion Takes a screen shot of the specified screen area and save to the specified file (Used in Debug)
function screenshot(){
    param(  [Drawing.Rectangle]$bounds, 
            [string]$path)
   $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
   $graphics = [Drawing.Graphics]::FromImage($bmp)

   $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)

   $bmp.Save($path)

   $graphics.Dispose()
   $bmp.Dispose()
}

#  ///////////////////////////////////////////////
#  //////////////////// MAIN /////////////////////
#  ///////////////////////////////////////////////
if ($screens -or $Debug){
    if(!(Test-Path((Convert-Path .) + "\Debug\"))){
        md ((Convert-Path .) + "\Debug\")
    }
}

if($screens){
    $Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
    $bounds = [Drawing.Rectangle]::FromLTRB($Screen.Left, $Screen.Top, $Screen.Width*2, $Screen.Height*2)
}

if ($Debug){
    $sw_outlook = [Diagnostics.Stopwatch]::StartNew()
    $sw_excel = [Diagnostics.Stopwatch]::StartNew()
    $sw_word = [Diagnostics.Stopwatch]::StartNew()
    $sw_ppt = [Diagnostics.Stopwatch]::StartNew()
    $sw_oneNote = [Diagnostics.Stopwatch]::StartNew()
    $sw_oneNote.Stop()
    $sw_outlook.Stop()
    $sw_excel.Stop()
    $sw_word.Stop()
    $sw_ppt.Stop()
    Start-Transcript -Append -Force -Path ((Convert-Path .) + "\Debug\Log.txt") 

    write-host "Starting:"`t (get-date -format hh:mm:ss)
}

if ($Address[$Address.Length - 1] -ne ";"){
    $Address = $Address + ";"
}
if ($ReplyAddress[$ReplyAddress.Length - 1] -ne ";"){
    $ReplyAddress = $ReplyAddress + ";"
}

$sw.Start()
initFocus

try {
	Import-Module (Join-Path -Path "$PSScriptRoot\Scripts" -ChildPath 'ProductivityPSModule.psm1') -ErrorAction Stop
	$procArch = Get-ProcessorArchitecture
    $ResourcePath = Join-Path -path $PSScriptRoot resources
    $ScriptsPath = Join-Path -path $PSScriptRoot scripts
	
	#*****************************************************************
    #
    #               AXE setup
    #
    #*****************************************************************

    # AXE termination signal handling loop
    $Global:TerminationLoop = $true

    # AXE environment and framework
	$AXEResultsPath = (Get-Item env:\AssessmentResultsPath).value
    $AXETempPath = (Get-Item env:\AssessmentTempPath).value
    $AxeBinPath = (Get-Item env:\AssessmentAxeBinPath).value
    $AxeCoreNet = "$AxeBinPath\Microsoft.Assessments.Core.dll"

    # workaround - we're not allowed to directly write results as an EE workload (current AXE limitation)
    # write to top level job results folder
    # make global since it needs to be referenced by timer actions
    #
    $Global:WorkloadResultsPath = [string] (Resolve-Path -Path "$AXEResultsPath\..\..\..\..\000_EnergyEfficiency\results")

    $LogFile = "$Global:WorkloadResultsPath\log.txt"
    # Print the values to log.txt
    "AXEResultsPath: $AXEResultsPath" | Out-File $LogFile -Force -Append
    "AXETempPath: $AXETempPath" | Out-File $LogFile -Force -Append
    "AxeBinPath: $AxeBinPath" | Out-File $LogFile -Force -Append
    
    # load up AXE framework from AXE DLL
    # initialize Runtime and create Logger helper object
    #
	"Load AXE..." | Out-File $LogFile -Force -Append
    $boolRunningUnderAxe = InitializeAxeLogger($AxeCoreNet)

    "AXE loaded succesfully..." | Log-Info
	
	while (([convert]::ToUInt64($sw.Elapsed.TotalSeconds)) -lt $RunTime) {
	    # ///////////////////////////////////////////////////////////////
	    # /////// SECTION 1: Open an email and send a reply to it ///////
	    # ///////////////////////////////////////////////////////////////
		"Outlook open and reply to email- START" | Log-Info
	    start-trace

	    if ($Debug){
	        write-host "Section 1:"`t (get-date -format hh:mm:ss)
	        $sw_outlook.Start()
	    }
	    $OutlookPath = ($FilesPath + $EmailFilename)
	    #$appOutlook = start-process -Filepath $OutlookPath

	    mark-trace "Outlook-Launch app"
	    start-process Outlook.exe
	    Start-Sleep -s 5
        mark-trace "Outlook-Focus"
	    #switchFocus -ApplicationTitle "Outlook"
        switchFocus -ProcessName ("OUTLOOK")
	    Start-Sleep -s 1

	    [System.Windows.Forms.SendKeys]::SendWait("%{Tab}")
		start-sleep -Milliseconds 500
	    [System.Windows.Forms.SendKeys]::SendWait("%{Tab}")

        mark-trace "Outlook-Maximize"
	    &$scripts\MaximizeWindow.ps1 -ApplicationTitle "Outlook"
	    start-sleep -s 1

	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5

        mark-trace "Outlook-Get body text from disk"
	    $EmailTxt = getRandomEmailText -PathToFiles $FilesPath

        mark-trace "Outlook-Reply to email"
	    Reply_Email -Body $EmailTxt -AddressToReply $ReplyAddress
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 1") + ".png")}
	    Start-Sleep -m 500
	    [System.Windows.Forms.SendKeys]::SendWait("{ESC}")
	    Start-Sleep -s 3
	    if ($Debug){
	        $sw_outlook.Stop()
	        $Global:Keycount+=2
	    }

	    stop-trace("trace_Outlook1.etl")
		"Outlook open and reply to email- END" | Log-Info

	    # /////////////////////////////////////////////////
	    # /////// SECTION 2: Start working in Word ////////
	    # /////////////////////////////////////////////////
		"Working with Word - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 2:"`t (get-date -format hh:mm:ss)
	        $sw_word.Start()
	    }
        mark-trace "Word-Get content from disk"
	    $txt = Get-Content ($FilesPath + $TextFilename)

        mark-trace "Word-Launch app"
	    $DocPath = $FilesPath + $DocFileName
	    Start-Process $DocPath

	    Start-Sleep -s 3

        mark-trace "Word-Maximize window"
	    &$scripts\MaximizeWindow.ps1 -ApplicationTitle $DocFileName
		
	    start-Sleep -s 5

        mark-trace "Word-Focus"
	    #switchFocus -ApplicationTitle "Word"
        switchFocus -ProcessName ("WINWORD")
	    start-Sleep -m 50
	    [System.Windows.Forms.SendKeys]::SendWait("^a")
	 
	    #divide the txt file into parts and type out first part
	    $txt = $txt -split " "
	    $typeMe = Split-array -inArray @($txt) -size 30
	    $textArr = 0
        mark-trace "Word-Type part 1"
	    type-string -stringToType $typeMe[$textArr++]
	    #$textArr++

	    start-sleep -s 5
        mark-trace "Word-Type part 2"
	    type-string -stringToType $typeMe[$textArr++]
	    #type-string -stringToType $typeMe[$textArr++]
	    Start-Sleep -m 800
        mark-trace "Word-Save"
	    [System.Windows.Forms.SendKeys]::SendWait("^s")
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 2") + ".png")}
	    Start-Sleep -s 2
	    if ($Debug){
	        $sw_word.Stop()
	        $Global:Keycount+=2
	    }
	    stop-trace("trace_Word2.etl")
		"Working with Word - END" | Log-Info

	    # //////////////////////////////////////////////
	    # //////////// SECTION 3: New Email ////////////
	    # //////////////////////////////////////////////
		"Outlook new email - START" | Log-Info
	    start-trace
        mark-trace "Outlook-Focus"
	    #switchFocus -ApplicationTitle "Outlook"
        switchFocus -ProcessName ("OUTLOOK")
	    if ($Debug){
	        write-host "Section 3:"`t (get-date -format hh:mm:ss)
	        $sw_outlook.Start()
	    }
        mark-trace "Outlook-Get body text from disk"
	    $EmailTxt = getRandomEmailText -PathToFiles $FilesPath
        mark-trace "Outlook-New email"
	    new_Email -AddressToSendTo $Address -Body $EmailTxt
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 3") + ".png")}
	    start-sleep -s 5
	    if ($Debug){
	        $sw_outlook.Stop()
	    }
	    stop-trace("trace_Outlook3.etl")
		"Outlook new email - END" | Log-Info

	    # ////////////////////////////////////////////////////
	    # /////// SECTION 4: Continue writing in Word ////////
	    # ////////////////////////////////////////////////////
		"Continue writing in Word - START" | Log-Info 		
	    start-trace
	    if ($Debug){
	        write-host "Section 4:"`t (get-date -format hh:mm:ss)
	        $sw_word.Start()
	    }
        mark-trace "Word-Focus"
	    #switchFocus -ApplicationTitle "Word"
        switchFocus -ProcessName ("WINWORD")
	    start-Sleep -m 50

        mark-trace "Word-Type part 3"
	    type-string -stringToType $typeMe[$textArr++]

	    start-sleep -s 3
        mark-trace "Word-Type part 4"
	    type-string -stringToType $typeMe[$textArr++]
	    #start-sleep -s 10
	    #type-string -stringToType $typeMe[$textArr++]
	    Start-Sleep -m 800
        mark-trace "Word-Save"
	    [System.Windows.Forms.SendKeys]::SendWait("^s")
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 4") + ".png")}
	    Start-Sleep -s 2
	    if ($Debug){
	        $sw_word.Stop()
	        $Global:Keycount++
	    }
	    stop-trace("trace_Word4.etl")
		"Continue writing in Word - END" | Log-Info

	    # /////////////////////////////////////////////
	    # //////// SECTION 5: Send HTML email /////////
	    # /////////////////////////////////////////////
		"Send HTML email - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 5:"`t (get-date -format hh:mm:ss)
	        $sw_outlook.Start()
	    }
        mark-trace "Outlook-Focus"
	    #switchFocus -ApplicationTitle "Outlook"
        switchFocus -ProcessName ("OUTLOOK")
        mark-trace "Outlook-Start HTML Email"
	    HTML_Email -PathToFiles $FilesPath -AddressToSendTo $Address
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 5") + ".png")}
	    Start-Sleep -s 15
        mark-trace "Outlook-Focus"
	    switchFocus -ApplicationTitle "Outlook"
	    start-Sleep -m 50
        mark-trace "Outlook-Close app"
	    [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
	    start-Sleep -s 3
	    if ($Debug){
	        $sw_outlook.Stop()
	        $Global:Keycount++
	    }
	    stop-trace("trace_Outlook5.etl")
		"Send HTML email - END" | Log-Info

	    # /////////////////////////////////////////////
	    # ////////// SECTION 6: Start Excel ///////////
	    # /////////////////////////////////////////////
		"Working with Excel - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 6:"`t (get-date -format hh:mm:ss)
	        $sw_excel.Start()
	    }
	    $ExcelPath = $FilesPath + $ExcelFileName
        mark-trace "Excel-Launch app"
	    Start-Process -FilePath $ExcelPath

	    Start-Sleep -s 3
        mark-trace "Excel-Focus"
	    #switchFocus -ApplicationTitle "Excel"
        switchFocus -ProcessName ("EXCEL")

        mark-trace "Excel-Maximize"
	    &$scripts\MaximizeWindow.ps1 -ApplicationTitle $ExcelFileName

	    Start-Sleep -s 3

        mark-trace "Excel-Generate table"
	    Generate_Random_Excel -Size 50 -Graph $True -Formulas $True
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 6") + ".png")}
	    Start-Sleep -s 5
	    mark-trace "Excel-Copy"
        [System.Windows.Forms.SendKeys]::SendWait("^c")
	    if ($Debug){
	        $sw_excel.Stop()
	        $Global:Keycount++
	    }
	    stop-trace("trace_Excel6.etl")
		"Working with Excel - END" | Log-Info

	    # /////////////////////////////////////////////
	    # //////// SECTION 7: Start PowerPoint ////////
	    # /////////////////////////////////////////////
	    "Working with PowerPoint - START" | Log-Info
		start-trace
	    if ($Debug){
	        write-host "Section 7:"`t (get-date -format hh:mm:ss)
	        $sw_ppt.Start()
	    }
	    $PPTPath = $FilesPath + $PPTFileName
        mark-trace "PowerPoint-Launch app"
	    Start-Process $PPTPath

	    Start-Sleep -s 3
        mark-trace "PowerPoint-Focus"
	    #switchFocus -ApplicationTitle ("PowerPoint")
        switchFocus -ProcessName ("POWERPNT")
        mark-trace "PowerPoint-Maximize"
	    &$scripts\MaximizeWindow.ps1 -ApplicationTitle $PPTFileName

	    Start-Sleep -s 5

        mark-trace "PowerPoint-Scroll pages"
	    slowPageScroll
	    slowPageScroll
	    slowPageScroll
	    slowPageScroll
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 7") + ".png")}
	    Start-Sleep -m 2500
        mark-trace "PowerPoint-Paste Excel table into new slide"
	    [System.Windows.Forms.SendKeys]::SendWait("^m")
	    Start-Sleep -m 800
	    [System.Windows.Forms.SendKeys]::SendWait("^a")
	    Start-Sleep -m 500
	    [System.Windows.Forms.SendKeys]::SendWait("{DELETE}")
	    Start-Sleep -m 800

	    [System.Windows.Forms.SendKeys]::SendWait("^v")
	    Start-Sleep -s 5
	    if ($Debug){
	        $sw_ppt.Stop()
	        $Global:Keycount+=4
	    }
	    stop-trace("trace_PPT7.etl")
		"Working with PowerPoint - END" | Log-Info

	    # /////////////////////////////////////////////
	    # /////////// SECTION 8: Use OneNote //////////
	    # /////////////////////////////////////////////
		"Working with OneNote - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 8:"`t (get-date -format hh:mm:ss)
	        $sw_oneNote.Start()
	    }
        mark-trace "OneNote-Launch app"
	    Start-Process ONENOTE.exe
	    Start-Sleep -s 5
        mark-trace "OneNote-Focus"
	    #switchFocus -ApplicationTitle "OneNote"
        switchFocus -ProcessName ("ONENOTE")
	    Start-Sleep -m 200
        mark-trace "OneNote-Maximize"
	    &$scripts\MaximizeWindow.ps1 -ApplicationTitle "OneNote"
	    Start-Sleep -s 2
	    Write_To_OneNote -TextToWrite $typeMe[0]
	    Write_To_OneNote -TextToWrite $typeMe[1]
	    Write_To_OneNote -TextToWrite $typeMe[2]
	    Write_To_OneNote -TextToWrite $typeMe[3]
	    Write_To_OneNote -TextToWrite $typeMe[4]
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 8") + ".png")}
	    Start-Sleep -s 5
	    [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
	    start-Sleep -m 100
        mark-trace "OneNote-Kill process"
	    kill -ProcessName ONENOTEM

	    if ($Debug){
	        $sw_oneNote.Stop()
	        $Global:Keycount++
	    }
	    stop-trace("trace_OneNote8.etl")
		"Working with OneNote - END" | Log-Info

	    # /////////////////////////////////////////////
	    # ///////// SECTION 9: Close Excel ////////////
	    # /////////////////////////////////////////////
		"Closing Excel - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 9:"`t (get-date -format hh:mm:ss)
	        $sw_excel.Start()
	    }
        mark-trace "Excel-Focus"
	    #switchFocus -ApplicationTitle "Excel"
        switchFocus -ProcessName ("EXCEL")
	    start-sleep -s 2
        mark-trace "Excel-Quit without saving"
	    [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 9") + ".png")}
	    start-Sleep -m 100
	    [System.Windows.Forms.SendKeys]::SendWait("n")
	    start-Sleep -m 100
	    if ($Debug){
	        $sw_excel.Stop()
	        $Global:Keycount+=2
	    }
	    stop-trace("trace_Excel9.etl")
		"Closing Excel - END" | Log-Info

	    # /////////////////////////////////////////////
	    # ///// SECTION 10: Start PowerPoint show /////
	    # /////////////////////////////////////////////
		"PowerPoint slide show - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 10:"`t (get-date -format hh:mm:ss)
	        $sw_ppt.Start()
	    }
        mark-trace "PowerPoint-Focus"
        #switchFocus -ApplicationTitle ("PowerPoint")
	    switchFocus -ProcessName ("POWERPNT")
	    start-sleep -s 1
        mark-trace "PowerPoint-Initiate slide show"
	    [System.Windows.Forms.SendKeys]::SendWait("{F5}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 2"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 3"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 4"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 5"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 6"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 7"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 8"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 9"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 10"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 11"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 12"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 13"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 14"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 15"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 16"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 17"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 18"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 19"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 10
        mark-trace "PowerPoint-Page 20"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 5
        mark-trace "PowerPoint-Page 21"
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    Start-Sleep -s 1
        mark-trace "PowerPoint-Page 22"
	    [System.Windows.Forms.SendKeys]::SendWait("{ESC}")
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 10") + ".png")}
	    Start-Sleep -s 7
	    if ($Debug){
	        $sw_ppt.Stop()
	        $Global:Keycount+=22
	    }
	    stop-trace("trace_PPT10.etl")
		"PowerPoint slide show - END" | Log-Info

	    # /////////////////////////////////////////////
	    # /////// SECTION 11: Close PowerPoint ////////
	    # /////////////////////////////////////////////
		"PowerPoint close - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 11:"`t (get-date -format hh:mm:ss)
	        $sw_ppt.Start()
	    }
        mark-trace "PowerPoint-Focus"
	    #switchFocus -ApplicationTitle ("PowerPoint")
        switchFocus -ProcessName ("POWERPNT")
        mark-trace "PowerPoint-Quit without saving"
	    [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
	    start-Sleep -m 100
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 11") + ".png")}
	    [System.Windows.Forms.SendKeys]::SendWait("n")
	    start-Sleep -s 2
	    if ($Debug){
	        $sw_ppt.Stop()
	        $Global:Keycount+=2
	    }
	    stop-trace("trace_PPT11.etl")
		"PowerPoint close - END" | Log-Info

	    # /////////////////////////////////////////////
	    # /////// SECTION 12: Send a new email ////////
	    # /////////////////////////////////////////////
		"Send a new email - START" | Log-Info
	    start-trace
	    write-host "Section 12:"`t (get-date -format hh:mm:ss)
	    if($Debug){$sw_outlook.Start()}
        mark-trace "Outlook-Launch app"
	    start-process Outlook.exe
	    Start-Sleep -s 5
        mark-trace "Outlook-Maximize"
	    &$scripts\MaximizeWindow.ps1 -ApplicationTitle "Outlook"
	    Start-Sleep -s 1
        mark-trace "Outlook-Focus"
	    #switchFocus -ApplicationTitle "outlook"
        switchFocus -ProcessName ("OUTLOOK")
	    $EmailTxt = getRandomEmailText -PathToFiles $FilesPath
        mark-trace "Outlook-New Email"
	    New_Email -Body $EmailTxt -AddressToSendTo $Address
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 12") + ".png")}
	    start-Sleep -s 20
        mark-trace "Outlook-Close app"
	    [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
	    start-Sleep -s 1
	    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
	    start-Sleep -s 1
	    if($Debug){
	        $sw_outlook.Stop()
	        $Global:Keycount+=2
	    }
	    stop-trace("trace_Outlook12.etl")
	    "Send a new email - END" | Log-Info

	    # ///////////////////////////////////////////////
	    # ///// SECTION 13: Finish Writting in Word /////
	    # ///////////////////////////////////////////////
		"Finish writing in Word - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 13:"`t (get-date -format hh:mm:ss)
	        $sw_word.Start()
	    }
        mark-trace "Word-Focus"
	    #switchFocus -ApplicationTitle ("Word")
        switchFocus -ProcessName ("WINWORD")
	    start-Sleep -m 50

        mark-trace "Word-Type part 5"
	    type-string -stringToType $typeMe[$textArr++]

	    start-sleep -s 10
        mark-trace "Word-Type part 6"
	    type-string -stringToType $typeMe[$textArr++]

	    Start-Sleep -m 800
        mark-trace "Word-Save"
	    [System.Windows.Forms.SendKeys]::SendWait("^s")
	    Start-Sleep -s 2
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 13") + ".png")}
	    #start-sleep -s 30
	    if ($Debug){
	        $sw_word.Stop()
	        $Global:Keycount++
	    }
	    stop-trace("trace_Word13.etl")
		"Finish writing in Word - END" | Log-Info

	    # ///////////////////////////////////////////////
	    # ///// SECTION 14: Close All Open Programs /////
	    # ///////////////////////////////////////////////
		"Closing all programs - START" | Log-Info
	    start-trace
	    if ($Debug){
	        write-host "Section 14:"`t (get-date -format hh:mm:ss)
	        $sw_word.Start()
	    }
        mark-trace "Word-Focus"
	    #switchFocus -ApplicationTitle "Word"
        switchFocus -ProcessName ("WINWORD")
	    start-Sleep -m 50
        mark-trace "Word-Close app"
	    [System.Windows.Forms.SendKeys]::SendWait("%{F4}")
	    start-Sleep -m 100
	  #  [System.Windows.Forms.SendKeys]::SendWait("n")
	    start-Sleep -s 2
	    if ($screens){screenshot -bounds $bounds -path ((Convert-Path .) + "\Debug\" + $((get-date -f MM.dd.yy-hh.mm)+ " - Section 14") + ".png")}
	    if ($Debug){
	        $sw_word.Stop()
	        $Global:Keycount++
	    }
	    stop-trace("trace_Close14.etl")
		"Closing all programs - END" | Log-Info
	}
} catch {
    #*****************************************************************
    #
    #                Handle exceptions
    #
    #*****************************************************************

    if ( $Global:axeLogger ) {
        $Global:axeLogger.LogErrorCode( $_.Exception.Hresult, $_ )

        # Write the exception details to a errors XML file
        $xmlErrorFile = "$AXEResultsPath\ErrorsAndWarnings.xml"
        $message = $_.Exception.Message + [Environment]::NewLine + $_.InvocationInfo.PositionMessage
        LogToXmlErrorFile -XmlErrorFile $xmlErrorFile -ErrorCode $_.Exception.Hresult -ErrorMessage $message
    }
        
    throw
} finally {
	if ($Trace) {
		$status = wpr.exe -status
		if (!($status -contains "WPR is not recording")) {
			Write-Host "Cancelling WPR recording."
			wpr.exe -cancel | Out-Null
		}
	}
}

if ($Debug){
    $sw.Stop()
    write-host "Exit: " (get-date -format hh:mm:ss)`r`n
    write-host Total Time Ran: ([convert]::ToUInt64($sw.Elapsed.TotalSeconds)) `r`n
    write-host "Breakdown of Time"
    write-host "==================================="
    Write-Host Outlook:`t`t([convert]::ToUInt64($sw_outlook.Elapsed.TotalSeconds))`t`t([convert]::ToUInt64(([convert]::ToUInt64($sw_outlook.Elapsed.TotalSeconds)/[convert]::ToUInt64($sw.Elapsed.TotalSeconds))*100))%
    Write-Host Excel:`t`t`t([convert]::ToUInt64($sw_excel.Elapsed.TotalSeconds))`t`t([convert]::ToUInt64(([convert]::ToUInt64($sw_excel.Elapsed.TotalSeconds)/[convert]::ToUInt64($sw.Elapsed.TotalSeconds))*100))%
    Write-Host Word:`t`t`t([convert]::ToUInt64($sw_word.Elapsed.TotalSeconds))`t`t([convert]::ToUInt64(([convert]::ToUInt64($sw_word.Elapsed.TotalSeconds)/[convert]::ToUInt64($sw.Elapsed.TotalSeconds))*100))%
    Write-Host PowerPoint:`t`t([convert]::ToUInt64($sw_ppt.Elapsed.TotalSeconds))`t`t([convert]::ToUInt64(([convert]::ToUInt64($sw_ppt.Elapsed.TotalSeconds)/[convert]::ToUInt64($sw.Elapsed.TotalSeconds))*100))%
    Write-Host OneNote:`t`t([convert]::ToUInt64($sw_oneNote.Elapsed.TotalSeconds))`t`t([convert]::ToUInt64(([convert]::ToUInt64($sw_oneNote.Elapsed.TotalSeconds)/[convert]::ToUInt64($sw.Elapsed.TotalSeconds))*100))%
    Write-Host `r`nKey Count:`t`t$Global:Keycount
    Stop-Transcript
}
