/*
 * Trio class.
 *
 * Copyright (C) 2007 SATOH Takayuki All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package ts.util;

import java.io.Serializable;

/**
 * 三つのオブジェクトの組を保持するクラス。
 * <br>
 * 三つのオブジェクトの組をフィールド変数として保持し、
 * それぞれの値の設定や取得を行うメソッド、及び各オブジェクトの値の
 * 比較による等値の判定を行うメソッドを用意している。
 *
 * @author  佐藤隆之. 
 * @version $Revision: 1.1.1.1 $, $Date: 2010-10-16 00:03:45 $
 */
public class Trio<F, S, T> implements Serializable
{
  /** Vリアル番号。 */
  static final long serialVersionUID = -367706096060785413L;

  /** 第1オブジェクト。 */
  private F value1_ ;

  /** 第2オブジェクト。 */
  private S value2_ ;

  /** 第3オブジェクト。 */
  private T value3_ ;

  /**
   * デフォルトコンストラクタ。
   * <br>
   * 各オブジェクトの値はヌルに設定される。
   */
  public Trio()
  {}

  /**
   * 三つのオブジェクトを引数にとるコンストラクタ。
   * <br>
   * 引数がヌルの場合は、そのままヌルを設定する。
   *
   * @param  first  第一オブジェクト。
   * @param  second 第二オブジェクト。
   * @param  third  第三オブジェクト。
   */
  public Trio(F first, S second, T third)
  {
    set(first, second, third);
  }

  /**
   * 三つのオブジェクトを設定する。
   * <br>
   * 引数がヌルの場合は、そのままヌルを設定する。
   *
   * @param  first 第一オブジェクト。
   * @param  second 第二オブジェクト。
   * @param  third 第三オブジェクト。
   */
  public void set(F first, S second, T third)
  {
    setFirst(first);
    setSecond(second);
    setThird(third);
  }

  /**
   * 第一オブジェクトを設定する。
   * <br>
   * 引数がヌルの場合は、そのままヌルを設定する。
   *
   * @param  first 第一オブジェクト。
   */
  public void setFirst(F first)
  {
    value1_ = first;
  }

  /**
   * 第一オブジェクトを取得する。
   *
   * @return 第一オブジェクト。
   */
  public F getFirst()
  {
    return value1_ ;
  }

  /**
   * 第二オブジェクトを設定する。
   * <br>
   * 引数がヌルの場合は、そのままヌルを設定する。
   *
   * @param  second 第二オブジェクト。
   */
  public void setSecond(S second)
  {
    value2_ = second;
  }

  /**
   * 第二オブジェクトを取得する。
   *
   * @return 第二オブジェクト。
   */
  public S getSecond()
  {
    return value2_ ;
  }

  /**
   * 第三オブジェクトを設定する。
   * <br>
   * 引数がヌルの場合は、そのままヌルを設定する。
   *
   * @param  third 第三オブジェクト。
   */
  public void setThird(T third)
  {
    value3_ = third;
  }

  /**
   * 第三オブジェクトを取得する。
   *
   * @return 第三オブジェクト。
   */
  public T getThird()
  {
    return value3_ ;
  }

  /**
   * 指定されたオブジェクトと内容が等しいかどうかを比較する。
   * <br>
   * 引数が<code>Trio</code>オブジェクトの場合は、それらのフィールド変数である
   * 三つのオブジェクトをそれぞれ比較して、全て等しい場合は<tt>true</tt>を、
   * そうでなければ<tt>false</tt>を返す。
   * 引数がヌルまたは<code>Trio</code>オブジェクトでない場合は<tt>false</tt>を
   * 返す。
   *
   * @param  obj 比較するオブジェクト。
   * @return オブジェクトの内容が等しい場合は<tt>true</tt>を返す。
   */
  public boolean equals(Object obj)
  {
    if (obj == null || !(obj instanceof Trio))
      return false;

    Trio another = Trio.class.cast(obj);

    if (getFirst() == null) {
      if (another.getFirst() != null)
        return false;
    }
    else if (! getFirst().equals(another.getFirst())) {
      return false;
    }

    if (getSecond() == null) {
      if (another.getSecond() != null)
        return false;
    }
    else if (! getSecond().equals(another.getSecond())) {
      return false;
    }

    if (getThird() == null) {
      if (another.getThird() != null)
        return false;
    }
    else if (! getThird().equals(another.getThird())) {
      return false;
    }

    return true;
  }

  /**
   * ハッシュコードを取得する。
   *
   * @return  ハッシュコード。
   */
  public int hashCode()
  {
    int v1 = (getFirst()  == null) ? 0 :  getFirst().hashCode();
    int v2 = (getSecond() == null) ? 0 : getSecond().hashCode();
    int v3 = (getThird()  == null) ? 0 :  getThird().hashCode();
    return (v1 + v2 + v3);
  }
}
