Imports EgtUILib
Imports System.IO

Friend Module CSVFile

   Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)

   '-----------------------------------------------------------------------------------------------
   Friend Class CsvPart
      Public m_sPath As String = String.Empty
      Public m_sName As String = String.Empty
      Public m_sOrd As String = String.Empty
      Public m_sDist As String = String.Empty
      Public m_sMaterial As String = String.Empty
      Public m_bActive As Boolean = True
      Public m_nCount As Integer = 0
      Public m_nAdd As Integer = 0
      Public m_nToNest As Integer = 0
      Public m_bIsRect As Boolean = True
      Public m_dDimX As Double = 0
      Public m_dDimY As Double = 0
      Public m_dTh As Double = 0
      Public m_dAng1 As Double = 0
      Public m_dHeel1 As Double = 0
      Public m_dAng2 As Double = 0
      Public m_dHeel2 As Double = 0
      Public m_dAng3 As Double = 0
      Public m_dHeel3 As Double = 0
      Public m_dAng4 As Double = 0
      Public m_dHeel4 As Double = 0
      Public m_nOriInd As Integer = 0
      Public m_nId As Integer = GDB_ID.NULL
      ' definsco il riferimento al gruppo
      Public m_sRefGuid As String = System.Guid.NewGuid.ToString
      ' definisco il colore del gruppo che sto inserendo
      Public m_cColor As Color3d = CompoColor(m_MainWindow.GetIniFile())
   End Class

   '-----------------------------------------------------------------------------------------------
   Friend Function ReadCsvFile(sFile As String, bFull As Boolean, ByRef sCsvPath As String, ByRef CsvPartList As List(Of CsvPart)) As Boolean
      ' Definizione variabili
      EgtLuaCreateGlobTable("CSV")
      EgtLuaSetGlobStringVar("CSV.FILE", sFile)
      ' Path script da eseguire
      Dim sReader As String = String.Empty
      GetPrivateProfileString(S_CSV, K_READER, "CsvRead.lua", sReader, m_MainWindow.GetIniFile())
      Dim sLuaScript As String = m_MainWindow.GetCsvAutoDir() & If(bFull, "\" & sReader, "\CsvSimplRead.lua")
      ' Esecuzione
      Dim nErr As Integer = 999
      If EgtLuaExecFile(sLuaScript) AndAlso
         EgtLuaCallFunction("CSV.Read") Then
         ' Verifica stato di errore
         EgtLuaGetGlobIntVar("CSV.ERR", nErr)
      End If
      If nErr <> 0 Then
         EgtOutLog("Error in CsvRead : " & nErr.ToString())
         Return False
      End If
      ' Assegno path
      sCsvPath = sFile
      ' Preparo lista dei pezzi
      Dim nNbr As Integer = 0
      EgtLuaGetGlobIntVar("CSV.NBR", nNbr)
      For i As Integer = 1 To nNbr
         Dim OnePart As New CsvPart
         Dim sN As String = i.ToString()
         OnePart.m_sPath = sFile
         EgtLuaGetGlobStringVar("CSV.NAME" & sN, OnePart.m_sName)
         OnePart.m_bActive = True
         EgtLuaGetGlobStringVar("CSV.ORD" & sN, OnePart.m_sOrd)
         EgtLuaGetGlobStringVar("CSV.DIST" & sN, OnePart.m_sDist)
         EgtLuaGetGlobStringVar("CSV.MAT" & sN, OnePart.m_sMaterial)
         EgtLuaGetGlobIntVar("CSV.COUNT" & sN, OnePart.m_nCount)
         OnePart.m_nToNest = OnePart.m_nCount
         EgtLuaGetGlobBoolVar("CSV.RECT" & sN, OnePart.m_bIsRect)
         EgtLuaGetGlobNumVar("CSV.DIMX" & sN, OnePart.m_dDimX)
         EgtLuaGetGlobNumVar("CSV.DIMY" & sN, OnePart.m_dDimY)
         EgtLuaGetGlobNumVar("CSV.TH" & sN, OnePart.m_dTh)
         EgtLuaGetGlobNumVar("CSV.A1_" & sN, OnePart.m_dAng1)
         EgtLuaGetGlobNumVar("CSV.H1_" & sN, OnePart.m_dHeel1)
         EgtLuaGetGlobNumVar("CSV.A2_" & sN, OnePart.m_dAng2)
         EgtLuaGetGlobNumVar("CSV.H2_" & sN, OnePart.m_dHeel2)
         EgtLuaGetGlobNumVar("CSV.A3_" & sN, OnePart.m_dAng3)
         EgtLuaGetGlobNumVar("CSV.H3_" & sN, OnePart.m_dHeel3)
         EgtLuaGetGlobNumVar("CSV.A4_" & sN, OnePart.m_dAng4)
         EgtLuaGetGlobNumVar("CSV.H4_" & sN, OnePart.m_dHeel4)
         OnePart.m_nOriInd = i
         If OnePart.m_nCount > 1 Then
            OnePart.m_sRefGuid = System.Guid.NewGuid.ToString
         End If
         ' inserisco in lista
         CsvPartList.Add(OnePart)
      Next
      EgtLuaResetGlobVar("CSV")
      ' Ordinamento lista dei pezzi (ordine crescente su materiale e spessore)
      CsvPartList.Sort(Function(x, y)
                        Dim nComp As Integer = String.Compare(x.m_sMaterial, y.m_sMaterial, True)
                        If nComp = 0 Then
                           If Math.Abs(x.m_dTh - y.m_dTh) < EPS_SMALL Then
                              Return (x.m_nOriInd - y.m_nOriInd)
                           Else
                              Return CInt(Math.Ceiling(x.m_dTh - y.m_dTh))
                           End If
                        Else
                           Return nComp
                        End If
                     End Function)
      Return True
   End Function

   Friend Function ReadCsvPartList(sFile As String, ByRef sCsvPath As String, ByRef CsvPartList As List(Of CsvPart)) As Boolean
      ' Gestione file
      Try
         ' Apro file
         Dim Reader As New IO.StreamReader(sFile, False)
         ' Lettura intestazione
         Dim sLine As String = Reader.ReadLine()
         While sLine <> Nothing
            If sLine = "[General]" Then
               ' non devo fare alcunché
            ElseIf sLine.Length() >= 5 AndAlso sLine.Substring(0, 5) = "Path=" Then
               Dim sItems() As String = sLine.Split("=".ToCharArray)
               If sItems.Count() >= 2 Then
                  sCsvPath = sItems(1)
               End If
            Else
               Exit While
            End If
            sLine = Reader.ReadLine()
         End While
         ' Ciclo di lettura dei pezzi
         Dim nI As Integer = 1
         Dim sPart As String = "[P" & nI.ToString() & "]"
         Dim OnePart As New CsvPart
         While sLine <> Nothing
            ' Inizio pezzo o fine del file
            If sLine = sPart Or sLine = "[END]" Then
               ' se esiste pezzo precedente, lo salvo
               If nI > 1 Then
                  ' inserisco in lista
                  CsvPartList.Add(OnePart)
               End If
               ' predisposizioni per prossimo pezzo
               nI += 1
               sPart = "[P" & nI.ToString() & "]"
               OnePart = New CsvPart
            ' Dato
            Else
               Dim sItems() As String = sLine.Split("=".ToCharArray)
               If sItems.Count() >= 2 Then
                  If sItems(0) = "Path" Then
                     OnePart.m_sPath = sItems(1)
                  ElseIf sItems(0) = "Nam" Then
                     OnePart.m_sName = sItems(1)
                  ElseIf sItems(0) = "Ord" Then
                     OnePart.m_sOrd = sItems(1)
                  ElseIf sItems(0) = "Dist" Then
                     OnePart.m_sDist = sItems(1)
                  ElseIf sItems(0) = "Mat" Then
                     OnePart.m_sMaterial = sItems(1)
                  ElseIf sItems(0) = "Act" Then
                     OnePart.m_bActive = If(sItems(1) = "0", False, True)
                  ElseIf sItems(0) = "Cnt" Then
                     StringToInt(sItems(1), OnePart.m_nCount)
                  ElseIf sItems(0) = "Add" Then
                     StringToInt(sItems(1), OnePart.m_nAdd)
                  ElseIf sItems(0) = "ToN" Then
                     StringToInt(sItems(1), OnePart.m_nToNest)
                  ElseIf sItems(0) = "Rct" Then
                     OnePart.m_bIsRect = If(sItems(1) = "0", False, True)
                  ElseIf sItems(0) = "DX" Then
                     StringToDouble(sItems(1), OnePart.m_dDimX)
                  ElseIf sItems(0) = "DY" Then
                     StringToDouble(sItems(1), OnePart.m_dDimY)
                  ElseIf sItems(0) = "Th" Then
                     StringToDouble(sItems(1), OnePart.m_dTh)
                  ElseIf sItems(0) = "A1" Then
                     StringToDouble(sItems(1), OnePart.m_dAng1)
                  ElseIf sItems(0) = "H1" Then
                     StringToDouble(sItems(1), OnePart.m_dHeel1)
                  ElseIf sItems(0) = "A2" Then
                     StringToDouble(sItems(1), OnePart.m_dAng2)
                  ElseIf sItems(0) = "H2" Then
                     StringToDouble(sItems(1), OnePart.m_dHeel2)
                  ElseIf sItems(0) = "A3" Then
                     StringToDouble(sItems(1), OnePart.m_dAng3)
                  ElseIf sItems(0) = "H3" Then
                     StringToDouble(sItems(1), OnePart.m_dHeel3)
                  ElseIf sItems(0) = "A4" Then
                     StringToDouble(sItems(1), OnePart.m_dAng4)
                  ElseIf sItems(0) = "H4" Then
                     StringToDouble(sItems(1), OnePart.m_dHeel4)
                  ElseIf sItems(0) = "OIn" Then
                     StringToInt(sItems(1), OnePart.m_nOriInd)
                  ElseIf sItems(0) = "Guid" Then
                     OnePart.m_sRefGuid = sItems(1).Trim
                  End If
               End If
            End If
            sLine = Reader.ReadLine()
         End While
         ' Chiudo il file
         Reader.Close()
         Return True
      ' Errore
      Catch ex As Exception
         EgtOutLog("Error reading " & sFile)
         Return False
      End Try
   End Function

   Friend Function WriteCsvPartList(sFile As String, sCsvPath As String, CsvPartList As List(Of CsvPart)) As Boolean
      ' Gestione file
      Try
         ' Apro file
         Dim Writer As New IO.StreamWriter(sFile, False)
         ' Intestazione
         Writer.WriteLine("[General]")
         Writer.WriteLine("Path=" & sCsvPath)
         ' Ciclo sui pezzi
         For i As Integer = 1 To CsvPartList.Count()
            Dim CurrPart As CsvPart = CsvPartList(i - 1)
            Writer.WriteLine("[P" & i.ToString() & "]")
            Writer.WriteLine("Path=" & CurrPart.m_sPath)
            Writer.WriteLine("Nam=" & CurrPart.m_sName)
            Writer.WriteLine("Ord=" & CurrPart.m_sOrd)
            Writer.WriteLine("Dist=" & CurrPart.m_sDist)
            Writer.WriteLine("Mat=" & CurrPart.m_sMaterial)
            Writer.WriteLine("Act=" & If(CurrPart.m_bActive, "1", "0"))
            Writer.WriteLine("Cnt=" & CurrPart.m_nCount.ToString())
            Writer.WriteLine("Add=" & CurrPart.m_nAdd.ToString())
            Writer.WriteLine("ToN=" & CurrPart.m_nToNest.ToString())
            Writer.WriteLine("Rct=" & If(CurrPart.m_bIsRect, "1", "0"))
            Writer.WriteLine("DX=" & DoubleToString(CurrPart.m_dDimX, 4))
            Writer.WriteLine("DY=" & DoubleToString(CurrPart.m_dDimY, 4))
            Writer.WriteLine("Th=" & DoubleToString(CurrPart.m_dTh, 4))
            Writer.WriteLine("A1=" & DoubleToString(CurrPart.m_dAng1, 4))
            Writer.WriteLine("H1=" & DoubleToString(CurrPart.m_dHeel1, 4))
            Writer.WriteLine("A2=" & DoubleToString(CurrPart.m_dAng2, 4))
            Writer.WriteLine("H2=" & DoubleToString(CurrPart.m_dHeel2, 4))
            Writer.WriteLine("A3=" & DoubleToString(CurrPart.m_dAng3, 4))
            Writer.WriteLine("H3=" & DoubleToString(CurrPart.m_dHeel3, 4))
            Writer.WriteLine("A4=" & DoubleToString(CurrPart.m_dAng4, 4))
            Writer.WriteLine("H4=" & DoubleToString(CurrPart.m_dHeel4, 4))
            Writer.WriteLine("OIn=" & CurrPart.m_nOriInd.ToString())
            Writer.WriteLine("Guid=" & CurrPart.m_sRefGuid)
         Next
         ' Terminatore
         Writer.WriteLine("[END]")
         ' Chiudo file
         Writer.Close()
         Return True
         ' Errore
      Catch ex As Exception
         EgtOutLog("CSV List error writing " & sFile)
         Return False
      End Try
   End Function

   ' dato l'elenco completo dei file salvo ogni singolo epl 
   Friend Function WriteCsvMergePartList(CsvPartList As List(Of CsvPart)) As Boolean
      Dim bOk As Boolean = True
      Dim LocalPartList As New List(Of CsvPart)
      Dim Index As Integer = 0
      ' devo dividere la lista in tante parti quanti sono i file che lo costituiscono
      While Index < CsvPartList.Count
         Dim CurrFile As String = CsvPartList(Index).m_sPath
         Dim sFile As String = Path.ChangeExtension(CurrFile, ".epl")
         LocalPartList.Clear()
         While CurrFile = CsvPartList(Index).m_sPath
            LocalPartList.Add(CsvPartList(Index))
            Index += 1
            ' se terminata la lista
            If Index = CsvPartList.Count Then
               Exit While
            End If
         End While
         ' salvo l'elenco corrente
         bOk = WriteCsvPartList(sFile, CurrFile, LocalPartList) And bOk
      End While
      Return bOk
   End Function

   Friend Function RemoveNotToNestParts(ByRef CsvPartList As List(Of CsvPart)) As Boolean
      For i As Integer = CsvPartList.Count() - 1 To 0 Step -1
         If CsvPartList(i).m_nToNest = 0 Then
            CsvPartList.RemoveAt(i)
         End If
      Next
      Return True
   End Function

   Friend Function RemoveWrongParts(ByRef CsvPartList As List(Of CsvPart)) As Boolean
      For i As Integer = CsvPartList.Count() - 1 To 0 Step -1
         If Not CsvPartList(i).m_bIsRect Or CsvPartList(i).m_dDimX < EPS_SMALL Or CsvPartList(i).m_dDimY < EPS_SMALL Then
            CsvPartList.RemoveAt(i)
         End If
      Next
      Return True
   End Function

End Module
