Public Class Zakazky
    Dim Zdroj As String
    Public PoleVyrobku() As String
    Public PocetDruhu As Integer
    Dim txtOutput As String
    Public Vysledne_pole(50) As Integer
    Public pom_pole(50) As Single
    Public min As Single
    Public Zacatek_prace As Date
    Public PocetZakazek As Integer
    Dim connection As OleDbConnection
    Dim pripona, oznaceni As String
    Dim usek1, usek2 As Single
    Public MinReseni() As Integer

    Public Structure Zakazky_objekt
        Public id As Integer
        Public id_zakazky As String
        Public id_vyrobku As String
        Public index_vyrobku As Integer
        Public termin As Single
        Public termin_zacatku As Single
        Public termin_konce As Single
        Public vyroba As Single
        Public priorita As Single
    End Structure

    Public ListZakazek As New List(Of Zakazky_objekt)
    Private Sub DB_open_button_Click(sender As Object, e As EventArgs) Handles DB_open_button.Click
        Dim i, j As Integer
        Dim pomret As String
        Dim obsahuje As Boolean
        Dim path As String

        OpenFileDialog1 = New OpenFileDialog()

        OpenFileDialog1.Filter = "DB File|*.mdb"
        Dim result As DialogResult = OpenFileDialog1.ShowDialog()

        If result = Windows.Forms.DialogResult.OK Then
            path = OpenFileDialog1.FileName
        Else
            Exit Sub

        End If


        connection = New OleDbConnection("Provider = Microsoft.Jet.OLEDB.4.0;Data Source=" & path)
        connection.Open()

        Dim command As New OleDbCommand("SELECT ORDNUM FROM ALTERN", connection)
        Dim myReader As OleDbDataReader = command.ExecuteReader()
        While myReader.Read()
            pripona = myReader.GetValue(0).ToString
        End While

        Get_cela_pripona(pripona)

        myReader.Close()

        'MsgBox("db otevrena")
        command = New OleDbCommand("SELECT ORDERID, PARTID, ORDSIZE, DUEDATE, PRIORITY FROM ORDER" & oznaceni, connection)
        myReader = command.ExecuteReader()
        i = 0

        While myReader.Read()
            If i = 0 Then
                Zakazky_tabulka.Columns.Add("jmeno", myReader.GetName(0).ToString)
                Zakazky_tabulka.Columns.Add("jmeno", myReader.GetName(1).ToString)
                Zakazky_tabulka.Columns.Add("jmeno", myReader.GetName(2).ToString)
                Zakazky_tabulka.Columns.Add("jmeno", myReader.GetName(3).ToString)
                Zakazky_tabulka.Columns.Add("jmeno", myReader.GetName(4).ToString)
                Zakazky_tabulka.Columns(3).Width = 150

            End If
            Zakazky_tabulka.Rows.Add()
            Zakazky_tabulka.Rows(i).Cells(0).Value = myReader.GetString(0)
            Zakazky_tabulka.Rows(i).Cells(1).Value = myReader.GetValue(1)
            Zakazky_tabulka.Rows(i).Cells(2).Value = myReader.GetValue(2)
            Zakazky_tabulka.Rows(i).Cells(3).Value = myReader.GetDateTime(3)
            Zakazky_tabulka.Rows(i).Cells(4).Value = myReader.GetValue(4)
            Zakazky_tabulka.Rows(i).HeaderCell.Value = i + 1 & "."

            i += 1

        End While
        myReader.Close()

        command = New OleDbCommand("SELECT DISTINCT ORDER" & oznaceni & ".PARTID, PART" & oznaceni & ".PROCPLANID, JOBSTEP" & oznaceni & ".RESID1 FROM ((ORDER" & oznaceni & " INNER JOIN PART" & oznaceni & " ON ORDER" & oznaceni & ".PARTID = PART" & oznaceni & ".PARTID) INNER JOIN JOBSTEP" & oznaceni & " ON PART" & oznaceni & ".PROCPLANID = JOBSTEP" & oznaceni & ".PROCPLANID)", connection)
        myReader = command.ExecuteReader()
        i = 0
        While myReader.Read()
            If i = 0 Then
                Vyrobky_tabulka.Columns.Add("jmeno", myReader.GetName(0).ToString)
                Vyrobky_tabulka.Columns.Add("jmeno", myReader.GetName(1).ToString)
                Vyrobky_tabulka.Columns.Add("jmeno", myReader.GetName(2).ToString)

            End If
            Vyrobky_tabulka.Rows.Add()
            Vyrobky_tabulka.Rows(i).Cells(0).Value = myReader.GetString(0)
            Vyrobky_tabulka.Rows(i).Cells(1).Value = myReader.GetValue(1)
            Vyrobky_tabulka.Rows(i).Cells(2).Value = myReader.GetValue(2)

            i += 1

        End While

        connection.Close()

        For i = 0 To Vyrobky_tabulka.Rows.Count - 1
            pomret = Vyrobky_tabulka.Rows(i).Cells(2).Value
            obsahuje = False
            If pomret <> Nothing And pomret <> " " Then


                For j = 0 To Vyber_uzke_misto.Items.Count - 1
                    If pomret = Vyber_uzke_misto.Items.Item(j).ToString Then
                        obsahuje = True
                    End If
                Next
                If Not obsahuje Then
                    Vyber_uzke_misto.Items.Add(pomret)
                End If
            End If

        Next

        Vyber_uzke_misto.Enabled = True
        Create_matrix_button.Enabled = True
        DB_open_button.Enabled = False

    End Sub

    Private Sub Zakazky_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Left = 50
        Me.Top = 10
        Vyber_uzke_misto.Enabled = False
        Create_matrix_button.Enabled = False
        Datum_zacatku.Enabled = False
        Optimalizace_button.Enabled = False
    End Sub

    Private Sub Create_matrix_button_Click(sender As Object, e As EventArgs) Handles Create_matrix_button.Click
        Dim i, j, k, row, col, l As Integer
        Dim obsahuje As Boolean
        Dim datum As Single

        Dim querystring As String
        If Vyber_uzke_misto.SelectedItem = Nothing Then
            MsgBox("Vyberte úzké místo!")
            Exit Sub
        Else
            Zdroj = Vyber_uzke_misto.SelectedItem.ToString
        End If


        k = 0
        For i = 0 To Zakazky_tabulka.Rows.Count - 1
            obsahuje = False
            If Not i = 0 Then
                'MsgBox("j = " & PoleVyrobku.Count)
                For j = 0 To PoleVyrobku.Count - 1
                    If PoleVyrobku(j) = Zakazky_tabulka.Rows(i).Cells(1).Value Then
                        obsahuje = True
                    End If
                Next
            End If
            If Not obsahuje Then
                ReDim Preserve PoleVyrobku(k)
                PoleVyrobku(k) = Zakazky_tabulka.Rows(i).Cells(1).Value
                k += 1
            End If

        Next


        PocetDruhu = PoleVyrobku.Count
        'For i = 0 To PoleVyrobku.Count - 1
        '    MsgBox(PoleVyrobku(i))
        'Next


        For i = 0 To PocetDruhu - 1
            Serizovaci_tabulka.Columns.Add(PoleVyrobku(i), PoleVyrobku(i))
            Serizovaci_tabulka.Rows.Add()
            Serizovaci_tabulka.Rows(i).HeaderCell.Value = PoleVyrobku(i)

        Next
        connection.Open()

        'MsgBox("db otevrena")
        querystring = "SELECT PARTID1, PARTID2, ATIME FROM LOOKUP" & oznaceni & " WHERE RESID='" & Zdroj & "'"
        'MsgBox(querystring)
        Dim command As New OleDbCommand(querystring, connection)
        Dim myReader As OleDbDataReader = command.ExecuteReader()

        i = 0
        While myReader.Read
            row = GetIndex(myReader.GetValue(0).ToString)
            col = GetIndex(myReader.GetValue(1).ToString)
            If row <> 120 And col <> 120 Then
                Serizovaci_tabulka.Rows(row).Cells(col).Value = Single.Parse(myReader.GetValue(2), System.Globalization.NumberFormatInfo.InvariantInfo)
                i += 1
            End If

        End While

        l = 0
        If PocetDruhu < 8 Then
            Vysledne_pole(1) = 1
            Kombinace(1, PocetDruhu)

            ReDim MinReseni(Zakazky_tabulka.Rows.Count - 1)

            txtOutput &= "Idealní pořadí výrobků je: " & Environment.NewLine
            For i = 1 To PocetDruhu
                txtOutput &= PoleVyrobku(pom_pole(i) - 1) & " -> "
            Next
            txtOutput &= Environment.NewLine & "Idealní pořadí zakázek je: " & Environment.NewLine
            For i = 1 To PocetDruhu
                For j = 0 To Zakazky_tabulka.Rows.Count - 1
                    If Zakazky_tabulka.Rows(j).Cells(1).Value = PoleVyrobku(pom_pole(i) - 1) Then
                        txtOutput &= Zakazky_tabulka.Rows(j).Cells(0).Value & " -> "
                        MinReseni(l) = j + 1
                        l += 1
                    End If
                Next

            Next
            txtOutput &= Environment.NewLine & Environment.NewLine & "Celkový minimální přeseřizovací čas je " & min & " hodin." & Environment.NewLine
        ElseIf PocetDruhu >= 8 Then
            txtOutput &= "POZOR, počet výrobků je příliš velký! Pokud chcete zjistit pořadí pro minimální celkový přeseřizovaí čas, spustěte modul optimalizace a jako váhu přseřízení zvolte 1 a váhu zpoždění 0. " & Environment.NewLine


        End If

        myReader.Close()
        connection.Close()

        Poradi_zakazek_textbox.Text = txtOutput


        Datum_zacatku.Enabled = True
        Optimalizace_button.Enabled = True


    End Sub

    Private Function GetIndex(retezec As String) As Integer
        Dim i = 0

        For i = 0 To PoleVyrobku.Count - 1
            If retezec = PoleVyrobku(i) Then
                GetIndex = i
                Exit Function
            End If
        Next
        GetIndex = 120
    End Function

    Private Sub Kombinace(Pocatek As Integer, Pocet_Druhu As Integer)
        Dim i, j As Integer
        Dim soucet As Single
        Dim first As Boolean



        Do
            Vysledne_pole(Pocatek + 1) = 1
            If (Pocatek + 1) < Pocet_Druhu Then
                Kombinace(Pocatek + 1, Pocet_Druhu)
            Else
                Do
                    For i = 1 To Pocet_Druhu
                        For j = i + 1 To Pocet_Druhu
                            If Vysledne_pole(i) = Vysledne_pole(j) Then
                                GoTo Skok1
                            End If



                        Next
                    Next
                    soucet = 0
                    For i = 1 To Pocet_Druhu
                        'txtOutput &= Vysledne_pole(i) & " "

                    Next

                    For i = 1 To Pocet_Druhu - 1
                        soucet += Serizovaci_tabulka.Rows(Vysledne_pole(i) - 1).Cells(Vysledne_pole(i + 1) - 1).Value
                    Next

                    first = True
                    For i = 1 To Pocet_Druhu
                        If Vysledne_pole(i) <> i Then
                            first = False
                        End If
                    Next
                    If first Then
                        min = soucet
                        For i = 1 To Pocet_Druhu
                            pom_pole(i) = Vysledne_pole(i)
                        Next
                    ElseIf soucet < min Then
                        min = soucet
                        For i = 1 To Pocet_Druhu
                            pom_pole(i) = Vysledne_pole(i)
                        Next

                    End If
                    'txtOutput &= " = " & soucet
                    'txtOutput &= Environment.NewLine

