Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.IO
Imports System.IO.Ports
Imports System.Windows.Forms
Imports System.Data
Imports System.Text


Public Class SerialPort2

#Region "DeclarPubliq"
    
    Dim myPort As Array

    
    Delegate Sub SetTextCallback(ByVal [text] As String)


    Public Str1, strX, strY As String

    Public Posx0, Posx1, Posx2, Posx3, Posx4, Posx5, Posx6, Posx7, Posx8, Posx9, Posx10, Posx11, Posx12, Posx13 As String
    Public Posx14, Posx15, Posx16, Posx17, Posx18, Posx19, Posx20, Posx21, Posx22, Posx23, Posx24, Posx25, Posx26 As String
    Public Posx27, Posx28, Posx29, Posx30, Posx31, Posx32, Posx33, Posx34, Posx35, Posx36, Posx37, Posx38 As String
    Public Posx39, Posx40, Posx41, Posx42, Posx43, Posx44, Posx45, Posx46, Posx47, Posx48, Posx49 As String

    Public Posy0, Posy1, Posy2, Posy3, Posy4, Posy5, Posy6, Posy7, Posy8, Posy9, Posy10, Posy11, Posy12, Posy13 As String
    Public Posy14, Posy15, Posy16, Posy17, Posy18, Posy19, Posy20, Posy21, Posy22, Posy23, Posy24, Posy25, Posy26 As String
    Public Posy27, Posy28, Posy29, Posy30, Posy31, Posy32, Posy33, Posy34, Posy35, Posy36, Posy37, Posy38 As String
    Public Posy39, Posy40, Posy41, Posy42, Posy43, Posy44, Posy45, Posy46, Posy47, Posy48, Posy49 As String

#End Region ' DeclarPubliq

#Region "SERIALPORT_LOAD"
    Private Sub SerialPort2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


        
        myPort = IO.Ports.SerialPort.GetPortNames()

   
        cmbBaud.Items.Add(9600)
        cmbBaud.Items.Add(19200)
        cmbBaud.Items.Add(38400)
        cmbBaud.Items.Add(57600)
        cmbBaud.Items.Add(115200)
        cmbBaud.Items.Add(230400)
        cmbBaud.Items.Add(460800)
        cmbBaud.Items.Add(921600)


        For i = 0 To UBound(myPort)     

            cmbPort.Items.Add(myPort(i))

        Next

       
        cmbPort.Text = cmbPort.Items.Item(0)

        
        cmbBaud.Text = cmbBaud.Items.Item(1)

        
        btnDisconnect.Enabled = False


    End Sub

#End Region ' PORT_LOAD_DEF_COM

#Region "Button_Cnxn_Disc"
    Public Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click

        
        SerialPort1.PortName = cmbPort.Text

        
        SerialPort1.BaudRate = cmbBaud.Text

       
        SerialPort1.Parity = IO.Ports.Parity.None

     
        SerialPort1.StopBits = IO.Ports.StopBits.One

     
        SerialPort1.DataBits = 8

        
        SerialPort1.Open()

       
        btnConnect.Enabled = False

      
        btnDisconnect.Enabled = True

     
        Rtb_ONOFF.BackColor = System.Drawing.Color.LimeGreen
        Rtb_ONOFF.Text = " ON"

    End Sub

    Public Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click

       
        SerialPort1.DiscardInBuffer()
        SerialPort1.Close()

  
        btnConnect.Enabled = True
        btnDisconnect.Enabled = False


        Rtb_ONOFF.BackColor = System.Drawing.Color.Red
        Rtb_ONOFF.Text = " OFF"

    End Sub

#End Region 'Cnxn_Disc_SERIALPORT

