/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     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 
>>>>>>> Stashed changes
 * 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);
    }
  }
}
