/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (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.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.util;

import java.io.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;

public class VCardAddress
{
  /*--------------------------------------------------------------------------------
   * Predicate class to use for searches
   *--------------------------------------------------------------------------------
   */

  static abstract class Predicate
  {
    public abstract boolean test(VCardAddress addr);

  } // end class Predicate

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private boolean home_adr;
  private boolean work_adr;
  private boolean postal_adr;
  private boolean parcel_adr;
  private boolean domestic_adr;
  private boolean intl_adr;
  private boolean preferred;
  private String pobox;
  private String ext_address;
  private String street;
  private String locality;
  private String region;
  private String postal_code;
  private String country;

  /*--------------------------------------------------------------------------------
   * Constructors
   *--------------------------------------------------------------------------------
   */

  VCardAddress(boolean home_adr, boolean work_adr, boolean postal_adr, boolean parcel_adr, boolean domestic_adr,
	       boolean intl_adr, boolean preferred, String pobox, String ext_address, String street, String locality,
	       String region, String postal_code, String country)
  {
    this.home_adr = home_adr;
    this.work_adr = work_adr;
    this.postal_adr = postal_adr;
    this.parcel_adr = parcel_adr;
    this.domestic_adr = domestic_adr;
    this.intl_adr = intl_adr;
    this.preferred = preferred;
    this.pobox = pobox;
    this.ext_address = ext_address;
    this.street = street;
    this.locality = locality;
    this.region = region;
    this.postal_code = postal_code;
    this.country = country;

  } // end constructor

  VCardAddress(Element adr) throws ValidationException
  {
    DOMElementHelper h = new DOMElementHelper(adr);
    home_adr = h.hasChildElement("HOME");
    work_adr = h.hasChildElement("WORK");
    postal_adr = h.hasChildElement("POSTAL");
    parcel_adr = h.hasChildElement("PARCEL");
    domestic_adr = h.hasChildElement("DOM");
    intl_adr = h.hasChildElement("INTL");
    if (domestic_adr && intl_adr)
      throw new ValidationException("same address can't be both DOM and INTL");
    preferred = h.hasChildElement("PREF");
    pobox = VCard.cleanup(h.getSubElementText("POBOX"));
    ext_address = VCard.cleanup(h.getSubElementText("EXTADR"));
    street = VCard.cleanup(h.getSubElementText("STREET"));
    locality = VCard.cleanup(h.getSubElementText("LOCALITY"));
    region = VCard.cleanup(h.getSubElementText("REGION"));
    postal_code = VCard.cleanup(h.getSubElementText("PCODE"));
    country = VCard.cleanup(h.getSubElementText("CTRY"));

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal operations
   *--------------------------------------------------------------------------------
   */

  final void exportXML(Writer xml_writer) throws IOException
  {
    xml_writer.write("<ADR>");
    if (home_adr)
      xml_writer.write("<HOME/>");
    if (work_adr)
      xml_writer.write("<WORK/>");
    if (postal_adr)
      xml_writer.write("<POSTAL/>");
    if (parcel_adr)
      xml_writer.write("<PARCEL/>");
    if (domestic_adr)
      xml_writer.write("<DOM/>");
    if (intl_adr)
      xml_writer.write("<INTL/>");
    if (preferred)
      xml_writer.write("<PREF/>");
    xml_writer.write("\n");
    if (!StringUtil.isStringEmpty(pobox))
      xml_writer.write("<POBOX>" + pobox + "</POBOX>\n");
    if (!StringUtil.isStringEmpty(ext_address))
      xml_writer.write("<EXTADR>" + ext_address + "</EXTADR>\n");
    if (!StringUtil.isStringEmpty(street))
      xml_writer.write("<STREET>" + street + "</STREET>\n");
    if (!StringUtil.isStringEmpty(locality))
      xml_writer.write("<LOCALITY>" + locality + "</LOCALITY>\n");
    if (!StringUtil.isStringEmpty(region))
      xml_writer.write("<REGION>" + region + "</REGION>\n");
    if (!StringUtil.isStringEmpty(postal_code))
      xml_writer.write("<PCODE>" + postal_code + "</PCODE>\n");
    if (!StringUtil.isStringEmpty(country))
      xml_writer.write("<CTRY>" + country + "</CTRY>\n");
    xml_writer.write("</ADR>\n");

  } // end exportXML

  /*--------------------------------------------------------------------------------
   * Overrides from class Object
   *--------------------------------------------------------------------------------
   */

  public boolean equals(Object o)
  {
    if ((o==null) || !(o instanceof VCardAddress))
      return false;
    VCardAddress other = (VCardAddress)o;
    if (   (home_adr!=other.home_adr) || (work_adr!=other.work_adr) || (postal_adr!=other.postal_adr)
	|| (parcel_adr!=other.parcel_adr) || (domestic_adr!=other.domestic_adr) || (intl_adr!=other.intl_adr)
	|| (preferred!=other.preferred))
      return false;
    if (!StringUtil.areEqual(pobox,other.pobox))
      return false;
    if (!StringUtil.areEqual(ext_address,other.ext_address))
      return false;
    if (!StringUtil.areEqual(street,other.street))
      return false;
    if (!StringUtil.areEqual(locality,other.locality))
      return false;
    if (!StringUtil.areEqual(region,other.region))
      return false;
    if (!StringUtil.areEqual(postal_code,other.postal_code))
      return false;
    return StringUtil.areEqual(country,other.country);

  } // end equals

  public int hashCode()
  {
    int rc = 0;
    int mask = 0x40000000;
    if (home_adr)
      rc |= mask;
    mask >>= 1;
    if (work_adr)
      rc |= mask;
    mask >>= 1;
    if (postal_adr)
      rc |= mask;
    mask >>= 1;
    if (parcel_adr)
      rc |= mask;
    mask >>= 1;
    if (domestic_adr)
      rc |= mask;
    mask >>= 1;
    if (intl_adr)
      rc |= mask;
    mask >>= 1;
    if (preferred)
      rc |= mask;
    if (pobox!=null)
      rc ^= pobox.hashCode();
    if (ext_address!=null)
      rc ^= ext_address.hashCode();
    if (street!=null)
      rc ^= street.hashCode();
    if (locality!=null)
      rc ^= locality.hashCode();
    if (region!=null)
      rc ^= region.hashCode();
    if (postal_code!=null)
      rc ^= postal_code.hashCode();
    if (country!=null)
      rc ^= country.hashCode();
    return rc;

  } // end hashCode

  /*--------------------------------------------------------------------------------
   * External getters/setters
   *--------------------------------------------------------------------------------
   */

  public final boolean isHomeAddress()
  {
    return home_adr;

  } // end isHomeAddress

  public final boolean isWorkAddress()
  {
    return work_adr;

  } // end isWorkAddress

  public final boolean isPostalAddress()
  {
    return postal_adr;

  } // end isPostalAddress

  public final boolean isParcelAddress()
  {
    return parcel_adr;

  } // end isParcelAddress

  public final boolean isDomesticAddress()
  {
    return domestic_adr;

  } // end isDomesticAddress

  public final boolean isInternationalAddress()
  {
    return intl_adr;

  } // end isInternationalAddress

  public final boolean isPreferred()
  {
    return preferred;

  } // end isPreferred

  public final String getPOBox()
  {
    return pobox;

  } // end getPOBox

  public final String getExtension()
  {
    return ext_address;

  } // end getExtension

  public final String getStreet()
  {
    return street;

  } // end getStreet

  public final String getLocality()
  {
    return locality;

  } // end getLocality

  public final String getRegion()
  {
    return region;

  } // end getRegion

  public final String getPostalCode()
  {
    return postal_code;

  } // end getPostalCode

  public final String getCountry()
  {
    return country;

  } // end getCountry

} // end class VCardAddress