#Region "DefinitionCoord&DefTimer"

    Public Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click


        ' Positions (49 / x et y) 
        'X VALUES
        'AND Y VALUES ARE DEFINED HERE, STHG LIKE Posx0="-10" etc...


        '  dPOSITIONS Array:
        Dim PosArray(,) As String =
            {{Posx0, Posy0}, {Posx1, Posy1}, {Posx2, Posy2}, {Posx3, Posy3}, {Posx4, Posy4}, {Posx5, Posy5}, {Posx6, Posy6}, {Posx7, Posy7}, {Posx8, Posy8}, {Posx9, Posy9},
            {Posx10, Posy10}, {Posx11, Posy11}, {Posx12, Posy12}, {Posx13, Posy13}, {Posx14, Posy14}, {Posx15, Posy15}, {Posx16, Posy16},
            {Posx17, Posy17}, {Posx18, Posy18}, {Posx19, Posy19}, {Posx20, Posy20}, {Posx21, Posy21}, {Posx22, Posy22}, {Posx23, Posy23}, {Posx24, Posy24},
            {Posx25, Posy25}, {Posx26, Posy26}, {Posx27, Posy27}, {Posx28, Posy28}, {Posx29, Posy29}, {Posx30, Posy30}, {Posx31, Posy31}, {Posx32, Posy32},
            {Posx33, Posy33}, {Posx34, Posy34}, {Posx35, Posy35}, {Posx36, Posy36}, {Posx37, Posy37}, {Posx38, Posy38}, {Posx39, Posy39}, {Posx40, Posy40},
            {Posx41, Posy41}, {Posx42, Posy42}, {Posx43, Posy43}, {Posx44, Posy44}, {Posx45, Posy45}, {Posx46, Posy46}, {Posx47, Posy47}, {Posx48, Posy48}, {Posx49, Posy49}}


        ' DataTable in DataSet:
        Dim row As DataRow
        Dim i As Integer

        ' TOTAL COORDINATES LOOP
        For i = 1 To 49

            ' Fill in DataTable:
            row = dTable1.NewRow()
            row("dTKey") = i
            row("dTColPosX") = PosArray(i, 0)
            row("dTColPosY") = PosArray(i, 1)

            dTable1.Rows.Add(row)

        Next i

        ' DataGridView to display the table:
        DataGridView1.DataSource = dTable1

        DataGridView1.Columns(0).DataPropertyName = dTable1.Columns(0).ColumnName
        DataGridView1.Columns(1).DataPropertyName = dTable1.Columns(1).ColumnName
        DataGridView1.Columns(2).DataPropertyName = dTable1.Columns(2).ColumnName


        For Each row_ As DataRow In dTable1.Rows

            

            strX = row_("dTColPosX")
            strY = row_("dTColPosY")

			' SUB -> SEND TO CONTROLLER
            SendCoords(strX, strY)

            'TESTING PAUSES/BLINKS:
            Timer1.Interval = 17000
            Timer2.Interval = 800
            Timer1.Enabled = True
            Timer2.Enabled = True

        
            ' Blinking message (FORM2):
            Form2.Opacity = 0.65
            Form2.Text = String.Empty
            Form2.Lbl_Wait.ForeColor = Color.DarkRed
            Form2.ControlBox = False
            Form2.Activate()
            Form2.ShowDialog()
          

        Next row_

    End Sub


#End Region 'DefCoord_&Timer

#Region "EnvoiCoordonneesPlatine"

    Public Sub SendCoords(ByVal PosX As String, ByVal PosY As String)

        Dim line_1, line_2, line_3, line_4, line_5, line_6, line_7 As String
        Dim TotStringMess As String

		'COMMANDS TO THE CONTROLLER
        ' STRING APPEND / TOTAL MESSAGE
        line_1 = "1TP?;2TP?;WT500;"
        line_2 = "1PA"
        'line_3 = "WT500;"
        line_4 = "2PA"
        line_5 = "1WS;2WS;WT500;"
        line_6 = "1TP?;2TP?;"
        line_7 = "1MD?;2MD?;WT3000;"


        'Concat with coords:
        line_2 = line_2 & PosX & ";"
        line_4 = line_4 & PosY & ";"

        'Concat:
        TotStringMess = line_1 & line_2 & line_4 & line_5 & line_6 & line_7
     
        txtTransmit.Text = TotStringMess 

        'MAYBE WE SHOULD TRY WRITELINE AND READLINE:
		
        SerialPort1.Write(TotStringMess & vbCr)

        'WHEN DATA is written to the outbuffer and sent, it triggers DATA RECEIVED EVENT ====> SerialPort1_DataReceived

        'coordinates string back to empty:
        line_2 = ""
        line_4 = ""


    End Sub

#End Region 'EnvoiCoordonneesPlatine


