Imports System.ComponentModel
Imports System.Globalization
Imports System.Xml
Imports EgtUILib
Imports OmagCUT.NestPageUC

Public Class SelParkIndWD

   Private Shared m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)
   Private m_nCtx As Integer = -1
   Public Const nIndAllOff As Integer = 999

   Public Shared sActualProj As String = String.Empty

   Private m_ParkIndList As New List(Of ParkInd)
   Public Property ParkIndList As List(Of ParkInd)
      Get
         Return m_ParkIndList
      End Get
      Set(value As List(Of ParkInd))
         m_ParkIndList = value
      End Set
   End Property

   Sub New(Owner As Window, Optional nCtx As Integer = -1)
      'Me.Owner = Owner
      InitializeComponent()
      If nCtx > -1 Then m_nCtx = nCtx
   End Sub

   Public Sub Me_Laoded() Handles Me.Loaded
      ' Aggiorno la lista
      UpdateList()
      ' Imposto la selezione del primo parcheggio disponibile
      UpdateDefaultSelection()
   End Sub

   Public Sub UpdateList()
      ' Carico lista dei pezzi
      LoadParkInd(m_ParkIndList, m_nCtx)
      ParkIndListBox.ItemsSource = m_ParkIndList
      UpdateDefaultSelection()
      ' Forzo l'aggiornamento della grafica
      ParkIndListBox.Items.Refresh()
   End Sub

   Public Sub UpdateDefaultSelection()
      ' Procedo a selezionare il primo (E FORSE ANCHE L'UNICO?) parcheggio attivo
      Dim bFound As Boolean = False
      For Each ItemPark As ParkInd In m_ParkIndList
         If ItemPark.IsStatusON Then
            ParkIndListBox.SelectedItem = ItemPark
            bFound = True
            Exit For
         End If
      Next
      If Not bFound And m_ParkIndList.Count > 0 Then
         m_ParkIndList(0).Status = GDB_ST.ON_
         ParkIndListBox.SelectedItem = m_ParkIndList(0)
      End If
      '' Provedo a spegnere tutti gli altri parcheggi
      'For Each ItemParkInd As ParkInd In m_ParkIndList
      '   If ParkIndListBox.SelectedItem.Ind <> ItemParkInd.Ind Then
      '      ItemParkInd.Status = GDB_ST.OFF
      '      SetStatusPartInParkInd(ItemParkInd)
      '   End If
      'Next
   End Sub

   Private Sub ParkIndListBox_SelectionChanged() Handles ParkIndListBox.MouseLeftButtonUp
      ' Non so se il click sta accendeno o spegnendo quinid faccio una verifica dello stato attuale del parcheggio
      Dim localParkInd As ParkInd = ParkIndListBox.SelectedItem
      ' Se l'elemento selezionato è attivo allora esco (perchè altrimenti lo spegnerei)
      If localParkInd.IsStatusON Then Return
      Dim bFound As Boolean = False
      If localParkInd.Ind = nIndAllOff Then
         localParkInd.Status = GDB_ST.ON_
         bFound = True
      End If
      Dim nPartId As Integer = EgtGetFirstPart()
      ' Cerco il primo pezzo del parcheggio indicato
      While nPartId <> GDB_ID.NULL And Not bFound
         Dim sInfoParkInd As String = String.Empty
         ' Se i pezzi non hanno un indice di parcheggio di default vale "0"
         If Not EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then sInfoParkInd = "0"
         If localParkInd.Ind.ToString = sInfoParkInd Then
            ' Determino lo stato da assegnare al parcheggio (prendo il primo pezzo del parcheggio come riferimento)
            Dim OppositStat As Integer = If(localParkInd.Status = GDB_ST.ON_, GDB_ST.OFF, GDB_ST.ON_)
            localParkInd.Status = OppositStat
            bFound = True
            ' termino la ricerca
            Exit While
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      ' Assegno lo stato del parcheggio a tutti i pezzi i parcheggio
      If bFound Then
         SetStatusPartInParkInd(localParkInd, True, m_nCtx)
      Else
         ' Significa che i pezzi sono tutti in macchina: quindi i pezzi sono (SICURAMENTE?) accesi
         Dim OppositStat As Integer = If(localParkInd.Status = GDB_ST.ON_, GDB_ST.OFF, GDB_ST.ON_)
         localParkInd.Status = OppositStat
         SetStatusPartInParkInd(localParkInd, True, m_nCtx)
      End If
      ' Se accendo un parcheggio procedo a spegnere tutto gli atri
      If localParkInd.Status = GDB_ST.ON_ Then
         For Each ItemParkInd As ParkInd In m_ParkIndList
            If localParkInd.Ind <> ItemParkInd.Ind Then
               ItemParkInd.Status = GDB_ST.OFF
               SetStatusPartInParkInd(ItemParkInd, True, m_nCtx)
            End If
         Next
      End If
      EgtZoom(ZM.ALL)
   End Sub

