Imports System
Imports System.ComponentModel
Imports System.Text
Imports System.Windows.Forms
Imports System.Text.RegularExpressions

Namespace Fusion
Namespace Controls
      Public Class CurrencyTextBox
           Inherits TextBox

#Region " Variabili Private"
           Private DecimalSeparator As String = Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencyDecimalSeparator
           Private GroupSeparator As String = Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencyGroupSeparator
           Private Symbol As String = Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencySymbol
           Private KeyPressRegex As String = "^-?\$?\d*?(\" & DecimalSeparator & ")?(\d{2})?$"
           Private OnValidatingRegex As String = "^-?\$?\d*?(\" & DecimalSeparator & "\d{2})?$"
#End Region ' Variabili Private

#Region " Proprietà "
           Private m_Focused As Boolean = False
           Private m_Digits As Integer = -1
           <Category("Configurazione"), Description("Numero di cifre utilizzate per rappresentare gli interi (-1 = Nessun Limite)")> _
           Public Property Digits() As Integer
                Get
                    Return m_Digits
                End Get
                Set(ByVal value As Integer)
                    m_Digits = value
                    BuildRegStrings()
                End Set
           End Property
           Private m_Precision = Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencyDecimalDigits
           <Category("Configurazione"), Description("Numero di cifre utilizzate per rappresentare i decimali")> _
           Public Property Precision() As Integer
                Get
                    Return m_Precision
                End Get
                Set(ByVal value As Integer)
                    m_Precision = value
                    BuildRegStrings()
                End Set
           End Property
           <Browsable(False)> _
           Public ReadOnly Property Text_Formatting() As String
                Get
                    Return String.Format("{0:c}", Convert.ToDouble(Me.Text.Replace(Symbol, "").Replace(GroupSeparator, "").Replace(" ", "")))
                End Get
           End Property
           <Browsable(False)> _
           Public ReadOnly Property Text_Noformatting() As String
                Get
                    Return Me.Text.Replace(Symbol, "").Replace(GroupSeparator, "").Replace(" ", "")
                End Get
           End Property
           <Browsable(False)> _
           Public ReadOnly Property Text_AsDouble() As Double
                Get
                    Dim tempStr As String = Me.Text_Noformatting.Trim()
                    If tempStr.Length > 0 Then
                     Return Convert.ToDouble(Me.Text_Noformatting)
                    Else
                     Return 0
                    End If
                End Get
           End Property
           Private m_ErrorProvider As System.Windows.Forms.ErrorProvider
           <Category("Configurazione"), Description("ErrorProvider utilizzato per visualizzare i messaggi di errore."), Editor("System.Windows.Forms.Design.ErrorProvider, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")> _
           Public Property ErrorProvider() As System.Windows.Forms.ErrorProvider
                Get
                    Return m_ErrorProvider
                End Get
                Set(ByVal value As System.Windows.Forms.ErrorProvider)
                    m_ErrorProvider = value
                End Set
           End Property
#End Region ' Proprietà