#Region "DATA_RECEIVED_SERIALPORT"

    Public Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

    
        ' PROBABLY THE CULPRIT AS IT READS BOTH STREAM (remaining data ?) AND THE OUTBUFFER !?!?
        ReceivedText(SerialPort1.ReadExisting())

    End Sub

    Public Sub ReceivedText(ByVal [text] As String)
        
        If Me.rtbReceived.InvokeRequired Then

            Dim x As New SetTextCallback(AddressOf ReceivedText)

            Me.Invoke(x, New Object() {(text)})

        Else

            ' Displays returning DATA 
            Me.rtbReceived.Text &= [text]
            

            Str1 = rtbReceived.Text
            TextBox_LengthOUT.Text = Str1.Length

            Dim idx As Integer
            Dim idx_Str As String
            idx = CInt(Rtb_Steps.Text) + 1
            idx_Str = idx.ToString

            If Str1.Substring(Str1.Length - 2, 1) = "1" Then

				' ---------------------------------------------------------------------------------
                
				' From here on, the axis movement is over and the backgroundworker tasks begins
                
				' ---------------------------------------------------------------------------------
				
				BackgroundWorker1.WorkerReportsProgress = True
                BackgroundWorker1.WorkerSupportsCancellation = True

                'BCKGDWORKER starts:
                BackgroundWorker1.RunWorkerAsync()

                'blocking modal form displaying position and "NEXT" button to get to the N+1 POSITION:
                Form_Aqui.rtb_InfoAcqui.Text = " Mouvement n°: " & idx_Str & " terminé !" & vbCrLf & vbCrLf & Chr(9) & Chr(9) & Chr(9) & "Position: (" & strX & " ; " & strY & ")" & " atteinte." & vbCrLf & vbCrLf & " La partie Acquisition a débutée. Veuillez attendre le passage de l'indicateur ""Acquisition"" à la couleur VERTE et 100%, pour passer à l'étape suivante."

                ' +1 step indicator:
                UpdtStep()

                Form_Aqui.Activate()
                Form_Aqui.btn_next3.Enabled = False

                Form_Aqui.ShowDialog()

            Else

				' Char 1 did not figure at the end of the returning string = movement in progress -> error
				' For the moment no alternative to start again
               Msgbox("Error, movement not over yet",MsgBoxStyle.OkOnly, "Movement Error")


            End If


            'Cancel background task when user leaves Modal Form (clicks "Next"):
            BackgroundWorker1.CancelAsync()

            ' indicators:
            Timer3.Enabled = False
            RichTextBox1.BackColor = Color.Red
            Label2.Text = "0% ..."

           

        End If

    End Sub


#End Region 'DATA_RECEIVED_SERIALPORT

#Region "RemiseAZero"

    Private Sub btn_RAZ_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_RAZ.Click

        Dim Sline_1, Sline_2, Sline_3, Sline_4, StringRAZ As String

		' Commands to get both axis back to ZERO
        Sline_1 = "1PA0;"
        Sline_2 = "2PA0;"
        Sline_3 = "1WS;2WS;WT500;"
        Sline_4 = "1TP?;2TP?;"

        'Concat:
        StringRAZ = Sline_1 & Sline_2 & Sline_3 & Sline_4

        SerialPort1.Write(StringRAZ & vbCr)

        'Update:
        Rtb_Steps.Text = "0"
        Rtb_Steps.BackColor = Color.Gold

    End Sub

#End Region 'RemiseAZero


#Region "IncrémentEtape"
    Public Sub UpdtStep()

        Dim indx_step As Integer
        indx_step = CInt(Rtb_Steps.Text)

        indx_step = indx_step + 1
        Rtb_Steps.Text = indx_step

        If indx_step = 49 Then

            Rtb_Steps.BackColor = Color.LimeGreen

        End If


    End Sub


    Private Sub btnPlus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlus.Click

        UpdtStep()

    End Sub