#Region "METODI SHARED per gestione della lista parcheggi"

   ' Restituisce il primo indice di parcheggio libero
   Public Shared Function NewParkInd(Optional nCtx As Integer = -1) As Integer
      ' recupero il contesto corrente
      Dim CurrCtx As Integer = EgtGetCurrentContext()
      ' recupero il contesto del progetto
      Dim ProjCtx As Integer = m_MainWindow.m_CurrentProjectPageUC.CurrentProjectScene.GetCtx()
      If nCtx > -1 Then ProjCtx = nCtx
      EgtSetCurrentContext(ProjCtx)
      Dim LastParkInd As Integer = 0
      Dim nRawId As Integer = GetCurrentRaw()
      ' Leggo l'indice di parcheggio dei pezzi in tavola
      Dim nPartId As Integer = EgtGetFirstGroupInGroup(nRawId)
      While nPartId <> GDB_ID.NULL
         ' Se i pezzi non hanno un indice di parcheggio
         Dim sInfoParkInd As String = String.Empty
         If EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then
            If IsNumeric(sInfoParkInd) Then
               Dim nInfoParkIndn As Integer = CInt(sInfoParkInd)
               LastParkInd = Math.Max(LastParkInd, nInfoParkIndn)
            End If
         End If
         nPartId = EgtGetNextGroup(nPartId)
      End While
      ' Leggo l'indice di parcheggio dei pezzi in parcheggio
      nPartId = EgtGetFirstPart()
      While nPartId <> GDB_ID.NULL
         ' Se i pezzi non hanno un indice di parcheggio (COPIA della funzione sopra)
         Dim sInfoParkInd As String = String.Empty
         If EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then
            If IsNumeric(sInfoParkInd) Then
               Dim nInfoParkIndn As Integer = CInt(sInfoParkInd)
               LastParkInd = Math.Max(LastParkInd, nInfoParkIndn)
            End If
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      ' Ripristino il contesto corrente
      EgtSetCurrentContext(CurrCtx)
      Return LastParkInd + 1
   End Function

   ' Gestisce lo stato dei pezzi associati al parcheggio indicato
   Public Shared Sub SetStatusPartInParkInd(localParkInd As ParkInd, Optional bDraw As Boolean = True, Optional nCtx As Integer = -1)
      If IsNothing(localParkInd) Then Return
      ' recupero il contesto corrente
      Dim CurrCtx As Integer = EgtGetCurrentContext()
      ' recupero il contesto del progetto
      Dim ProjCtx As Integer = m_MainWindow.m_CurrentProjectPageUC.CurrentProjectScene.GetCtx()
      If nCtx > -1 Then ProjCtx = nCtx
      EgtSetCurrentContext(ProjCtx)
      Dim nRawId As Integer = GetCurrentRaw()
      ' Pezzi in tavola
      Dim nPartId As Integer = EgtGetFirstGroupInGroup(nRawId)
      While nPartId <> GDB_ID.NULL
         Dim sInfoParkInd As String = String.Empty
         If Not EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then sInfoParkInd = "0"
         If localParkInd.Ind.ToString = sInfoParkInd Then
            ' Salvo lo stato del parcheggio (per gestire la navigazione) ANCHE SE I PEZZI SONO ACCESI
            EgtSetInfo(nPartId, INFO_PARKSTATUS, localParkInd.Status)
         End If
         nPartId = EgtGetNextGroup(nPartId)
      End While
      ' Pezzi in parcheggio
      nPartId = EgtGetFirstPart()
      While nPartId <> GDB_ID.NULL
         Dim sInfoParkInd As String = String.Empty
         If Not EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then sInfoParkInd = "0"
         If localParkInd.Ind.ToString = sInfoParkInd Then
            ' Setto lo stato
            EgtSetStatus(nPartId, localParkInd.Status)
            ' Salvo lo stato (per gestire la navigazione)
            EgtSetInfo(nPartId, INFO_PARKSTATUS, localParkInd.Status)
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      If bDraw Then EgtDraw()
      ' Ripristino il contesto corrente
      EgtSetCurrentContext(CurrCtx)
   End Sub

   ' Restituuisce la lista dei parcheggi del progetto corrente
   Public Shared Sub LoadParkInd(P_List As List(Of ParkInd), Optional nCtx As Integer = -1)
      If IsNothing(P_List) Then Return
      P_List.Clear()
      P_List.Add(New ParkInd(nIndAllOff, "All off", 0))
      ' recupero il contesto corrente
      Dim CurrCtx As Integer = EgtGetCurrentContext()
      ' recupero il contesto del progetto
      Dim ProjCtx As Integer = m_MainWindow.m_CurrentProjectPageUC.CurrentProjectScene.GetCtx()
      If nCtx > -1 Then ProjCtx = nCtx
      EgtSetCurrentContext(ProjCtx)
      Dim nRawId As Integer = GetCurrentRaw()
      ' Pezzi in tavola
      Dim nPartId As Integer = EgtGetFirstGroupInGroup(nRawId)
      While nPartId <> GDB_ID.NULL
         Dim sInfoParkInd As String = String.Empty
         Dim nInfoParkInd As Integer = -1
         ' Recupero l'indice del parcheggio
         If EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then
            nInfoParkInd = If(IsNumeric(sInfoParkInd), CInt(sInfoParkInd), -1)
         Else
            nInfoParkInd = 0
         End If
         ' Se l'indice di parcheggio restituito è valido (Maggiore di -1)
         If nInfoParkInd > -1 Then
            ' Verifico se nella lista dei parcheggi è già presente l'indice indicato
            Dim localParkInd As ParkInd = P_List.Find(Function(x) x.Ind = nInfoParkInd)
            ' Se non trovo nessun parcheggio con questo indice allora lo aggiungo
            If IsNothing(localParkInd) Then
               Dim nStatus As Integer
               If Not EgtGetInfo(nPartId, INFO_PARKSTATUS, nStatus) Then nStatus = GDB_ST.ON_
               ' EgtGetStatus(nPartId, nStatus)
               P_List.Add(New ParkInd(nInfoParkInd, "Park_" & nInfoParkInd.ToString, nStatus))
            End If
         End If
         nPartId = EgtGetNextGroup(nPartId)
      End While
      ' Pezzi in parcheggio
      nPartId = EgtGetFirstPart()
      While nPartId <> GDB_ID.NULL
         Dim sInfoParkInd As String = String.Empty
         Dim nInfoParkInd As Integer = -1
         ' Recupero l'indice del parcheggio
         If EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then
            nInfoParkInd = If(IsNumeric(sInfoParkInd), CInt(sInfoParkInd), -1)
         Else
            nInfoParkInd = 0
         End If
         ' Se l'indice di parcheggio restituito è valido (Maggiore di -1)
         If nInfoParkInd > -1 Then
            ' Verifico se nella lista dei parcheggi è già presente l'indice indicato
            Dim localParkInd As ParkInd = P_List.Find(Function(x) x.Ind = nInfoParkInd)
            ' Se non trovo nessun parcheggio con questo indice allora lo aggiungo
            If IsNothing(localParkInd) Then
               Dim nStatus As Integer
               If Not EgtGetInfo(nPartId, INFO_PARKSTATUS, nStatus) Then nStatus = GDB_ST.ON_
               ' EgtGetStatus(nPartId, nStatus)
               P_List.Add(New ParkInd(nInfoParkInd, "Park_" & nInfoParkInd.ToString, nStatus))
            End If
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      EgtSetCurrentContext(CurrCtx)
   End Sub

   ' Aggiorna la lista dei parcheggi, se "bDraw=true" aggiorno la scena
   Public Shared Sub UpdateViewOnParkInd(Optional bDraw As Boolean = True)
      ' Ricarico la lista dei parcheggi
      Dim ListParkInd As New List(Of ParkInd)
      SelParkIndWD.LoadParkInd(ListParkInd)
      ' Aggiorna la vista dei parcheggi
      For Each Item As ParkInd In ListParkInd
         SelParkIndWD.SetStatusPartInParkInd(Item, bDraw)
      Next
   End Sub

   ' Restituisce il primo parcheggio attivo (
   Public Shared Function GetCurrentParkIndSelected() As ParkInd
      Dim ListParkInd As New List(Of ParkInd)
      SelParkIndWD.LoadParkInd(ListParkInd)
      ' Procedo a selezionare il primo (E ANCHE UNICO?..a volte no..) parcheggio attivo -> guarda funzione UpdateList <-
      For Each ItemPark As ParkInd In ListParkInd
         If ItemPark.IsStatusON Then
            Return ItemPark
         End If
      Next
      Return Nothing
   End Function

   ' Restitusice il nome del file immagine del parcheggio (manance solo dell'Indice di parcheggio e dell'esetensione png)
   Public Shared Function GetPathCurrProj() As String
      Dim nProj As Integer = m_MainWindow.m_CurrentProjectPageUC.GetCurrentProject()
      Dim sParkPath As String = m_MainWindow.GetSaveDir() & "\" & Math.Abs(nProj).ToString("D4") & "_ParkInd_"
      If Not String.IsNullOrEmpty(sActualProj) Then
         Dim sDir As String = System.IO.Path.GetDirectoryName(sActualProj)
         Dim sFile As String = System.IO.Path.GetFileNameWithoutExtension(sActualProj)
         sParkPath = sDir & "\" & sFile & "_ParkInd_"
      End If
      Return sParkPath
   End Function

   Public Shared Sub CopyImgSvg(sNewFileName As String, Optional nCtx As Integer = -1)
      If sNewFileName.EndsWith(".nge") Then
         sNewFileName = sNewFileName.Remove(sNewFileName.Length - 4, 4) & "_ParkInd_"
      End If
      Dim Extension As String = ".svg"
      If Not MainWindow.m_bShowSVGParkInd Then Extension = ".png"
      Dim ListParkInd As New List(Of ParkInd)
      ' ricarico la lista
      SelParkIndWD.LoadParkInd(ListParkInd, nCtx)
      'SelParkIndWD.sActualProj = Path.GetFileNameWithoutExtension(sPath)
      For Each ItemParkInd As ParkInd In ListParkInd
         If ItemParkInd.Ind <> 0 And ItemParkInd.Ind <> 999 And ItemParkInd.nPartInPark > 0 Then
            Try
               Dim sNewFile As String = sNewFileName & ItemParkInd.Ind.ToString & Extension
               If MainWindow.m_bShowSVGParkInd Then
                  WriteMyXML(sNewFile, ItemParkInd.LocalMyCanvas)
               Else
                  If System.IO.File.Exists(sNewFile) Then
                     System.IO.File.Delete(sNewFile)
                  End If
                  System.IO.File.Copy(If(Extension = ".svg", ItemParkInd.Svg, ItemParkInd.Img), sNewFile)
               End If
            Catch ex As Exception
               EgtOutLog("Copia immagine " & If(Extension = ".svg", ItemParkInd.Svg, ItemParkInd.Img) & " di ParkInd non roiscita")
            End Try
         End If
      Next
   End Sub

