Imports System.ComponentModel
Imports System.IO
Imports System.Net.Sockets
Imports ComponentPro.Net

Namespace ProxySample
	Partial Public Class Sample
		Inherits Form
		Private ReadOnly _settings As SettingInfo

		Public Sub New()
			InitializeComponent()

			' Set timeout values to 15s.
			proxyClient.Timeout = 15000

			' Load settings from the Registry.
			_settings = SettingInfo.LoadConfig()

			' Get proxy settings.
			txtProxyHost.Text = _settings.ProxyServer
			txtProxyPort.Text = _settings.ProxyPort.ToString()
			cbxType.SelectedIndex = CInt(Fix(_settings.ProxyType))
			txtUserName.Text = _settings.ProxyUser
			txtPassword.Text = _settings.ProxyPassword
			txtDomain.Text = _settings.ProxyDomain
			cbxMethod.SelectedIndex = CInt(Fix(_settings.ProxyMethod))

			' Get destination host address.
			txtHost.Text = _settings.Host
			txtPort.Text = _settings.Port.ToString()

#If Not Framework4_5 Then
			AddHandler Me.proxyClient.ConnectCompleted, AddressOf proxyClient_ConnectCompleted
#End If
		End Sub

		''' <summary>
		''' Handles the form's Closed event.
		''' </summary>
		''' <param name="e">The event arguments.</param>
		Protected Overrides Sub OnClosed(ByVal e As EventArgs)
			MyBase.OnClosed(e)

			' Update settings.
			_settings.ProxyServer = txtProxyHost.Text
			Try
				_settings.ProxyPort = Integer.Parse(txtProxyPort.Text)
			Catch
				_settings.ProxyPort = 1080
			End Try
			_settings.ProxyType = CType(cbxType.SelectedIndex, ProxyType)
			_settings.ProxyUser = txtUserName.Text
			_settings.ProxyPassword = txtPassword.Text
			_settings.ProxyDomain = txtDomain.Text
			_settings.ProxyMethod = CType(cbxMethod.SelectedIndex, ProxyHttpConnectAuthMethod)

			' Host info.
			_settings.Host = txtHost.Text
			Try
				_settings.Port = Integer.Parse(txtPort.Text)
			Catch
				_settings.Port = 80
			End Try

			' And save to the Registry.
			_settings.SaveConfig()
		End Sub

		''' <summary>
		''' Enables/disables controls.
		''' </summary>
		''' <param name="enable">Indicates whether to enable or disable the dialog.</param>
		Private Sub EnableDialog(ByVal enable As Boolean)
			btnGet.Enabled = enable
			grbSettings.Enabled = enable
			grbHost.Enabled = enable
			Util.EnableCloseButton(Me, enable)
		End Sub

		''' <summary>
		''' Handles the Get button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
#If Framework4_5 Then
		Private privateasync Sub btnGet_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnGet.Click
#Else
		Private Sub btnGet_Click(ByVal sender As Object, ByVal e As EventArgs)
#End If
			If txtHost.Text.Length = 0 Then
				MessageBox.Show("Host Name is required", "Error")
				Return
			End If
			Dim port As Integer

			Try
				' Parse the port number.
				port = Integer.Parse(txtPort.Text)
			Catch exc As Exception
				MessageBox.Show("Invalid port number: " & exc.Message, "Error")
				Return
			End Try

			Dim proxyPort As Integer = 0
			If txtProxyPort.Text.Length > 0 Then
				Try
					' Parse the proxy port number.
					proxyPort = Integer.Parse(txtProxyPort.Text)
				Catch exc As Exception
					MessageBox.Show("Invalid proxy port number: " & exc.Message, "Error")
					Return
				End Try
			End If

			' Disable dialog.
			EnableDialog(False)

			proxyClient.ProxyHost = txtProxyHost.Text
			proxyClient.ProxyPort = proxyPort
			proxyClient.ProxyType = CType(cbxType.SelectedIndex, ProxyType)
			proxyClient.UserName = txtUserName.Text
			proxyClient.Password = txtPassword.Text
			proxyClient.Domain = txtDomain.Text
			proxyClient.AuthenticationMethod = CType(cbxMethod.SelectedIndex, ProxyHttpConnectAuthMethod)

			txtContent.Text = "Downloading..."

#If Framework4_5 Then
			Try
				' Asynchronously connect to the specified host.
				await proxyClient.ConnectAsync(txtHost.Text, port)
				ShowResult()
			Catch ex As Exception
				Util.ShowError(ex)
				txtContent.Text = String.Empty
			End Try

			' Close the connection.
			proxyClient.Disconnect()

			' Enable dialog.
			EnableDialog(True)
#Else
			' Asynchronously connect to the specified host.
			proxyClient.ConnectAsync(txtHost.Text, port)
#End If
		End Sub

		Private Sub ShowResult()
			Try
				' Connected?
				If proxyClient.Connected Then
					' Construct a request message sending to the destination host.
					Dim requestMessage As String = "GET / HTTP/1.1" & vbCrLf & "Host: " & txtHost.Text & vbCrLf & "Connection: close" & vbCrLf & vbCrLf

					' Send the request message.
					Dim nsr As NetworkStream = proxyClient.GetStream()
					Dim streamWriter As New StreamWriter(nsr)
					streamWriter.Write(requestMessage)
					streamWriter.Flush()

					' And read the response.
					Dim streamReader As New StreamReader(nsr)
					txtContent.Text = streamReader.ReadToEnd()
				End If
			Catch ex As Exception
				Util.ShowError(ex)
				txtContent.Text = String.Empty
			End Try
		End Sub

#If Not Framework4_5 Then
		''' <summary>
		''' Handles the proxy client's ConnectCompleted event.
		''' </summary>
		''' <param name="sender">The proxy client object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub proxyClient_ConnectCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
			If e.Error IsNot Nothing Then
				Util.ShowError(e.Error)
				txtContent.Text = String.Empty
			Else
				ShowResult()
			End If

			' Close the connection.
			proxyClient.Disconnect()

			' Enable dialog.
			EnableDialog(True)
		End Sub
#End If

		''' <summary>
		''' Handles the combo box proxy type's SelectedIndexChanged event.
		''' </summary>
		''' <param name="sender">The combo box.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub cbx_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cbxMethod.SelectedIndexChanged, cbxType.SelectedIndexChanged
			Dim enable As Boolean = cbxType.SelectedIndex > 0

			cbxMethod.Enabled = cbxType.SelectedIndex = CInt(Fix(ProxyType.HttpConnect)) ' Authentication method is available for HTTP Connect only.
			txtDomain.Enabled = cbxMethod.Enabled AndAlso cbxMethod.SelectedIndex = CInt(Fix(ProxyHttpConnectAuthMethod.Ntlm)) ' Domain is available for NTLM authentication method only.
			txtUserName.Enabled = enable ' User name and password are ignored with SendToProxy proxy type. -  && cbxType.SelectedIndex != (int)ProxyType.SendToProxy
			txtPassword.Enabled = enable ' && cbxType.SelectedIndex != (int)ProxyType.SendToProxy
			txtProxyHost.Enabled = enable ' Proxy host and port are not available in NoProxy type.
			txtProxyPort.Enabled = enable
		End Sub
	End Class
End Namespace