/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jdo.tck.pc.newInstance;

import java.io.Serializable;

/** This class represents a postal address. */
public class Address implements IAddress
//        , Serializable, Comparable, Comparator, DeepEquality
{

  private long addrid;
  private String street;
  private String city;
  private String state;
  private String zipcode;
  private String country;

  /**
   * This is the JDO-required no-args constructor. The TCK relies on this constructor for testing
   * PersistenceManager.newInstance(PCClass).
   */
  public Address() {}

  /**
   * This constructor initializes the <code>Address</code> components.
   *
   * @param addrid The address ID.
   * @param street The street address.
   * @param city The city.
   * @param state The state.
   * @param zipcode The zip code.
   * @param country The zip country.
   */
  public Address(
      long addrid, String street, String city, String state, String zipcode, String country) {
    this.addrid = addrid;
    this.street = street;
    this.city = city;
    this.state = state;
    this.zipcode = zipcode;
    this.country = country;
  }

  /**
   * Get the addrid associated with this object.
   *
   * @return the addrid.
   */
  public long getAddrid() {
    return addrid;
  }

  /**
   * Set the id associated with this object.
   *
   * @param id the id.
   */
  public void setAddrid(long id) {
    if (this.addrid != 0) throw new IllegalStateException("Id is already set.");
    this.addrid = id;
  }

  /**
   * Get the street component of the address.
   *
   * @return The street component of the address.
   */
  public String getStreet() {
    return street;
  }

  /**
   * Set the street component of the address.
   *
   * @param street The street component.
   */
  public void setStreet(String street) {
    this.street = street;
  }

  /**
   * Get the city.
   *
   * @return The city component of the address.
   */
  public String getCity() {
    return city;
  }

  /**
   * Set the city component of the address.
   *
   * @param city The city.
   */
  public void setCity(String city) {
    this.city = city;
  }

  /**
   * Get the state component of the address.
   *
   * @return The state.
   */
  public String getState() {
    return state;
  }

  /**
   * Set the state component of the address.
   *
   * @param state The state.
   */
  public void setState(String state) {
    this.state = state;
  }

  /**
   * Get the zipcode component of the address.
   *
   * @return The zipcode.
   */
  public String getZipcode() {
    return zipcode;
  }

  /**
   * Set the zip code component of the address.
   *
   * @param zipcode The zipcode.
   */
  public void setZipcode(String zipcode) {
    this.zipcode = zipcode;
  }

  /**
   * Get the country component of the address.
   *
   * @return The country.
   */
  public String getCountry() {
    return country;
  }

  /**
   * Set the country component of the address.
   *
   * @param country The country.
   */
  public void setCountry(String country) {
    this.country = country;
  }

  /**
   * Returns a String representation of a <code>Address</code> object.
   *
   * @return a String representation of a <code>Address</code> object.
   */
  public String toString() {
    return "Address(" + getFieldRepr() + ")";
  }

  /**
   * Returns a String representation of the non-relationship fields.
   *
   * @return a String representation of the non-relationship fields.
   */
  protected String getFieldRepr() {
    StringBuilder rc = new StringBuilder();
    rc.append(addrid);
    rc.append(", street ").append(street);
    rc.append(", city ").append(city);
    rc.append(", state ").append(state);
    rc.append(", zipcode ").append(zipcode);
    rc.append(", country ").append(country);
    return rc.toString();
  }

  //    /**
  //     * Returns <code>true</code> if all the fields of this instance are
  //     * deep equal to the coresponding fields of the specified Person.
  //     * @param other the object with which to compare.
  //     * @param helper EqualityHelper to keep track of instances that have
  //     * already been processed.
  //     * @return <code>true</code> if all the fields are deep equal;
  //     * <code>false</code> otherwise.
  //     * @throws ClassCastException if the specified instances' type prevents
  //     * it from being compared to this instance.
  //     */
  //    public boolean deepCompareFields(Object other,
  //                                     EqualityHelper helper) {
  //        IAddress otherAddress = (IAddress)other;
  //        String where = "Address<" + addrid + ">";
  //        return
  //            helper.equals(addrid, otherAddress.getAddrid(), where + ".addrid") &
  //            helper.equals(street, otherAddress.getStreet(), where + ".street") &
  //            helper.equals(city, otherAddress.getCity(), where + ".city") &
  //            helper.equals(state, otherAddress.getState(), where + ".state") &
  //            helper.equals(zipcode, otherAddress.getZipcode(), where + ".zipcode") &
  //            helper.equals(country, otherAddress.getCountry(), where + ".country");
  //    }
  //
  //    /**
  //     * Compares this object with the specified object for order. Returns a
  //     * negative integer, zero, or a positive integer as this object is less
  //     * than, equal to, or greater than the specified object.
  //     * @param o The Object to be compared.
  //     * @return a negative integer, zero, or a positive integer as this
  //     * object is less than, equal to, or greater than the specified object.
  //     * @throws ClassCastException - if the specified object's type prevents
  //     * it from being compared to this Object.
  //     */
  //    public int compareTo(Object o) {
  //        return compareTo((IAddress)o);
  //    }
  //
  //    /**
  //     * Compare two instances. This is a method in Comparator.
  //     */
  //    public int compare(Object o1, Object o2) {
  //        return compare((IAddress)o1, (IAddress)o2);
  //    }
  //
  //    /**
  //     * Compares this object with the specified Address object for
  //     * order. Returns a negative integer, zero, or a positive integer as
  //     * this object is less than, equal to, or greater than the specified
  //     * object.
  //     * @param other The Address object to be compared.
  //     * @return a negative integer, zero, or a positive integer as this
  //     * object is less than, equal to, or greater than the specified Address
  //     * object.
  //     */
  //    public int compareTo(IAddress other) {
  //        return compare(this, other);
  //    }
  //
  //    /**
  //     * Compares its two IAddress arguments for order. Returns a negative
  //     * integer, zero, or a positive integer as the first argument is less
  //     * than, equal to, or greater than the second.
  //     * @param o1 the first IAddress object to be compared.
  //     * @param o2 the second IAddress object to be compared.
  //     * @return a negative integer, zero, or a positive integer as the first
  //     * object is less than, equal to, or greater than the second object.
  //     */
  //    public static int compare(IAddress o1, IAddress o2) {
  //        return EqualityHelper.compare(o1.getAddrid(), o2.getAddrid());
  //    }
  //
  //    /**
  //     * Indicates whether some other object is "equal to" this one.
  //     * @param obj the object with which to compare.
  //     * @return <code>true</code> if this object is the same as the obj
  //     * argument; <code>false</code> otherwise.
  //     */
  //    public boolean equals(Object obj) {
  //        if (obj instanceof IAddress) {
  //            return compareTo((IAddress)obj) == 0;
  //        }
  //        return false;
  //    }

  /**
   * Returns a hash code value for the object.
   *
   * @return a hash code value for this object.
   */
  public int hashCode() {
    return (int) addrid;
  }

  /**
   * This class is used to represent the application identifier for the <code>Address</code> class.
   */
  public static class Oid implements Serializable, Comparable<Oid> {

    private static final long serialVersionUID = 1L;

    /**
     * This is the identifier field for <code>Address</code> and must correspond in type and name to
     * the field in <code>Address</code>.
     */
    public long addrid;

    /** The required public, no-arg constructor. */
    public Oid() {
      addrid = 0;
    }

    /**
     * A constructor to initialize the identifier field.
     *
     * @param addrid the id of the Address.
     */
    public Oid(long addrid) {
      this.addrid = addrid;
    }

    public Oid(String s) {
      addrid = Long.parseLong(justTheId(s));
    }

    public String toString() {
      return this.getClass().getName() + ": " + addrid;
    }

    /** */
    public boolean equals(java.lang.Object obj) {
      if (obj == null || !this.getClass().equals(obj.getClass())) return (false);
      Oid o = (Oid) obj;
      if (this.addrid != o.addrid) return (false);
      return (true);
    }

    /** */
    public int hashCode() {
      return ((int) addrid);
    }

    protected static String justTheId(String str) {
      return str.substring(str.indexOf(':') + 1);
    }

    /** */
    public int compareTo(Oid obj) {
      return Long.compare(addrid, obj.addrid);
    }
  }
}
