Imports System.IO

Public Class SideNav
    Inherits UserControl

#Region "Defined Types"

    Class MenuItem
        Property target As String
        Property status As SideNavItem.ItemStatus

        Sub New(target As String, status As SideNavItem.ItemStatus)
            Me.target = target
            Me.status = status
        End Sub
        Sub New(lst As List(Of String), ctls As ControlCollection, index As Integer)
            Dim ctl As SideNavItem = ctls(index)
            target = lst(index)
            status = ctl.status
        End Sub
    End Class

    Event LinkClicked(item As MenuItem)

#End Region

#Region "Properties"

    Private _links As New List(Of String)

#End Region

#Region "Methods"

    Function Add(title As String, target As String, status As SideNavItem.ItemStatus, Optional forceLink As Boolean = False) As SideNavItem

        Dim newItem = New SideNavItem(title, status)
        newItem.selected = (target = Path.GetFileName(Request.PhysicalPath) & ".aspx")
        'Dim t As String = Path.GetFileName(Request.PhysicalPath)
        newItem.forceLink = forceLink
        newItem.ID = _links.Count

        list.Controls.Add(newItem)
        _links.Add(target)

        Return newItem
    End Function

    Function GetFirst() As MenuItem
        Return New MenuItem(_links, list.Controls, 0)
    End Function

    Function GetCurrent() As MenuItem
        For i = 0 To _links.Count - 1
            Dim navItem As SideNavItem = list.Controls(i)
            If navItem.selected Then
                Return New MenuItem(_links, list.Controls, i)
            End If
        Next
        Return Nothing
    End Function

    Function GetCurrentTitle() As String
        For i = 0 To _links.Count - 1
            Dim navItem As SideNavItem = list.Controls(i)
            If navItem.selected Then
                Return navItem.title
            End If
        Next
        Return Nothing
    End Function

    Function GetNext() As MenuItem

        For i = 0 To _links.Count - 2
            Dim navItem As SideNavItem = list.Controls(i)
            If navItem.selected Then
                Return New MenuItem(_links, list.Controls, i + 1)
            End If
        Next

        Dim last As SideNavItem = list.Controls(list.Controls.Count - 1)
        If last.selected Then
            Return New MenuItem("Submit.aspx", SideNavItem.ItemStatus.Disabled)
        Else
            Return Nothing
        End If

    End Function

    Function GetPercent() As String
        Dim s As String = "0% Complete"
        For i = 0 To _links.Count - 2
            Dim navItem As SideNavItem = list.Controls(i)
            If navItem.selected Then
                s = Math.Round(i / (_links.Count - 2) * 100, 0) & "% Complete"
                Exit For
            End If
        Next
        Return s
    End Function

    Function GetPrevious() As MenuItem
        For i = 1 To _links.Count - 1
            Dim navItem As SideNavItem = list.Controls(i)
            If navItem.selected Then
                Return New MenuItem(_links, list.Controls, i - 1)
            End If
        Next
        Return Nothing
    End Function

    Sub SetCurrentPage(filename As String)
        For i = 0 To _links.Count - 1
            Dim navItem As SideNavItem = list.Controls(i)
            navItem.selected = _links(i) = filename
        Next
    End Sub

    Sub SetFooter(footer As String)
        litFooter.Text = footer
    End Sub

#End Region

#Region "Event handlers"

    Private sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        If Page.IsPostBack Then
            For each child As SideNavItem In list.Controls
                Dim childId = child.ClientID
                If Request.Form(childId) IsNot Nothing Then
                    Dim indexStart = childId.LastIndexOf("_"c)
                    Dim index = childId.Substring(indexStart + 1)
                    RaiseEvent LinkClicked(New MenuItem(_links, list.Controls, index))
                End If
            Next
        End If
    End sub

    Protected Overrides Sub LoadViewState(savedState As Object)

        Dim state = CType(savedState, Object())

        MyBase.LoadViewState(state(0))
        Dim targets = state(1)
        Dim titles = state(2)
        Dim statuses = state(3)
        Dim forceLinks = state(4)
        
        For i = 0 To titles.Count - 1
            Add(titles(i), targets(i), statuses(i), forceLinks(i))
        Next
        
    End Sub

    Protected Overrides Function SaveViewState() As Object
        Dim state(4) As Object

        Dim titles As New List(Of String)
        Dim statuses As New List(Of String)
        Dim forceLinks As New List(Of Boolean)
        For Each ctl As SideNavItem In list.Controls
            titles.Add(ctl.title)
            statuses.Add(ctl.status)
            forceLinks.Add(ctl.forceLink)
        Next

        state(0) = MyBase.SaveViewState()
        state(1) = _links
        state(2) = titles
        state(3) = statuses
        state(4) = forceLinks

        Return state
    End Function

#End Region

End Class