#End Region    ' Metodi Shared

End Class

Public Class ParkInd
   Implements INotifyPropertyChanged

   Private m_VisbilityAllOff As Visibility = Visibility.Hidden

   Private m_Ind As Integer
   Public Property Ind As Integer
      Get
         Return m_Ind
      End Get
      Set(value As Integer)
         m_Ind = value
      End Set
   End Property

   Private m_Name As String
   Public Property Name As String
      Get
         Return m_Name
      End Get
      Set(value As String)
         m_Name = value
      End Set
   End Property

   Private m_Img As String = String.Empty
   Public Property Img As String
      Get
         Return m_Img
      End Get
      Set(value As String)
         m_Img = value
         NotifyPropertyChanged("MyVisibilityImg")
      End Set
   End Property

   Private m_Svg As String = String.Empty
   Public Property Svg As String
      Get
         Return m_Svg
      End Get
      Set(value As String)
         m_Svg = value
         NotifyPropertyChanged("MyVisibilitySvg")
      End Set
   End Property

   Private m_nPartInTable As Integer = 0
   Public Property nPartInTable As Integer
      Get
         Return m_nPartInTable
      End Get
      Set(value As Integer)
         m_nPartInTable = value
         NotifyPropertyChanged(NameOf(nPartInTable))
      End Set
   End Property

   Private m_nPartInPark As Integer = GDB_ST.ON_
   Public Property nPartInPark As Integer
      Get
         Return m_nPartInPark
      End Get
      Set(value As Integer)
         m_nPartInPark = value
         NotifyPropertyChanged(NameOf(nPartInPark))
      End Set
   End Property

   Public ReadOnly Property CountInTab As String
      Get
         Return m_nPartInTable.ToString
      End Get
   End Property

   Public ReadOnly Property ImgTab As String
      Get
         Return DirectCast(Application.Current.MainWindow, MainWindow).GetResourcesDir() & "\MachineButtonsImage\NewIcons\table.png"
      End Get
   End Property

   Public ReadOnly Property CountInPark As String
      Get
         Return m_nPartInPark.ToString
      End Get
   End Property

   Public ReadOnly Property ImgPark As String
      Get
         Return DirectCast(Application.Current.MainWindow, MainWindow).GetResourcesDir() & "\MachineButtonsImage\NewIcons\Park.png"
      End Get
   End Property

   Private m_Status As Integer

   Public Property Status As Integer
      Get
         Return m_Status
      End Get
      Set(value As Integer)
         m_Status = value
         NotifyPropertyChanged(NameOf(IsStatusON))
      End Set
   End Property

   Public ReadOnly Property IsStatusON As Boolean
      Get
         Return (m_Status = GDB_ST.ON_)
      End Get
   End Property

   Public ReadOnly Property MyVisibilityTmg As Visibility
      Get
         Return If(Not System.IO.File.Exists(m_Img), Visibility.Collapsed, Visibility.Visible)
      End Get
   End Property

   Public ReadOnly Property MyVisibilitySvg As Visibility
      Get
         Return If(Not System.IO.File.Exists(m_Svg), Visibility.Collapsed, Visibility.Visible)
      End Get
   End Property

   Public ReadOnly Property TitleVisibility As Visibility
      Get
         Return If(m_Ind = 999, m_VisbilityAllOff, Visibility.Visible)
      End Get
   End Property

   Private m_LocalMyCanvas As MyCanvas
   Public ReadOnly Property LocalMyCanvas As MyCanvas
      Get
         Return m_LocalMyCanvas
      End Get
   End Property

   Sub New(Ind As Integer, Name As String, Stat As Integer)
      m_Ind = Ind
      m_Name = Name
      m_Status = Stat
      ' Costruisco il percorso immagine 
      If m_Ind = 0 Then
         ' Se Ind=0 allora applico il default: C:\EgtData\OmagCUT\Resources\MachineButtonsImage\NewIcons
         m_Img = DirectCast(Application.Current.MainWindow, MainWindow).GetResourcesDir() & "\MachineButtonsImage\NewIcons\Park_On.png"
         m_Svg = DirectCast(Application.Current.MainWindow, MainWindow).GetResourcesDir() & "\MachineButtonsImage\NewIcons\Park_On.svg"
      ElseIf m_Ind = 999 Then
         ' Se Ind=0 allora applico il default: C:\EgtData\OmagCUT\Resources\MachineButtonsImage\NewIcons
         m_Img = DirectCast(Application.Current.MainWindow, MainWindow).GetResourcesDir() & "\MachineButtonsImage\NewIcons\Park_Off.png"
         m_Svg = DirectCast(Application.Current.MainWindow, MainWindow).GetResourcesDir() & "\MachineButtonsImage\NewIcons\Park_Off.svg"
      Else
         m_Img = SelParkIndWD.GetPathCurrProj() & m_Ind.ToString & ".png"
         m_Svg = SelParkIndWD.GetPathCurrProj() & m_Ind.ToString & ".svg"
      End If

      If MainWindow.m_bShowSVGParkInd Then
         Dim CanvWidth As Integer = 145
         Dim CanvHeight As Integer = CInt(CanvWidth / 1.4)
         m_LocalMyCanvas = New MyCanvas(CanvWidth, CanvHeight)
         If System.IO.File.Exists(m_Svg) Then
            ReadMyXML(m_Svg, m_LocalMyCanvas)
            m_Img = ""
         End If
      Else
         m_Svg = ""
      End If

      ' Conto il numero di pezzi in Tavola
      CountPartInTable()
      ' Conto il numero di pezzi in parcheggio
      CountPartInPark()

   End Sub

   ' Conta in numero di pezzi di questo parcheggio in Tavola
   Private Sub CountPartInTable()
      Dim nCount As Integer = 0
      Dim nRawId As Integer = GetCurrentRaw()
      ' Leggo l'indice di parcheggio dei pezzi in tavola
      Dim nPartId As Integer = EgtGetFirstGroupInGroup(nRawId)
      While nPartId <> GDB_ID.NULL
         ' Aggiorno il valore del contatore
         If IncreaseCounterPart(nPartId, nCount) Then
            UpdateEntInCanvas(nPartId, 0.2)
         End If
         nPartId = EgtGetNextGroup(nPartId)
      End While
      m_nPartInTable = nCount
   End Sub

   ' Conta il numero di pezzi di questo parcheggio in Parcheggio
   Private Sub CountPartInPark()
      Dim nCount As Integer = 0
      Dim nPartId As Integer = EgtGetFirstPart()
      While nPartId <> GDB_ID.NULL
         ' Aggiorno il valore del contatore 
         If IncreaseCounterPart(nPartId, nCount) Then
            UpdateEntInCanvas(nPartId, 1)
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      m_nPartInPark = nCount
   End Sub

   Private Sub UpdateEntInCanvas(nPartId, dOpacity)
      If Not IsNothing(m_LocalMyCanvas) Then
         ' modifico il colore del pezzo nel SVG
         Dim nIdRegion As Integer = EgtGetFirstNameInGroup(nPartId, "Region")
         If nIdRegion <> GDB_ID.NULL Then
            Dim nIdEnt As Integer = EgtGetFirstInGroup(nIdRegion)
            While nIdEnt <> GDB_ID.NULL
               If EgtGetType(nIdEnt) = GDB_TY.SRF_FRGN Then
                  Exit While
               End If
            End While
            If nIdEnt <> GDB_ID.NULL Then
               Dim sName As String = ""
               EgtGetName(nIdEnt, sName)
               Dim Idpath As MyPath = m_LocalMyCanvas.ListPath.Find(Function(x) x.id = sName)
               If Not IsNothing(Idpath) Then
                  Idpath.fill_opacity = dOpacity
                  m_LocalMyCanvas.UpdateMyPath(Idpath)
                  Idpath.LoadPath()
                  NotifyPropertyChanged(NameOf(LocalMyCanvas))
               End If
            End If
         End If
      End If
   End Sub

   ' Verifica se il pezzo passato (da parcheggio o tavola) appartiene al ParkInd corrente e quindi aggiorna il valore di nCount+=1
   Private Function IncreaseCounterPart(nPartId As Integer, ByRef nCount As Integer) As Boolean
      Dim bOk As Boolean = False
      ' Se i pezzi non hanno un indice di parcheggio
      Dim sInfoParkInd As String = String.Empty
      Dim nInfoParkInd As Integer = -1
      ' Recupero l'indice del parcheggio
      If EgtGetInfo(nPartId, INFO_PARKIND, sInfoParkInd) Then
         nInfoParkInd = If(IsNumeric(sInfoParkInd), CInt(sInfoParkInd), -1)
      Else
         nInfoParkInd = 0
      End If
      ' Se l'indice di parcheggio restituito è valido (Maggiore di -1)
      If nInfoParkInd > -1 Then
         ' e uguale a quallo del parcheggio correntemente selezionato
         If nInfoParkInd = m_Ind Then
            nCount = nCount + 1
            bOk = True
         End If
      End If

      Return bOk
   End Function

   Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

   Public Sub NotifyPropertyChanged(propName As String)
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
   End Sub

