UniversalDashboard/UniversalDashboard.Community/UniversalDashboard.Controls.psm1

function Invoke-UDEvent {
    param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            Position = 0
        )]
        [String]$Id,
        [Parameter(
            Mandatory = $true,
            Position = 1,
            ParameterSetName = "onClick"
        )]
        [ValidateSet("onClick")]
        [string]$event,
        [Parameter(
            Mandatory = $true,
            Position = 1,
            ParameterSetName = "Scheduled"
        )]
        [switch]$scheduled
    )

    Begin {

    }

    Process {
        if ($PSCmdlet.ParameterSetName -eq "onClick") {
            Invoke-UDJavaScript -javaScript "
                document.getElementById('$Id').click();
            "

        }
        elseif ($PSCmdlet.ParameterSetName -eq "Scheduled") {
            $dashboard = Get-UDDashboard
            $endpoint = $dashboard.DashboardService.EndpointService.ScheduledEndpoints | where-object Name -eq $Id

            if ($endpoint) {
                try {
                    $endpoint.ScriptBlock.Invoke() | Out-Null
                }
                catch {
                    throw ("Invoking endpoint $Id failed with: $($_.Exception.Message)")
                }
                
            }
            else {
                Write-UDLog "Attempting to trigger $Id failed, unable to locate endpoint."
            }
            
        }

    }

    End {

    }
}
function New-UDHeading {
    param(
        [Parameter()]
        [String]$Id = ([Guid]::NewGuid()),
        [Parameter(ParameterSetName = "Content")]
        [ScriptBlock]$Content,
        [Parameter(ParameterSetName = "Text")]
        [string]$Text,
        [Parameter()]
        [ValidateSet("1", "2", "3", "4", "5", "6")]
        $Size,
        [Parameter()]
        [UniversalDashboard.Models.DashboardColor]$Color = 'black'
    )

    if ($PSCmdlet.ParameterSetName -eq "Text") {
        $Content = { $Text }
    }

    New-UDElement -Id $Id -Tag "h$size" -Content $Content -Attributes @{
        style = @{
            color = $Color.HtmlColor
        }
    }
}
function New-UDIcon {
    param(
        [Parameter()]
        [string]$Id = ([Guid]::NewGuid()).ToString(),
        [Parameter()]
        [UniversalDashboard.Models.FontAwesomeIcons]$Icon, 
        [Parameter()]
        [Switch]$FixedWidth,
        [Parameter()]
        [switch]$Inverse,
        [Parameter()]
        [int]$Rotation,
        [Parameter()]
        [string]$ClassName,
        [Parameter()]
        [string]$Transform,
        [Parameter()]
        [ValidateSet("horizontal", 'vertical', 'both')]
        [string]$Flip,
        [Parameter()]
        [ValidateSet('right', 'left')]
        [string]$Pull,
        [Parameter()]
        [switch]$ListItem,
        [Parameter()]
        [switch]$Spin,
        [Parameter()]
        [switch]$Border,
        [Parameter()]
        [switch]$Pulse,
        [Parameter ()]
        [ValidateSet("xs", "sm", "lg", "2x", "3x", "4x", "5x", "6x", "7x", "8x", "9x", "10x")]
        [string]$Size = "sm",
        [Parameter()]
        [Hashtable]$Style,
        [Parameter()]
        [string]$Title,
        [Parameter()]
        [switch]$Regular,
        [Parameter()]
        [UniversalDashboard.Models.DashboardColor]
        $Color
    )

    End {

        $iconName = [UniversalDashboard.Models.FontAwesomeIconsExtensions]::GetIconName($Icon)

        $MUIcon = @{
            type       = "icon"
            id         = $id 
            size       = $Size
            fixedWidth = $FixedWidth
            color      = $Color.HtmlColor
            listItem   = $ListItem.IsPresent
            inverse    = $Inverse.IsPresent
            rotation   = $Rotation
            flip       = $Flip
            spin       = $Spin.IsPresent
            pulse      = $Pulse.IsPresent
            border     = $Border.IsPresent
            pull       = $Pull
            className  = $ClassName
            transform  = $Transform
            style      = $Style
            title      = $Title
            regular    = $Regular.IsPresent
            icon       = $iconName
        }

        $MUIcon.PSTypeNames.Insert(0, "UniversalDashboard.Icon") | Out-Null

        $MUIcon
    }
}
function New-UDIFrame {
    param(
        [Parameter()]
        [String]$Id = ([Guid]::NewGuid()),
        [Parameter()]
        $Uri
    )

    New-UDElement -Id $Id -Tag "iframe" -Attributes @{
        src = $Uri
    }
}
function New-UDImage {
    [CmdletBinding(DefaultParameterSetName = 'url')]
    param(
        [Parameter()]
        [String]$Id = ([Guid]::NewGuid()),
        [Parameter(ParameterSetName = 'url')]
        [String]$Url,
        [Parameter(ParameterSetName = 'path')]
        [String]$Path,
        [Parameter()]
        [int]$Height,
        [Parameter()]
        [int]$Width,
        [Parameter()]
        [Hashtable]$Attributes = @{}
    )

    switch ($PSCmdlet.ParameterSetName) {
        'path' {
            if (-not [String]::IsNullOrEmpty($Path)) {
                if (-not (Test-Path $Path)) {
                    throw "$Path does not exist."
                }
        
                $mimeType = 'data:image/png;base64, '
                if ($Path.EndsWith('jpg') -or $Path.EndsWith('jpeg')) {
                    $mimeType = 'data:image/jpg;base64, '
                }
        
                $base64String = [Convert]::ToBase64String([System.IO.File]::ReadAllBytes($Path))
        
                $Attributes.'src' = "$mimeType $base64String"
            }
        }
        'url' {
            $Attributes.'src' = $Url
        }
    }
    if ($PSBoundParameters.ContainsKey('Height')) {
        $Attributes.'height' = $Height
    }
    if ($PSBoundParameters.ContainsKey('Width')) {
        $Attributes.'width' = $Width
    }

    $Attributes["id"] = $Id

    New-UDElement -Tag 'img' -Attributes $Attributes
}
function New-UDParagraph {
    param(
        [Parameter(ParameterSetName = 'content')]
        [ScriptBlock]$Content,
        [Parameter(ParameterSetName = 'text')]
        [string]$Text,
        [Parameter()]
        [UniversalDashboard.Models.DashboardColor]$Color = 'black'
    )

    if ($PSCmdlet.ParameterSetName -eq 'content') {
        New-UDElement -Tag 'p' -Content $Content -Attributes @{
            style = @{
                color = $Color.HtmlColor
            }
        }
    }
    else {
        New-UDElement -Tag 'p' -Content {
            $Text
        } -Attributes @{
            style = @{
                color = $Color.HtmlColor
            }
        }
    }
   
}
function New-UDSpan {
    param(
        [Parameter()]
        [String]$Id = ([Guid]::NewGuid()),
        [Parameter()]
        $Content
    )

    New-UDElement -Id $Id -Tag "span" -Content {
        $Content
    }
}
function New-UDSplitPane {
    param(
        [Parameter()]
        [string]$Id = ([Guid]::NewGuid()).ToString(),
        [Parameter(Mandatory)]
        [ScriptBlock]$Content,
        [Parameter()]
        [ValidateSet("vertical", "horizontal")]
        [string]$Direction = "vertical",
        [Parameter()]
        [int]$MinimumSize,
        [Parameter()]
        [int]$DefaultSize
    )

    $Children = & $Content

    if ($Children.Length -ne 2) {
        Write-Error "Split pane requires exactly two components in Content"
        return
    }

    $Options = @{
        content = $Children
        id = $Id
        split = $Direction.ToLower()
        type = "ud-splitpane"
    }

    if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey("MinimumSize")) {
        $Options["minSize"] = $MinimumSize
    }

    if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey("DefaultSize")) {
        $Options["defaultSize"] = $DefaultSize
    }

    $Options
}

