context: /* --------------------------------------------------------------------------
   * Copyrights
   *
   * Portions created by or assigned to Cursive Systems, Inc. are
   * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
   * information for Cursive Systems, Inc. is available at
   * http://www.cursive.net/.
   *
   * License
   *
   * Jabber-Net is licensed under the LGPL.
   * See LICENSE.txt for details.
   * --------------------------------------------------------------------------*/
  using System;
  
  using System.Diagnostics;
  
  using System.Xml;
  
  using bedrock.util;
  
  // http://www.xmpp.org/extensions/xep-0054.html
  
  namespace jabber.protocol.iq
  {
      /// <summary>
      /// Type of telephone number.
      /// </summary>
      public enum TelephoneType
      {
          /// <summary>
          /// None specified
          /// </summary>
          unknown = -1,
          /// <summary>
          /// voice
          /// </summary>
          voice,
          /// <summary>
          /// fax
          /// </summary>
          fax,
          /// <summary>
          /// pager
          /// </summary>
          pager,
          /// <summary>
          /// voice mail
          /// </summary>
          msg,
          /// <summary>
          /// mobile
          /// </summary>
          cell,
          /// <summary>
          /// video phone
          /// </summary>
          video,
          /// <summary>
          /// Bulletin Board System
          /// </summary>
          bbs,
          /// <summary>
          /// Modem
          /// </summary>
          modem,
          /// <summary>
          /// ISDN
          /// </summary>
          isdn,
          /// <summary>
          /// dunno.
          /// </summary>
          pcs
      };
  
      /// <summary>
      /// Telephone location
      /// </summary>
      public enum TelephoneLocation
      {
          /// <summary>
          /// Home
          /// </summary>
          home,
          /// <summary>
          /// Work
          /// </summary>
          work,
          /// <summary>
          /// Unknown
          /// </summary>
          unknown
      }
  
      /// <summary>
      /// Address location
      /// </summary>
      public enum AddressLocation
      {
          /// <summary>
          /// Home
          /// </summary>
          home,
          /// <summary>
          /// Work
          /// </summary>
          work,
          /// <summary>
          /// Unknown
          /// </summary>
          unknown
      }
  
      /// <summary>
      /// Email type attribute
      /// </summary>
      public enum EmailType
      {
          /// <summary>
          /// None specified
          /// </summary>
          NONE = -1,
          /// <summary>
          /// Home
          /// </summary>
          home,
          /// <summary>
          /// Work
          /// </summary>
          work,
          /// <summary>
          /// Internet
          /// </summary>
          internet,
          /// <summary>
          /// x400
          /// </summary>
          x400
      }
  
      /// <summary>
      /// IQ packet with a version query element inside.
      /// </summary>
      [SVN(@"$Id$")]
      public class VCardIQ : jabber.protocol.client.TypedIQ<VCard>
      {
          /// <summary>
          /// Create a vCard IQ
          /// </summary>
          /// <param name="doc"></param>
          public VCardIQ(XmlDocument doc) : base(doc)
          {
          }
  
          /// <summary>
          /// returns the vCard element for this iq.
          /// </summary>
          public VCard VCard
          {
              get { return Instruction; }
          }
      }
  
      /// <summary>
      /// A vCard element.
      /// </summary>
      [SVN(@"$Id$")]
      public class VCard : Element
      {
          /// <summary>
          ///
          /// </summary>
          /// <param name="doc"></param>
          public VCard(XmlDocument doc) : base("vCard", URI.VCARD, doc)
          {
          //  SetElem("PRODID", "jabber-net: " + this.GetType().Assembly.FullName);
          }
  
          /// <summary>
          ///
          /// </summary>
          /// <param name="prefix"></param>
          /// <param name="qname"></param>
          /// <param name="doc"></param>
          public VCard(string prefix, XmlQualifiedName qname, XmlDocument doc) :
              base(prefix, qname, doc)
          {
          }
  
          /// <summary>
          /// Full name of the individual, as a single string
          /// </summary>
          public string FullName
          {
              get { return GetElem("FN"); }
              set { SetElem("FN", value); }
          }
  
          /// <summary>
          /// Pieces of the name, split apart
          /// </summary>
          public VName ComplexName
          {
              get { return this["N"] as VName; }
              set { ReplaceChild(value); }
          }
  
          /// <summary>
          /// Person's nick name.  This might be a good choice for a default roster nick,
          /// for instance.
          /// </summary>
          public string Nickname
          {
              get { return GetElem("NICKNAME"); }
              set { SetElem("NICKNAME", value); }
          }
  
          /// <summary>
          /// User's photograph
          /// </summary>
          public VPhoto Photo
          {
              get { return this["PHOTO"] as VPhoto; }
              set { ReplaceChild(value); }
          }
  
          /// <summary>
          /// Date of birth
          /// </summary>
          public DateTime Birthday
          {
              get { return DateTime.Parse(GetElem("BDAY")); }
              set { SetElem("BDAY", string.Format("yyyy-MM-dd", value)); }
          }
  
          /// <summary>
          /// Associated URL
          /// </summary>
          public System.Uri Url
          {
              get
              {
                  string url = GetElem("URL");
                  if ((url == null) || (url == ""))
                      return null;
                  try
                  {
                      Uri uri = new Uri(url);
                      return uri;
                  }
                  catch (UriFormatException)
                  {
                      return null;
                  }
              }
              set { SetElem("URL", value.ToString()); }
          }
  
          /// <summary>
          ///
          /// </summary>
          public VOrganization Organization
          {
              get { return this["ORG"] as VOrganization; }
              set { this.ReplaceChild(value); }
          }
  
          /// <summary>
          ///
          /// </summary>
          public string Title
          {
              get { return GetElem("TITLE"); }
              set { SetElem("TITLE", value); }
          }
  
          /// <summary>
          ///
          /// </summary>
          public string Role
          {
              get { return GetElem("ROLE"); }
              set { SetElem("ROLE", value); }
          }
  
          /// <summary>
          /// Jabber ID
          /// </summary>
          public JID JabberId
          {
              get { return GetElem("JABBERID"); }
              set { SetElem("JABBERID", value); }
          }
  
          /// <summary>
          ///
          /// </summary>
          public string Description
          {
              get { return GetElem("DESC"); }
              set { SetElem("DESC", value); }
          }
  
          /// <summary>
          /// List of telephone numbers
          /// </summary>
          /// <returns></returns>
          public VTelephone[] GetTelephoneList()
          {
              XmlNodeList nl = GetElementsByTagName("TEL", URI.VCARD);
              VTelephone[] numbers = new VTelephone[nl.Count];
              int i=0;
              foreach (XmlNode n in nl)
              {
                  numbers[i] = (VTelephone) n;
                  i++;
              }
              return numbers;
          }
  
          /// <summary>
          ///
          /// </summary>
          /// <param name="type"></param>
          /// <param name="location"></param>
          /// <returns></returns>
          public VTelephone GetTelephone(TelephoneType type, TelephoneLocation location)
          {
              foreach (VTelephone tel in GetTelephoneList())
              {
                  if ((tel.Location == location) && (tel.Type == type))
                      return tel;
              }
              return null;
          }
  
          /// <summary>
          /// List of addresses
          /// </summary>
          /// <returns></returns>
          public VAddress[] GetAddressList()
          {
              XmlNodeList nl = GetElementsByTagName("ADR", URI.VCARD);
              VAddress[] addresses = new VAddress[nl.Count];
              int i=0;
              foreach (XmlNode n in nl)
              {
                  addresses[i] = (VAddress) n;
                  i++;
              }
              return addresses;
          }
  
          /// <summary>
          /// Get the address for the given location.
          /// </summary>
          /// <param name="location"></param>
          /// <returns></returns>
          public VAddress GetAddress(AddressLocation location)
          {
              foreach (VAddress adr in GetAddressList())
              {
                  if (adr.Location == location)
                      return adr;
              }
              return null;
          }
  
          /// <summary>
          /// List of Email addresses
          /// </summary>
          /// <returns></returns>
          public VEmail[] GetEmailList()
          {
              XmlNodeList nl = GetElementsByTagName("EMAIL", URI.VCARD);
              VEmail[] emails = new VEmail[nl.Count];
              int i=0;
              foreach (XmlNode n in nl)
              {
                  emails[i] = (VEmail)n;
                  i++;
              }
              return emails;
          }
  
          /// <summary>
          /// Get the email address for the given type.
          /// </summary>
          /// <param name="type"></param>
          /// <returns></returns>
          public VEmail GetEmail(EmailType type)
          {
              foreach (VEmail email in GetEmailList())
              {
                  if (email.Type == type)
                      return email;
              }
              return null;
          }
  
          /// <summary>
          ///  Sets the email address for the given type.
          /// </summary>
          /// <param name="email"></param>
          public void SetEmail(VEmail email)
          {
  
gt:             VEmail existing = GetEmail(email.Type);