using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
using System.Text.RegularExpressions;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.UserDefined,
IsByteOrdered = true,
IsFixedLength = false,
MaxByteSize = 11)]
public struct PhoneNumber : INullable, IBinarySerialize
{
    public override string ToString()
    {
        return this.number;
    }

    public bool IsNull
    {
        get
        {
            if (this.number == "")
                return true;
            else
                return false;
        }
    }

    public static PhoneNumber Null
    {
        get
        {
            PhoneNumber h = new PhoneNumber();
            h.number = "";
            return h;
        }
    }

    public static PhoneNumber Parse(SqlString s)
    {
        if (s.IsNull)
            return Null;
        PhoneNumber u = new PhoneNumber();

        // wywołanie właściwości Number i przypisanie wartości
        u.Number = s;
        return u;
    }

    // publiczny mutator dla numeru
    public SqlString Number
    {
        get
        {
            return new SqlString(this.number);
        }
        set
        {
            // jeśli null - koniec przetwarzania
            if (value == "")
            {
                this.number = "";
                return;
            }

            // dopasowanie do grup 1 lub więcej cyfr
            Regex regex = new Regex("[0-9]*");
            MatchCollection matches = regex.Matches((string)value);

            StringBuilder result = new StringBuilder();

            foreach (Match match in matches)
            {
                result.Append(match.Value);
            }

            if (result.Length == 10)
                this.number = result.ToString();
            else
                throw new ArgumentException("Numer telefonu musi się składać z 10 cyfr.");
        }
    }

    // numer telefonu
    private string number;

    #region IBinarySerialize Members

    public void Read(System.IO.BinaryReader r)
    {
        this.number = r.ReadString();
    }

    public void Write(System.IO.BinaryWriter w)
    {
        w.Write(number);
    }

    #endregion
}