Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Ink
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes

Namespace MainTestApplication
	''' <summary>
	''' Cell that shows a rating value as an image with stars.
	''' </summary>
	Public Class RatingCell
		Inherits StackPanel
		Private Shared _star As ImageSource
		Private Const MAXRATING As Integer = 5
		Private Const [OFF] As Double = 0.2
		Private Const [ON] As Double = 1.0

		''' <summary>
		''' Identifies the <see cref="ItemsSource"/> dependency property.
		''' </summary>
		Public Shared ReadOnly RatingProperty As DependencyProperty = DependencyProperty.Register("Rating", GetType(Integer), GetType(RatingCell), New PropertyMetadata(0, AddressOf OnRatingChanged))

		Public Sub New()
			If _star Is Nothing Then
				_star = ImageCell.GetImageSource("star.png")
			End If
			Orientation = Orientation.Horizontal
			For i As Integer = 0 To 4
				Dim img = GetStarImage()
				img.Opacity = [OFF]
				AddHandler img.MouseLeftButtonDown, AddressOf img_MouseLeftButtonDown
				Children.Add(img)
			Next i
		End Sub
		Public Property Rating() As Integer
			Get
				Return CInt(Fix(GetValue(RatingProperty)))
			End Get
			Set(ByVal value As Integer)
				SetValue(RatingProperty, value)
			End Set
		End Property
		Private Sub img_MouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
			' calculate rating based on the index of the star
			Dim img As Image = TryCast(sender, Image)
			Dim cell As RatingCell = TryCast(img.Parent, RatingCell)
			Dim index As Integer = cell.Children.IndexOf(img)
			If index > 0 OrElse e.GetPosition(img).X > img.Width \ 3 Then
				index += 1
			End If

			' apply the new rating
			cell.Rating = index
			Animate(img)
		End Sub
		Private Shared Function GetStarImage() As Image
			Dim img = New Image()
			img.Source = _star
			img.Height = 17
			img.Width = img.Height
			img.Stretch = Stretch.None
			Return img
		End Function
		Private Shared Sub OnRatingChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
			Dim cell As RatingCell = CType(d, RatingCell)
			For i As Integer = 0 To cell.Children.Count - 1
				cell.Children(i).Opacity = If(i < cell.Rating, [ON], [OFF])
			Next i
		End Sub

		Private Shared _animate As Image
		Private Shared _sb As Storyboard
		Private Sub Animate(ByVal img As Image)
			' create storyboard
			If _sb Is Nothing Then
				_sb = New Storyboard()
				_sb.Duration = New Duration(TimeSpan.FromMilliseconds(20))
				AddHandler _sb.Completed, AddressOf sb_Completed
			End If

			' suspend current animation if any
			If _animate IsNot Nothing Then
				_sb.Stop()
				_animate.RenderTransform = Nothing
			End If

			' start new animation
			img.RenderTransform = New ScaleTransform() With {.ScaleX = 2, .ScaleY = 2, .CenterX = img.Width \ 2, .CenterY = img.Height \ 2}
			_animate = img
			_sb.Begin()
		End Sub

		Private Sub sb_Completed(ByVal sender As Object, ByVal e As EventArgs)
			Dim st = TryCast(_animate.RenderTransform, ScaleTransform)
			If st IsNot Nothing Then
				If st.ScaleX > 1 Then
					st.ScaleX -=.1
					st.ScaleY -=.1
					_sb.Begin()
				End If
				Return
			End If
		End Sub
	End Class
End Namespace
