######################################################################
### Funktionsbibliothek für die Erweiterung der Benutzeroberfläche ###
######################################################################

##
## Helper
##

function ArrangeForConnection($node, $port) {
	$parent = $port.Parent
	$d = 40
	if ($port.Orientation -eq "TOP") {
		$node.X = $parent.X
		$node.Y = $parent.Y - $node.Height - $d
	} elseif ($port.Orientation -eq "BOTTOM") {
		$node.X = $parent.X
		$node.Y = $parent.Y + $parent.Height + $d
	} elseif ($port.Orientation -eq "LEFT") {
		$node.X = $parent.X - $node.Width - $d
		$node.Y = $parent.Y
	} elseif ($port.Orientation -eq "RIGHT") {
		$node.X = $parent.X + $parent.Width + $d
		$node.Y = $parent.Y
	}
}

##
## IGraph
##

## Knoten linear ausrichten

function Check-Arrange-Nodes($appCore, $graph, $result) {
	$result.Value = $graph.Count -gt 0
}

##
## INode
##

## Namen des Knotens anzeigen

function Node-ShowName($appCore, $node) {
	$Null = [Windows.Forms.MessageBox]::Show($node.Name, "Name des Knotens", "OK", "Information")
}
function Check-Node-ShowName($appCore, $node, $result) {
	$rand = New-Object Random
	if ($rand.NextDouble() -gt 0.5) {
		$result.Value = $True
	}
}

##
## IPort
##

##
## InPort
##

## Warteschlange (de)aktivieren

function InPort-ActivateQueue($appCore, $port) {
	$port.HasQueue = $true
}
function Check-InPort-ActivateQueue($appCode, $port, $result) {
	$result.Value = -not $port.HasQueue
}

function InPort-DeactivateQueue($appCore, $port) {
	$port.HasQueue = $false
}
function Check-InPort-DeactivateQueue($appCode, $port, $result) {
	$result.Value = $port.HasQueue
}

## NotSet-Platzieren

function InPort-PlaceEmptyToken($appCore, $port) {
	$port.UpdateToken($(Token -value $NULL -state "NotSet"))
	$port.Parent.Activate()
}

## Cockpit-Knoten erzeugen

function InPort-GenerateCockpit($appCore, $port) {
	$types = $port.SupportedTypes
	$parent = $port.Parent
	$nodeName = $parent.Parent.GetAddress() + "\" + $parent.Name + "_" + $port.Name + "_UI"
	
	function BuildNode($type) {
		$n = New-Node -typeName "DynamicNode.Lib.Cockpit.N$type" -name $nodeName
		ArrangeForConnection $n $port
		$n["name"].Value = $parent.Name + "_" + $port.Name
		return $n
	}
	function AcceptsEnum() {
		foreach ($t in $types) {
			if ($t.IsEnum) { 
				Write-Host "true"
				return $true 
			}
		}
		return $false
	}
	
	$node = $Null
	
	if ($types.Length -eq 0) {
		$node = BuildNode "Trigger"
	} elseif ($types -contains [IO.FileInfo]) {
		$node = BuildNode "File"
	} elseif ($types -contains [IO.DirectoryInfo]) {
		$node = BuildNode "Directory"
	} elseif ($types -contains [Bool]) {
		$node = BuildNode "Boolean"
	} elseif ($types -contains [Byte]) {
		$node = BuildNode "Numeric"
		$node["min"].Value = 0.0
		$node["max"].Value = 255.0
		$node["style"].Value = [DynamicNode.Lib.Cockpit.NumericStyle]::Slider
	} elseif ($types -contains [Int16] -or $types -contains [Int32] -or $types -contains [Int64]) {
		$node = BuildNode "Numeric"
		$node["style"].Value = [DynamicNode.Lib.Cockpit.NumericStyle]::Textbox
	} elseif ($types -contains [Single] -or $types -contains [Double]) {
		$node = BuildNode "Numeric"
		$node["style"].Value = [DynamicNode.Lib.Cockpit.NumericStyle]::Slider
		$node["min"].Value = 0.0
		$node["max"].Value = 1.0
	} elseif ($types -contains [String]) {
		$node = BuildNode "String"
	} elseif ($types -contains [Object]) {
		$node = BuildNode "Trigger"
	} elseif (AcceptsEnum) {
		$node = BuildNode "Enum"
	}
	
	if ($node) {
		$node.Activate()
		if (-not $port.TryConnect($node["value"])) {
			Write-Error "Verbinden des Cockpit-Knotens mit $($parent.Name) ist fehlgeschlagen."
		}
	}
}
function Check-InPort-GenerateCockpit($appCore, $port, $result) {
	$types = $port.SupportedTypes
	$supported = `
		[IO.FileInfo], [IO.DirectoryInfo], `
		[Bool], [Byte], [Int16], [Int32], [Int64], `
		[Single], [Double], `
		[String], [Object]
		
	if ($types.Length -eq 0) {
		$result.Value = $true
		return
	}
	foreach ($t in $supported) {
		if ($types -contains $t) {
			$result.Value = $true
			return
		}
	}
	foreach ($t in $types) {
		if ($t.IsEnum) {
			$result.Value = $true
			return
		}
	}
}

# Bild-laden-Knoten erzeugen