End Class

#Region "ELEMENTI PER LA GESTIONE SVG"

Public Class MyCanvas

   Private m_CurrCanvas As New Canvas
   Public Property CurrCanvas As Canvas
      Get
         Return m_CurrCanvas
      End Get
      Set(value As Canvas)
         m_CurrCanvas = value
      End Set
   End Property

   Private m_ListPath As New List(Of MyPath)
   Public Property ListPath As List(Of MyPath)
      Get
         Return m_ListPath
      End Get
      Set(value As List(Of MyPath))
         m_ListPath = value
      End Set
   End Property

   Private m_ViewBoxDim As String
   Public Property ViewBoxDim As String
      Get
         Return m_ViewBoxDim
      End Get
      Set(value As String)
         m_ViewBoxDim = value
      End Set
   End Property

   Sub New(Width As Integer, Height As Integer)
      m_CurrCanvas.Width = Width
      m_CurrCanvas.Height = Height
      m_CurrCanvas.ClipToBounds = True
   End Sub

   Public Sub LoadCanvas()
      For Each ItemPath As MyPath In m_ListPath
         m_CurrCanvas.Children.Add(ItemPath.CurrPath)
      Next
   End Sub

   Public Sub UpdateMyPath(CurrPath As MyPath)
      m_CurrCanvas.Children.Remove(CurrPath.CurrPath)
      m_CurrCanvas.Children.Add(CurrPath.CurrPath)
   End Sub