class ThemeColors {
    [string]$primary
    [string]$secondary
    [string]$background
    [string]$text
    [string]$muted

    ThemeColors() { 
    }

    ThemeColors([string]$primary, [string]$secondary) {
        $this.primary = $primary
        $this.secondary = $secondary
    }

    ThemeColors([string]$primary, [string]$secondary, [string]$background, [string]$text, [string]$muted) {
        $this.Primary = $Primary
        $this.Secondary = $Secondary
        $this.Background = $Background
        $this.Text = $Text
        $this.Muted = $Muted
    }

}

class ThemeColorModes {
    [ThemeColors]$Dark

    ThemeColorModes() {
    }

    ThemeColorModes([ThemeColors]$Dark) {
        $this.Dark = $Dark
    }
}

function New-UDTheme {
    [CmdletBinding()]
    param(
        [Parameter()]
        [string]$name,
        [Parameter()]
        [ThemeColors]$Colors,
        [Parameter()]
        [ThemeColorModes]$ColorModes,
        [Parameter()]
        [hashtable]$Variants
    )
    end {
        $theme = [ordered]@{
            name     = $Name
            colors   = if ($Colors) {
                $Colors 
            }
            else {
                [ThemeColors]::new() 
            }
            modes    = if ($ColorModes) {
                $ColorModes 
            }
            else {
                [ThemeColorModes]::new([ThemeColors]::new()) 
            }
            variants = $Variants
        }
        $Result = $theme | ConvertTo-Json -Depth 10 
        $Result
    }
}




function New-UDTooltip {
    param(
        [Parameter()]
        [string]$Id = [Guid]::NewGuid(),
        [Parameter()]
        [ValidateSet("top", "bottom", "left", "right")]
        [string]$Place = "top",
        [Parameter()]
        [ValidateSet("dark", "success", "warning", "error", "info", "light")]
        [string]$Type = "dark",
        [Parameter()]
        [ValidateSet("float", "solid")]
        [string]$Effect,
        [Parameter(Mandatory)]
        [ScriptBlock]$TooltipContent,
        [Parameter(Mandatory)]
        [ScriptBlock]$Content
    )

    @{
        type = "ud-tooltip"
        tooltipType = $Type
        effect = $Effect 
        place = $Place
        id = $Id
        tooltipContent = & $TooltipContent
        content = & $Content
    }
}