function InPort-GenerateImageSource($appCore, $port) {
	$types = $port.SupportedTypes
	$parent = $port.Parent
	$nodeName = $parent.Parent.GetAddress() + "\" + $parent.Name + "_" + $port.Name + "_Cockpit"
	$node = New-Node -typeName DynamicNode.Lib.Imaging.IO.NFileSource -name $nodeName
	ArrangeForConnection $node $port
	$node.Activate()
	
	$portName = ""
	if ($types -contains [DynamicNode.Types.Imaging.ARGBImage]) {
		$portName = "ARGB"
	} elseif ($types -contains [DynamicNode.Types.Imaging.RGBImage]) {
		$portName = "RGB"
	} elseif ($types -contains $(Get-GenericType DynamicNode.Types.Base.Matrix System.Byte)) {
		$portName = "Gray"
	}
	if (-not $port.TryConnect($node[$portName])) {
		Write-Error "Verbinden des Bild-laden-Knotens mit $($parent.Name) ist fehlgeschlagen."
	}
}
function Check-InPort-GenerateImageSource($appCore, $port, $result) {
	$types = $port.SupportedTypes
	$supported = `
		$(Get-GenericType DynamicNode.Types.Base.Matrix System.Byte), `
		[DynamicNode.Types.Imaging.RGBImage], `
		[DynamicNode.Types.Imaging.ARGBImage]
	
	foreach ($t in $supported) {
		if ($types -contains $t) {
			$result.Value = $True
			return
		}
	}
}

# Matrix-Knoten erzeugen

function InPort-Generate3x3Matrix($appCore, $port) {
	$types = $port.SupportedTypes
	$parent = $port.Parent
	$nodeName = $parent.Parent.GetAddress() + "\" + $parent.Name + "_" + $port.Name + "_Cockpit"
	$node = New-Node -typeName DynamicNode.Lib.Mathematics.NMatrixBox3x3 -name $nodeName
	ArrangeForConnection $node $port
	$node.Activate()
	
	if (-not $port.TryConnect($node["matrix"])) {
		Write-Error "Verbinden des 3x3-Matrix-Knotens mit $($parent.Name) ist fehlgeschlagen."
	}
}
function InPort-Generate5x5Matrix($appCore, $port) {
	$types = $port.SupportedTypes
	$parent = $port.Parent
	$nodeName = $parent.Parent.GetAddress() + "\" + $parent.Name + "_" + $port.Name + "_Cockpit"
	$node = New-Node -typeName DynamicNode.Lib.Mathematics.NMatrixBox5x5 -name $nodeName
	ArrangeForConnection $node $port
	$node.Activate()
	
	if (-not $port.TryConnect($node["matrix"])) {
		Write-Error "Verbinden des 3x3-Matrix-Knotens mit $($parent.Name) ist fehlgeschlagen."
	}
}
function Check-InPort-GenerateMatrix($appCore, $port, $result) {
	$types = $port.SupportedTypes
	$supported = `
		,$(Get-GenericType DynamicNode.Types.Base.Matrix System.Single)
	
	foreach ($t in $supported) {
		if ($types -contains $t) {
			$result.Value = $True
			return
		}
	}
}

##
## OutPort
##

# Bild-Betrachter-Knoten erzeugen

function OutPort-GenerateImageView($appCore, $port) { guiis {
	$types = $port.SupportedTypes
	$parent = $port.Parent
	$nodeName = $parent.Parent.GetAddress() + "\" + $parent.Name + "_" + $port.Name + "_Cockpit"
	$node = New-Node -typeName DynamicNode.Lib.Imaging.IO.NImageView -name $nodeName
	ArrangeForConnection $node $port
	$node.Activate()
	
	$portName = ""
	if (-not $port.TryConnect($node["image"])) {
		Write-Error "Verbinden des Bildbetrachter-Knotens mit $($parent.Name) ist fehlgeschlagen."
	}
}}
function OutPort-GenerateImageView2x($appCore, $port) { guiis {
	$types = $port.SupportedTypes
	$parent = $port.Parent
	$nodeName = $parent.Parent.GetAddress() + "\" + $parent.Name + "_" + $port.Name + "_Cockpit"
	$node = New-Node -typeName DynamicNode.Lib.Imaging.IO.NImageView2 -name $nodeName
	ArrangeForConnection $node $port
	$node.Activate()
	
	$portName = ""
	if (-not $port.TryConnect($node["image2"])) {
		Write-Error "Verbinden des Bildbetrachter-Knotens mit $($parent.Name) ist fehlgeschlagen."
	}
}}
function Check-OutPort-GenerateImageView($appCore, $port, $result) {
	$types = $port.SupportedType
	$supported = `
		$(Get-GenericType DynamicNode.Types.Base.Matrix System.Byte), `
		[DynamicNode.Types.Imaging.RGBImage], `
		[DynamicNode.Types.Imaging.ARGBImage], `
		$(Get-GenericType DynamicNode.Types.Base.Matrix System.UInt16), `
		[DynamicNode.Types.Imaging.RGBImage16], `
		[DynamicNode.Types.Imaging.ARGBImage16], `
		$(Get-GenericType DynamicNode.Types.Base.Matrix System.Single), `
		[DynamicNode.Types.Imaging.RGBImage32], `
		[DynamicNode.Types.Imaging.ARGBImage32]
	
	foreach ($t in $supported) {
		if ($port.SupportedType -eq $t) {
			$result.Value = $True
		}
	}
}