End Class

Public Class MyPath

   Private m_CurrPath As New System.Windows.Shapes.Path
   Public Property CurrPath As System.Windows.Shapes.Path
      Get
         Return m_CurrPath
      End Get
      Set(value As System.Windows.Shapes.Path)
         m_CurrPath = value
      End Set
   End Property

   Private m_CanvX As Double
   Public ReadOnly Property CanvX As Double
      Get
         Return m_CanvX
      End Get
   End Property

   Private m_CanvY As Double
   Public ReadOnly Property CanvY As Double
      Get
         Return m_CanvY
      End Get
   End Property

   Private m_DimX As Double
   Public ReadOnly Property DimX As Double
      Get
         Return m_DimX
      End Get
   End Property

   Private m_DimY As Double
   Public ReadOnly Property DimY As Double
      Get
         Return m_DimY
      End Get
   End Property

   Private m_id As String
   Public ReadOnly Property id As String
      Get
         Return m_id
      End Get
   End Property

   Private m_d As String
   Public ReadOnly Property d As String
      Get
         Return m_d
      End Get
   End Property

   Private m_fill As String
   Public Property fill As String
      Get
         Return m_fill
      End Get
      Set(value As String)
         m_fill = value
      End Set
   End Property

   Private m_fill_opacity As Double
   Public Property fill_opacity As Double
      Get
         Return m_fill_opacity
      End Get
      Set(value As Double)
         m_fill_opacity = value
      End Set
   End Property

   Private m_stroke As String
   Public Property stroke As String
      Get
         Return m_stroke
      End Get
      Set(value As String)
         m_stroke = value
      End Set
   End Property

   Private m_stroke_opacity As Double
   Public Property stroke_opacity As Double
      Get
         Return m_stroke_opacity
      End Get
      Set(value As Double)
         m_stroke_opacity = value
      End Set
   End Property

   Private m_stroke_width As Double
   Public Property stroke_width As Double
      Get
         Return m_stroke_width
      End Get
      Set(value As Double)
         m_stroke_width = value
      End Set
   End Property

   Sub New(Id As String, D As String, CanvX As Double, CanvY As Double, DimX As Double, DimY As Double, Fill As String, FillOpacity As Double, Stroke As String, StrokeOpacity As Double)
      m_id = Id
      m_d = D
      m_CanvX = CanvX
      m_CanvY = CanvY
      m_DimX = DimX
      m_DimY = DimY
      m_fill = Fill
      m_fill_opacity = FillOpacity
      m_stroke = Stroke
      m_stroke_opacity = StrokeOpacity
      LoadPath()
   End Sub

   Public Sub LoadPath()
      ' Carico la geometria
      m_CurrPath.Data = Geometry.Parse(d)
      ' Carico il colore di sfondo
      SetBrushFromRGBString(m_fill, m_CurrPath.Fill)
      ' Applico l'opacità della superificie
      m_CurrPath.Opacity = m_fill_opacity
      ' Calcolo e applico la traslazione e la scalatura
      Dim myTransformGroup As New TransformGroup()
      Dim ScaleX As Double = m_CanvX / DimX
      Dim ScaleY As Double = m_CanvY / DimY
      Dim OffX As Double = (m_CanvX - Math.Min(ScaleX, ScaleY) * DimX) / 2
      Dim OffY As Double = (m_CanvY - Math.Min(ScaleX, ScaleY) * DimY) / 2
      myTransformGroup.Children.Add(New ScaleTransform(Math.Min(ScaleX, ScaleY), Math.Min(ScaleX, ScaleY)))
      myTransformGroup.Children.Add(New TranslateTransform(OffX, OffY))
      m_CurrPath.RenderTransform = myTransformGroup
   End Sub

   Private Sub SetBrushFromRGBString(sFill As String, ByRef brFill As Brush)
      If String.IsNullOrEmpty(sFill) Then
         brFill = Brushes.DarkRed
         Return
      End If
      Dim s1 As String = sFill
      If s1.Contains("rgb") Then
         s1 = s1.Replace("rgb(", "")
         s1 = s1.Replace(")", "")
         Dim s2 As String = ""
         For Each s As String In s1.Split(",")
            s2 &= CInt(s).ToString("x2")
         Next
         brFill = New BrushConverter().ConvertFrom("#" & s2)
      End If
   End Sub