Skok1:
                    Vysledne_pole(Pocatek + 1) += 1

                Loop Until Vysledne_pole(Pocatek + 1) > Pocet_Druhu
            End If

            Vysledne_pole(Pocatek) += 1
        Loop Until Vysledne_pole(Pocatek) > Pocet_Druhu


    End Sub


    Private Function Spocitat_dobu_vyroby_vyrobku(vyrobek As String) As Single
        Dim querystring As String
        Dim Kroky(,) As String
        Dim Pompole(,) As String
        Dim i, j, k As Integer
        Dim soucet As Single
        Dim aktualnikrok As String
        Dim aktualni_doba As Single
        Dim pricitat As Boolean
        pricitat = False
        soucet = 0
        connection.Open()

        querystring = "SELECT JOBSTEP" & oznaceni & ".JSID, JOBSTEP" & oznaceni & ".NEXTJSID, JOBSTEP" & oznaceni & ".STEPEXP, JOBSTEP" & oznaceni & ".RESID1 FROM PART" & oznaceni & " INNER JOIN JOBSTEP" & oznaceni & " ON PART" & oznaceni & ".PROCPLANID=JOBSTEP" & oznaceni & ".PROCPLANID WHERE PARTID='" & vyrobek & "'"

        Dim command As New OleDbCommand(querystring, connection)

        Dim myReader As OleDbDataReader = command.ExecuteReader()

        i = 0
        ReDim Pompole(100, 3)

        While myReader.Read()
            Pompole(i, 0) = myReader.GetValue(0).ToString()
            Pompole(i, 1) = myReader.GetValue(1).ToString()
            Pompole(i, 2) = myReader.GetValue(2).ToString()
            Pompole(i, 3) = myReader.GetValue(3).ToString()
            i += 1
        End While
        j = i
        Dim pozice(j, 1)
        ReDim Kroky(i, 3)
        For i = 0 To j
            Kroky(i, 0) = Pompole(i, 0)
            Kroky(i, 1) = Pompole(i, 1)
            Kroky(i, 2) = Pompole(i, 2)
            Kroky(i, 3) = Pompole(i, 3)
        Next

        querystring = "SELECT PROCPLN" & oznaceni & ".FIRSTJS FROM PART" & oznaceni & " INNER JOIN PROCPLN" & oznaceni & " ON PART" & oznaceni & ".PROCPLANID=PROCPLN" & oznaceni & ".PROCPLANID WHERE PARTID='" & vyrobek & "'"
        command = New OleDbCommand(querystring, connection)
        myReader = command.ExecuteReader()

        While myReader.Read()
            aktualnikrok = myReader.GetValue(0).ToString
        End While

        k = 0
        usek1 = 0
        usek2 = 0
        i = 0
        Do
            If Kroky(i, 0) = aktualnikrok Then
                aktualni_doba = Single.Parse(Kroky(i, 2), System.Globalization.NumberFormatInfo.InvariantInfo)
                aktualnikrok = Kroky(i, 1)
                soucet += aktualni_doba
                If Kroky(i, 3) = Zdroj Then
                    If k = 0 Then
                        pozice(k, 1) = soucet - aktualni_doba
                    Else
                        pozice(k, 1) = soucet
                    End If
                    pozice(k, 0) = i
                    k += 1
                End If
                i = -1
            End If
            i += 1
        Loop Until aktualnikrok = " "

        usek1 = pozice(0, 1)
        usek2 = pozice(k - 1, 1)


        connection.Close()
        myReader.Close()
        Spocitat_dobu_vyroby_vyrobku = soucet


    End Function

    Private Sub Vytvorit_objekty_zakazek()
        Dim i As Integer
        Dim objekt As New Zakazky_objekt
        Dim datum As Date
        Dim priorita As Integer

        Zakazky_tabulka.Columns.Add("vyroba", "Doba Vyroby [h]")
        Zakazky_tabulka.Columns.Add("termin", "Termín Vyroby [h]")
        PocetZakazek = Zakazky_tabulka.Rows.Count
        For i = 0 To Zakazky_tabulka.Rows.Count - 1
            Try
                datum = DateTime.ParseExact(Zakazky_tabulka.Rows(i).Cells(3).Value, "dd. M. yyyy HH:mm:ss", Nothing)
            Catch ex As Exception
                datum = DateTime.ParseExact(Zakazky_tabulka.Rows(i).Cells(3).Value, "dd.M.yyyy HH:mm:ss", Nothing)
            End Try

            objekt.id = i
            objekt.id_zakazky = Zakazky_tabulka.Rows(i).Cells(0).Value
            objekt.id_vyrobku = Zakazky_tabulka.Rows(i).Cells(1).Value
            objekt.index_vyrobku = GetIndex(Zakazky_tabulka.Rows(i).Cells(1).Value)
            objekt.termin = DateDiff(DateInterval.Minute, Zacatek_prace, datum) / 60
            Zakazky_tabulka.Rows(i).Cells(6).Value = objekt.termin
            objekt.vyroba = Spocitat_dobu_vyroby_vyrobku(Zakazky_tabulka.Rows(i).Cells(1).Value) * Zakazky_tabulka.Rows(i).Cells(2).Value
            objekt.termin_zacatku = usek1 * Zakazky_tabulka.Rows(i).Cells(2).Value
            objekt.termin_konce = usek2 * Zakazky_tabulka.Rows(i).Cells(2).Value
            Zakazky_tabulka.Rows(i).Cells(5).Value = objekt.vyroba
            priorita = Zakazky_tabulka.Rows(i).Cells(4).Value
            If priorita = 0 Then
                objekt.priorita = 1
            ElseIf priorita > 1 Then
                objekt.priorita = priorita * 3
            End If



            ListZakazek.Add(objekt)

        Next

    End Sub

    Private Sub miAbout_Click(sender As Object, e As EventArgs) Handles miAbout.Click
        About.Show()
    End Sub

    Private Sub miHelpZakazky_Click(sender As Object, e As EventArgs) Handles miHelpZakazky.Click
        Help_Zakazky.Show()
    End Sub

    Private Sub Optimalizace_button_Click(sender As Object, e As EventArgs) Handles Optimalizace_button.Click
        Zacatek_prace = Datum_zacatku.Value
        Vytvorit_objekty_zakazek()
        Optimalizace.Left = 150
        Optimalizace.Top = 20
        Optimalizace.Show()
    End Sub

    Private Sub Get_cela_pripona(vstup As String)
        Select Case vstup.Length
            Case 1
                oznaceni = "00" & vstup
            Case 2
                oznaceni = "0" & vstup
            Case 3
                oznaceni = vstup
        End Select
    End Sub
End Class