' *
' * The project site is at: http://sourceforge.jp/projects/fishbornas/
' *
' * First author tiritomato 2012.
' *
' * Distributed under the FishbornArchiveShelf License (See
' *  file "Licenses/License.txt" contained in a project, or the following link.
' *  http://sourceforge.jp/projects/fishbornas/scm/svn/blobs/head/trunk/Licenses/License.txt)
' *
' * 2012.06.07 Initial Revision (tiritomato)
' *

Partial Public Class Logic

    Public Class LocalLocation

        Public Enum ApplicationUniquePathElement
            AssemblyVersion
            CompanyName
            ProductName
            ProductVersion
        End Enum

        Public Sub New(ByVal d As Diagnostics.FileVersionInfo,
                       Optional ByVal ApplicationUniquePathSetting() As ApplicationUniquePathElement = Nothing,
                       Optional ByVal ExistsSafe As Boolean = True)
            ConstructImplement(d, ApplicationUniquePathSetting, ExistsSafe)
        End Sub

        Public Sub New(ByVal Assembly As System.Reflection.Assembly,
                       Optional ByVal ApplicationUniquePathSetting() As ApplicationUniquePathElement = Nothing,
                       Optional ByVal ExistsSafe As Boolean = True)
            If Assembly Is Nothing Then Assembly = Reflection.Assembly.GetEntryAssembly
            ' [] default value set []
            ConstructImplement(Diagnostics.FileVersionInfo.GetVersionInfo(Assembly.Location), ApplicationUniquePathSetting, ExistsSafe)
            ' [] AssemblyVersion []
            If Assembly.GetName.Version IsNot Nothing Then m_AssemblyVersion = New Version(Assembly.GetName.Version.ToString)
        End Sub

        Private m_ApplicationUniquePathSetting() As ApplicationUniquePathElement
        Public ReadOnly Property ApplicationUniquePathSetting As System.Collections.ObjectModel.ReadOnlyCollection(Of ApplicationUniquePathElement)
            Get
                Return New System.Collections.ObjectModel.ReadOnlyCollection(Of ApplicationUniquePathElement)(m_ApplicationUniquePathSetting)
            End Get
        End Property

        Public ReadOnly Property ApplicationUniquePath As Logic.FileSystem.Path
            Get
                Dim elements As New System.Collections.Generic.List(Of String)(ApplicationUniquePathSetting.Count)
                For Each element As ApplicationUniquePathElement In ApplicationUniquePathSetting
                    Select Case element
                        Case ApplicationUniquePathElement.AssemblyVersion
                            If AssemblyVersion IsNot Nothing Then elements.Add(AssemblyVersion.ToString)
                        Case ApplicationUniquePathElement.CompanyName
                            If Not String.IsNullOrEmpty(CompanyName) Then elements.Add(CompanyName)
                        Case ApplicationUniquePathElement.ProductName
                            If Not String.IsNullOrEmpty(ProductName) Then elements.Add(ProductName)
                        Case ApplicationUniquePathElement.ProductVersion
                            If ProductVersion IsNot Nothing Then elements.Add(ProductVersion.ToString)
                    End Select
                Next
                If elements.Count <= 0 Then Return String.Empty
                Return Logic.FileSystem.JoinPathElements(elements.ToArray)
            End Get
        End Property

        Private m_AssemblyVersion As Version = Nothing
        Public ReadOnly Property AssemblyVersion As Version
            Get
                Return m_AssemblyVersion
            End Get
        End Property

        Private m_CompanyName As String = String.Empty
        Public ReadOnly Property CompanyName As String
            Get
                Return m_CompanyName
            End Get
        End Property

        Private m_FileVersion As Version = Nothing
        Public ReadOnly Property FileVersion As Version
            Get
                Return m_FileVersion
            End Get
        End Property

        Public Shared Function FromAssembly(ByVal Assembly As System.Reflection.Assembly, Optional ByVal ApplicationUniquePathSetting() As ApplicationUniquePathElement = Nothing)
            If Assembly IsNot Nothing Then Return New LocalLocation(Assembly, ApplicationUniquePathSetting)
            Return Nothing
        End Function

        Public Shared Function FromVersionInfo(ByVal d As Diagnostics.FileVersionInfo, Optional ByVal ApplicationUniquePathSetting() As ApplicationUniquePathElement = Nothing) As LocalLocation
            If d IsNot Nothing Then Return New LocalLocation(d, ApplicationUniquePathSetting)
            Return Nothing
        End Function

        Public Shared Function FromVersionInfo(ByVal Path As Logic.FileSystem.Path, Optional ByVal ApplicationUniquePathSetting() As ApplicationUniquePathElement = Nothing) As LocalLocation
            If Path IsNot Nothing AndAlso Path.FileExists Then
                Dim d As Diagnostics.FileVersionInfo = Nothing
                Try
                    d = Diagnostics.FileVersionInfo.GetVersionInfo(Path.ToString)
                Catch ex As IO.FileNotFoundException
                    ' do nothing
                End Try
                If d IsNot Nothing Then Return FromVersionInfo(d, ApplicationUniquePathSetting)
            End If
            Return Nothing
        End Function

        Private m_IsExistsSafe As Boolean
        Public ReadOnly Property IsExistsSafe As Boolean
            Get
                Return m_IsExistsSafe
            End Get
        End Property

        Public ReadOnly Property LocalUserAppDataPath As Logic.FileSystem.Path
            Get
                LocalUserAppDataPath = Logic.FileSystem.JoinPathElements(LocalUserAppDataPathBase.ToString, ApplicationUniquePath.ToString)
                If IsExistsSafe AndAlso LocalUserAppDataPath.DirectoryExists = False Then IO.Directory.CreateDirectory(LocalUserAppDataPath.ToString)
            End Get
        End Property

        Public ReadOnly Property LocalUserAppDataPathBase As Logic.FileSystem.Path
            Get
                If System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed Then
                    Return Logic.FileSystem.JoinPathElements(System.Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory, "Local Settings")
                End If
                Return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
            End Get
        End Property

        Private m_AssemblyLocation As String
        Public ReadOnly Property AssemblyLocation As Logic.FileSystem.Path
            Get
                Return New Logic.FileSystem.Path(m_AssemblyLocation)
            End Get
        End Property

        Private m_ProductName As String = String.Empty
        Public ReadOnly Property ProductName As String
            Get
                Return m_ProductName
            End Get
        End Property

        Private m_ProductVersion As Version = New Version(0, 0, 0, 0)
        Public ReadOnly Property ProductVersion As Version
            Get
                Return m_ProductVersion
            End Get
        End Property

        Public ReadOnly Property UserAppDataPath As Logic.FileSystem.Path
            Get
                UserAppDataPath = Logic.FileSystem.JoinPathElements(UserAppDataPathBase.ToString, ApplicationUniquePath.ToString)
                If IsExistsSafe AndAlso UserAppDataPath.DirectoryExists = False Then IO.Directory.CreateDirectory(UserAppDataPath.ToString)
            End Get
        End Property

        Public ReadOnly Property UserAppDataPathBase As Logic.FileSystem.Path
            Get
                If System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed Then
                    Return System.Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory
                End If
                Return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
            End Get
        End Property

        Private Sub ConstructImplement(ByVal d As Diagnostics.FileVersionInfo, ByVal ApplicationUniquePathSetting() As ApplicationUniquePathElement, ByVal IsExistsSafe As Boolean)
            If d Is Nothing Then d = Diagnostics.FileVersionInfo.GetVersionInfo(Reflection.Assembly.GetEntryAssembly.Location) ' exe file path is option's default
            If ApplicationUniquePathSetting Is Nothing OrElse ApplicationUniquePathSetting.Length <= 0 Then
                ApplicationUniquePathSetting = {ApplicationUniquePathElement.CompanyName,
                                                ApplicationUniquePathElement.ProductName,
                                                ApplicationUniquePathElement.ProductVersion}
            End If
            m_AssemblyLocation = d.FileName
            m_AssemblyVersion = New Version(0, 0, 0, 0)
            m_CompanyName = d.CompanyName
            If d.FileVersion IsNot Nothing Then
                m_FileVersion = New Version(d.FileVersion)
            Else
                m_FileVersion = New Version(0, 0, 0, 0)
            End If
            m_IsExistsSafe = IsExistsSafe
            m_ProductName = d.ProductName
            m_ProductVersion = New Version(IIf(d.ProductVersion IsNot Nothing, d.ProductVersion, m_FileVersion.ToString))
            m_ApplicationUniquePathSetting = ApplicationUniquePathSetting
        End Sub

    End Class

End Class
