'
' Copyright (c) 2010 Apple Inc. All rights reserved.
'
' Licensed under the Apache License, Version 2.0 (the "License");
' you may not use this file except in compliance with the License.
' You may obtain a copy of the License at
' 
'     http://www.apache.org/licenses/LICENSE-2.0
' 
' Unless required by applicable law or agreed to in writing, software
' distributed under the License is distributed on an "AS IS" BASIS,
' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' See the License for the specific language governing permissions and
' limitations under the License.
'

Imports System.Net
Imports System.Net.Sockets
Imports System.Data
Imports System.Text

Public Class SimpleChat
    Public WithEvents MyEventManager As New Bonjour.DNSSDEventManager
    Private m_service As New Bonjour.DNSSDService
    Private m_registrar As Bonjour.DNSSDService
    Private m_browser As Bonjour.DNSSDService
    Private m_resolver As Bonjour.DNSSDService
    Private m_socket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
    Private m_port As Integer
    Private m_buffer(1024 * 32) As Byte
    Private m_async As IAsyncResult
    Public Delegate Sub SocketDelegate(ByVal msg As String)
    Private m_socketDelegate As SocketDelegate
    Private m_name As String

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        Button1.Enabled = False

        m_socketDelegate = New SocketDelegate(AddressOf MessageReceived)

        Dim endPoint As New IPEndPoint(IPAddress.Any, 0)
        m_socket.Bind(endPoint)
        endPoint = m_socket.LocalEndPoint
        m_port = endPoint.Port

        Dim txtRecord As Bonjour.TXTRecord
        m_async = m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial, New AsyncCallback(AddressOf OnReceive), Me)
        m_registrar = m_service.Register(0, 0, Environment.UserName, "_p2pchat._udp", vbNullString, vbNullString, m_port, txtRecord, MyEventManager)
    End Sub
    Public Sub MyEventManager_ServiceRegistered(ByVal registrar As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal name As String, ByVal regType As String, ByVal domain As String) Handles MyEventManager.ServiceRegistered
        m_name = name
        m_browser = m_service.Browse(0, 0, regType, vbNullString, MyEventManager)
    End Sub
    Public Sub MyEventManager_ServiceFound(ByVal browser As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal serviceName As String, ByVal regtype As String, ByVal domain As String) Handles MyEventManager.ServiceFound
        If (serviceName <> m_name) Then
            Dim peer As PeerData = New PeerData
            peer.InterfaceIndex = ifIndex
            peer.Name = serviceName
            peer.Type = regtype
            peer.Domain = domain
            ComboBox1.Items.Add(peer)
            ComboBox1.SelectedIndex = 0
        End If
    End Sub
    Public Sub MyEventManager_ServiceLost(ByVal browser As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal serviceName As String, ByVal regtype As String, ByVal domain As String) Handles MyEventManager.ServiceLost
        ComboBox1.Items.Remove(serviceName)
    End Sub
    Public Sub MyEventManager_ServiceResolved(ByVal resolver As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal fullname As String, ByVal hostname As String, ByVal port As UShort, ByVal record As Bonjour.TXTRecord) Handles MyEventManager.ServiceResolved
        m_resolver.Stop()
        Dim peer As PeerData = ComboBox1.SelectedItem
        peer.Port = port
        m_resolver = m_service.QueryRecord(0, ifIndex, hostname, Bonjour.DNSSDRRType.kDNSSDType_A, Bonjour.DNSSDRRClass.kDNSSDClass_IN, MyEventManager)
    End Sub
    Public Sub MyEventManager_QueryAnswered(ByVal resolver As Bonjour.DNSSDService, ByVal flags As Bonjour.DNSSDFlags, ByVal ifIndex As UInteger, ByVal fullName As String, ByVal rrtype As Bonjour.DNSSDRRType, ByVal rrclass As Bonjour.DNSSDRRClass, ByVal rdata As Object, ByVal ttl As UInteger) Handles MyEventManager.QueryRecordAnswered
        m_resolver.Stop()
        Dim peer As PeerData = ComboBox1.SelectedItem
        Dim bits As UInteger = BitConverter.ToUInt32(rdata, 0)
        Dim address As IPAddress = New System.Net.IPAddress(bits)
        peer.Address = address
    End Sub
    Public Sub MyEventManager_OperationFailed(ByVal registrar As Bonjour.DNSSDService, ByVal errorCode As Bonjour.DNSSDError) Handles MyEventManager.OperationFailed
        MessageBox.Show("Operation failed error code: " + errorCode)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim peer As PeerData = ComboBox1.SelectedItem
        Dim message As String = m_name + ": " + TextBox2.Text
        Dim bytes As Byte() = Encoding.UTF8.GetBytes(message)
        Dim endPoint As IPEndPoint = New IPEndPoint(peer.Address, peer.Port)
        m_socket.SendTo(bytes, 0, bytes.Length, 0, endPoint)
        TextBox1.AppendText(TextBox2.Text + Environment.NewLine)
        TextBox2.Text = ""
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        Dim peer As PeerData = ComboBox1.SelectedItem
        m_resolver = m_service.Resolve(0, peer.InterfaceIndex, peer.Name, peer.Type, peer.Domain, MyEventManager)
    End Sub
    Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
        Dim peer As PeerData = ComboBox1.SelectedItem
        If ((peer.Address IsNot Nothing) And TextBox2.Text.Length > 0) Then
            Button1.Enabled = True
        Else
            Button1.Enabled = False
        End If
    End Sub
    Public Sub MessageReceived(ByVal msg As System.String)
        TextBox1.AppendText(msg)
    End Sub
    Private Sub OnReceive(ByVal ar As IAsyncResult)
        Dim bytesReceived As Integer = m_socket.EndReceive(ar)
        If (bytesReceived > 0) Then
            Dim msg As String = Encoding.UTF8.GetString(m_buffer, 0, bytesReceived)
            Me.Invoke(m_socketDelegate, msg)
        End If
        m_async = m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial, New AsyncCallback(AddressOf OnReceive), Me)
    End Sub
End Class

Public Class PeerData
    Public InterfaceIndex As UInteger
    Public Name As String
    Public Type As String
    Public Domain As String
    Public Address As IPAddress
    Public Port As UShort

    Overrides Function ToString() As String
        Return Name
    End Function
End Class