End Class

Public Module XMLReader

   Public Sub ReadMyXML(FilePath As String, Canv As MyCanvas)
      'Create the XML Reader
      Dim m_xmlr As XmlTextReader = New XmlTextReader(FilePath)
      'Disable whitespace so that you don't have to read over whitespaces
      m_xmlr.WhitespaceHandling = WhitespaceHandling.None
      ' Leggo la prima riga: '?xml' tag
      m_xmlr.Read()
      ' Passo a leggere la successiva: 'svg' tag
      m_xmlr.Read()
      ' Leggo gli attributi di questo tag (dimensioni)
      Dim ViewBoxDim = m_xmlr.GetAttribute("viewBox")
      Canv.ViewBoxDim = ViewBoxDim
      ' Elaboro i dati per avere la scalatura del disegno
      Dim DimViewBox As String() = ViewBoxDim.ToString.Split(" ")
      Dim DimX As Integer = Math.Abs(CInt(DimViewBox(2))) + Math.Abs(CInt(DimViewBox(0)))
      Dim DimY As Integer = Math.Abs(CInt(DimViewBox(3))) + Math.Abs(CInt(DimViewBox(1)))

      ' Leggo in loop i tag: 'path'
      While Not m_xmlr.EOF
         m_xmlr.Read()
         If Not m_xmlr.IsStartElement() Then
            Continue While
         End If
         ' recupero il valore dell'attributo 'id'
         Dim idAttribute = m_xmlr.GetAttribute("id")
         ' recupero il valore dell'attributo 'd'
         Dim dAttribute = m_xmlr.GetAttribute("d")
         ' recupero il valore dell'attributo 'fill'
         Dim fillAttribute = m_xmlr.GetAttribute("fill")
         ' recupero il valore dell'attributo 'fill-opacity'
         Dim fillOpacityAttribute = m_xmlr.GetAttribute("fill-opacity")
         ' recupero il valore dell'attributo 'stroke'
         Dim strokeAttribute = m_xmlr.GetAttribute("stroke")
         ' recupero il valore dell'attributo 'stroke-opacity'
         Dim strokeOpacityAttribute = m_xmlr.GetAttribute("stroke-opacity")
         ' recupero il valore dell'attributo 'stroke - Width'
         Dim strokeWidthAttribute = m_xmlr.GetAttribute("stroke-width")
         ' carico l'elemento in lista solo se esiste un'immagine
         If Not String.IsNullOrEmpty(idAttribute) And Not String.IsNullOrEmpty(dAttribute) Then
            Dim fillOpacity As Double = 1 ' CDbl(fillOpacityAttribute)
            StringToDouble(fillOpacityAttribute, fillOpacity)
            Dim strokeOpacity As Double = 1 ' CDbl(strokeOpacityAttribute)
            StringToDouble(strokeOpacityAttribute, strokeOpacity)
            Canv.ListPath.Add(New MyPath(idAttribute, dAttribute, Canv.CurrCanvas.Width, Canv.CurrCanvas.Height, DimX, DimY, fillAttribute, fillOpacity, strokeAttribute, strokeOpacity))
         End If

      End While
      ' Libero il file dalla lettura
      m_xmlr.Close()
      ' popolo la canvas con le Ptah che ho caricato
      Canv.LoadCanvas()
   End Sub

   Public Sub WriteMyXML(FilePath As String, Canv As MyCanvas)

      Dim _namespaceDefault As String = "http://www.w3.org/2000/svg"

      Dim doc As New Xml.XmlDocument

      Dim elm As System.Xml.XmlNode
      Dim elmSub As System.Xml.XmlNode
      Dim elmMain As Xml.XmlNode

      doc = New Xml.XmlDocument

      elmMain = doc.CreateElement("svg")
      elmSub = elmMain.Attributes.Append(doc.CreateAttribute("viewBox"))
      elmSub.Value = Canv.ViewBoxDim
      elmSub = elmMain.Attributes.Append(doc.CreateAttribute("xmlns"))
      elmSub.Value = _namespaceDefault

      For Each itemPath As MyPath In Canv.ListPath
         elm = elmMain.AppendChild(doc.CreateElement("path"))

         elmSub = elm.Attributes.Append(doc.CreateAttribute("id"))
         elmSub.Value = itemPath.id

         elmSub = elm.Attributes.Append(doc.CreateAttribute("d"))
         elmSub.Value = itemPath.d

         If Not String.IsNullOrEmpty(itemPath.fill) Then
            elmSub = elm.Attributes.Append(doc.CreateAttribute("fill"))
            elmSub.Value = itemPath.fill
         End If

         If Not String.IsNullOrEmpty(itemPath.fill_opacity) Then
            elmSub = elm.Attributes.Append(doc.CreateAttribute("fill-opacity"))
            elmSub.Value = itemPath.fill_opacity.ToString(CultureInfo.InvariantCulture)
         End If

         If Not String.IsNullOrEmpty(itemPath.stroke) Then
            elmSub = elm.Attributes.Append(doc.CreateAttribute("stroke"))
            elmSub.Value = itemPath.stroke
         End If

         If Not String.IsNullOrEmpty(itemPath.stroke_opacity) Then
            elmSub = elm.Attributes.Append(doc.CreateAttribute("stroke-opacity"))
            elmSub.Value = itemPath.stroke_opacity.ToString(CultureInfo.InvariantCulture)
         End If

         If Not String.IsNullOrEmpty(itemPath.stroke_width) Then
            elmSub = elm.Attributes.Append(doc.CreateAttribute("stroke-width"))
            elmSub.Value = itemPath.stroke_width.ToString(CultureInfo.InvariantCulture)
         End If

      Next

      doc.AppendChild(doc.CreateXmlDeclaration("1.0", "UTF-8", ""))
      doc.AppendChild(elmMain)
      doc.Save(FilePath)

   End Sub

End Module

#End Region    ' Elementi per la gestione SVG