#End Region 'IncrémentEtape



    ' ////////////////////////////////  BACKGROUNDWORKER  //////////////////////////////////////
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

		' For the moment this was a simple way (wrong obv.) to delay the BCKGND task from firing too early compared to the end of the axis movement...
        Threading.Thread.Sleep(4000)

		'THE NEXT LINES SIMULATES A TIME CONSUMING TASK (in reality it is the image acquisition and processing)
        Const Max As Integer = 100

        For i = 1 To Max
          
            'I put a sleep to simulate time consumed
            Threading.Thread.Sleep(100)

            ' report progress at regular intervals
            BackgroundWorker1.ReportProgress(CInt(100 * i / Max), "En cours..." & i.ToString)

            ' check at regular intervals for CancellationPending
            If BackgroundWorker1.CancellationPending Then
                BackgroundWorker1.ReportProgress(CInt(100 * i / Max), "Annulation...")
                Exit For
            End If

        Next

       

        If BackgroundWorker1.CancellationPending Then
            e.Cancel = True
            BackgroundWorker1.ReportProgress(100, "Annulé.")

        End If


    End Sub


    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

        '' This event is fired when you call the ReportProgress method from inside the DoWork sub.
        '' Any visual indicators about the progress should go here:
        Label1.Text = CType(e.UserState, String)
        Label2.Text = e.ProgressPercentage.ToString & "% achevés."

        'Updates progress bar:
        Me.ProgressBar1.Value = e.ProgressPercentage

        Lbl_AcquiProgress.Text = " Acquisition en cours ... "
        Timer3.Enabled = True

    End Sub

	
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

        If e.Error IsNot Nothing Then

            ' If BackgroundWorker terminated due to an error:
            MessageBox.Show(e.Error.Message)
            Label1.Text = "Erreur !"
            Timer3.Enabled = False
            Lbl_AcquiProgress.Visible = False
            RichTextBox1.BackColor = Color.DarkRed

        ElseIf e.Cancelled Then

            ' Otherwise if it was cancelled:
            Label1.Text = "Acquisition interrompue !"
            Timer3.Enabled = False
            Lbl_AcquiProgress.Visible = False
            Form_Aqui.btn_next3.Enabled = True
            RichTextBox1.BackColor = Color.DarkRed

        Else

            ' Otherwise it completed normally:
            Label1.Text = "Acquisition finie !"
            Timer3.Enabled = False
            Lbl_AcquiProgress.Visible = False


            Form_Aqui.btn_next3.Enabled = True
            RichTextBox1.BackColor = Color.LimeGreen


        End If

    End Sub

    '////////////////////////////////  END OF BCKGRNDWK PART /////////////////////////////////////////

	
#Region "ActionTimer"
    
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Form2.Close()
		
		Me.Activate()
        Me.Opacity = 1


    End Sub


    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
		
		'blinking text in blocking modal form
        Form2.Lbl_Wait.Visible = Not Form2.Lbl_Wait.Visible

    End Sub


    Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer3.Tick

		' blinking "in progress text
        Lbl_AcquiProgress.Visible = Not Lbl_AcquiProgress.Visible

    End Sub



#End Region 'ActionTimer


#Region "ControlCmbox"

    Private Sub cmbPort_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbPort.SelectedIndexChanged

        If SerialPort1.IsOpen = False Then

            SerialPort1.PortName = cmbPort.Text

          
        Else
            MsgBox("Action impossible tant que le port COM est ouvert", vbCritical)

        End If

    End Sub



    Private Sub cmbBaud_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbBaud.SelectedIndexChanged

        If SerialPort1.IsOpen = False Then

            SerialPort1.BaudRate = cmbBaud.Text

            
        Else

            MsgBox("Action impossible tant que le port COM est ouvert", vbCritical)

        End If

    End Sub

#End Region 'ControlCmbox

#Region "FileSave"

    Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click

        SaveFileDialog1.Filter = "Text Files (*.txt)|*.txt"
        SaveFileDialog1.ShowDialog()

        If SaveFileDialog1.FileName <> "" Then

            FileOpen(1, SaveFileDialog1.FileName, OpenMode.Output)
            PrintLine(1, Me.rtbReceived.Text)
            FileClose(1)

        End If


    End Sub

#End Region 'FileSave


#Region "QUIT"
    Private Sub btnQUIT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnQUIT.Click

        'Fonction pour pouvoir quitter l'application
        Dim QuitFormResult1 As System.Windows.Forms.DialogResult

        QuitFormResult1 = MsgBox("Êtes-vous certain de vouloir quitter ?", MsgBoxStyle.YesNo)
        If QuitFormResult1 = MsgBoxResult.Yes Then

            'Ferme le formulaire en cours si le bouton "Yes" est cliqué:
            Me.Close()

        End If


    End Sub

#End Region 'QUIT
    
End Class