#Region " Overrides "
           Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
                m_Focused = True
                Me.Text = Me.Text.Replace(Symbol, "").Replace(GroupSeparator, "").Trim().Replace(" ", "")
                MyBase.OnEnter(e)
           End Sub
           Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
                Select Case e.KeyChar
                    Case ChrW(Keys.Enter)
                    Case ChrW(Keys.Back)
                    Case ChrW(Keys.Clear)
                    Case Else
                     Dim tempStr As String = Me.Text
                     If Me.SelectionStart = Me.Text.Length Then
                          tempStr = String.Format("{0}{1}", Me.Text, e.KeyChar)
                     ElseIf Me.SelectionStart = 0 Then
                          tempStr = String.Format("{0}{1}", e.KeyChar, Me.Text)
                     Else
                          tempStr = String.Format("{0}{1}{2}", tempStr.Substring(0, Me.SelectionStart), e.KeyChar, tempStr.Substring(Me.SelectionStart, Me.Text.Length - Me.SelectionStart))
                     End If
                     If Not Regex.IsMatch(tempStr, KeyPressRegex) Then
                          e.Handled = True
                     End If
                End Select

                MyBase.OnKeyPress(e)
           End Sub
           Protected Overrides Sub OnValidating(ByVal e As System.ComponentModel.CancelEventArgs)
                Try
                    Dim tempStr As String = Me.Text.Replace(Symbol, "").Replace(GroupSeparator, "").Replace(" ", "")
                    If Not Regex.IsMatch(tempStr, OnValidatingRegex) Then
                     If Not Me.ErrorProvider Is Nothing Then
                          Me.ErrorProvider.SetError(Me, "Inserire solo valori numerici nel seguente formato: 999" & DecimalSeparator & "99")
                     End If
                     e.Cancel = True
                    Else
                     Me.Text = String.Format("{0:c}", Convert.ToDouble(tempStr))
                    End If
                Catch ex As Exception
                    If Not Me.ErrorProvider Is Nothing Then
                     Me.ErrorProvider.SetError(Me, "Inserire solo valori numerici nel seguente formato: 999" & DecimalSeparator & "99")
                    End If
                    e.Cancel = True
                Finally
                    MyBase.OnValidating(e)
                End Try
           End Sub
           Protected Overrides Sub OnValidated(ByVal e As System.EventArgs)
                If Not Me.ErrorProvider Is Nothing Then
                    Me.ErrorProvider.SetError(Me, "")
                End If
                Me.Text = String.Format("{0:c}", Convert.ToDouble(Me.Text.Replace(Symbol, "").Replace(GroupSeparator, "").Replace(" ", "")))
                MyBase.OnValidated(e)
                m_Focused = False
           End Sub
           Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
                If m_Focused = False Then
                    Dim tmpStr As String = Me.Text.Replace(Symbol, "").Replace(GroupSeparator, "").Replace(" ", "").Replace(" ", "")
                    If Not IsNumeric(tmpStr) Then
                     tmpStr = 0
                    End If
                    Me.Text = String.Format("{0:c}", Convert.ToDouble(tmpStr))
                End If

                MyBase.OnTextChanged(e)
           End Sub
           Public Function ValidateText() As Object
                Dim tempStr As String = Me.Text_Noformatting.Trim
                If tempStr.Length > 0 Then
                    Return Convert.ToDouble(Me.Text_Noformatting)
                Else
                    Return 0
                End If
           End Function
#End Region ' Overrides

#Region " Funzioni "
           Private Sub BuildRegStrings()
                Dim sb As New StringBuilder
                ' -------------
                ' KeyPressRegex
                ' -------------
                sb.Append("^-?\" & Symbol & "?\d")

                If m_Digits < 0 Then
                    sb.Append("*")
                Else
                    sb.Append("{" & GroupSeparator)
                    sb.Append(m_Digits.ToString)
                    sb.Append("}")
                End If

                sb.Append("?(\" & DecimalSeparator & ")?(\d{0,")
                sb.Append(m_Precision.ToString)
                sb.Append("})?$")

                KeyPressRegex = sb.ToString
                ' -------------


                ' -----------------
                ' OnValidatingRegex
                ' -----------------
                sb = New StringBuilder
                sb.Append("^-?\" & Symbol & "?\d")

                If m_Digits < 0 Then
                    sb.Append("*")
                Else
                    sb.Append("{0,")
                    sb.Append(m_Digits.ToString())
                    sb.Append("}")
                End If

                sb.Append("?(\" & DecimalSeparator & "\d{0,")
                sb.Append(m_Precision.ToString())
                sb.Append("})?$")

                OnValidatingRegex = sb.ToString()
                ' -----------------
           End Sub
#End Region ' Funzioni
      End Class
End Namespace
End Namespace