/**
 * Autogenerated by Thrift
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.util.BitSet;
import java.util.Arrays;
import com.facebook.thrift.*;
import com.facebook.thrift.annotations.*;
import com.facebook.thrift.async.*;
import com.facebook.thrift.meta_data.*;
import com.facebook.thrift.server.*;
import com.facebook.thrift.transport.*;
import com.facebook.thrift.protocol.*;

@SuppressWarnings({ "unused", "serial" })
public class Person implements TBase, java.io.Serializable, Cloneable {
  private static final TStruct STRUCT_DESC = new TStruct("Person");
  private static final TField ID_FIELD_DESC = new TField("id", TType.I64, (short)1);
  private static final TField NAME_FIELD_DESC = new TField("name", TType.STRING, (short)2);
  private static final TField AGE_FIELD_DESC = new TField("age", TType.I16, (short)3);
  private static final TField ADDRESS_FIELD_DESC = new TField("address", TType.STRING, (short)4);
  private static final TField FAVORITE_COLOR_FIELD_DESC = new TField("favoriteColor", TType.STRUCT, (short)5);
  private static final TField FRIENDS_FIELD_DESC = new TField("friends", TType.SET, (short)6);
  private static final TField BEST_FRIEND_FIELD_DESC = new TField("bestFriend", TType.I64, (short)7);
  private static final TField PET_NAMES_FIELD_DESC = new TField("petNames", TType.MAP, (short)8);
  private static final TField AFRAID_OF_ANIMAL_FIELD_DESC = new TField("afraidOfAnimal", TType.I32, (short)9);
  private static final TField VEHICLES_FIELD_DESC = new TField("vehicles", TType.LIST, (short)10);

  public final Long id;
  public final String name;
  public final Short age;
  public final String address;
  public final Color favoriteColor;
  public final Set<Long> friends;
  public final Long bestFriend;
  public final Map<Animal,String> petNames;
  /**
   * 
   * @see Animal
   */
  public final Animal afraidOfAnimal;
  public final List<Vehicle> vehicles;
  public static final int ID = 1;
  public static final int NAME = 2;
  public static final int AGE = 3;
  public static final int ADDRESS = 4;
  public static final int FAVORITECOLOR = 5;
  public static final int FRIENDS = 6;
  public static final int BESTFRIEND = 7;
  public static final int PETNAMES = 8;
  public static final int AFRAIDOFANIMAL = 9;
  public static final int VEHICLES = 10;

  public Person(
      Long id,
      String name,
      Short age,
      String address,
      Color favoriteColor,
      Set<Long> friends,
      Long bestFriend,
      Map<Animal,String> petNames,
      Animal afraidOfAnimal,
      List<Vehicle> vehicles) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.address = address;
    this.favoriteColor = favoriteColor;
    this.friends = friends;
    this.bestFriend = bestFriend;
    this.petNames = petNames;
    this.afraidOfAnimal = afraidOfAnimal;
    this.vehicles = vehicles;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Person(Person other) {
    if (other.isSetId()) {
      this.id = TBaseHelper.deepCopy(other.id);
    } else {
      this.id = null;
    }
    if (other.isSetName()) {
      this.name = TBaseHelper.deepCopy(other.name);
    } else {
      this.name = null;
    }
    if (other.isSetAge()) {
      this.age = TBaseHelper.deepCopy(other.age);
    } else {
      this.age = null;
    }
    if (other.isSetAddress()) {
      this.address = TBaseHelper.deepCopy(other.address);
    } else {
      this.address = null;
    }
    if (other.isSetFavoriteColor()) {
      this.favoriteColor = TBaseHelper.deepCopy(other.favoriteColor);
    } else {
      this.favoriteColor = null;
    }
    if (other.isSetFriends()) {
      this.friends = TBaseHelper.deepCopy(other.friends);
    } else {
      this.friends = null;
    }
    if (other.isSetBestFriend()) {
      this.bestFriend = TBaseHelper.deepCopy(other.bestFriend);
    } else {
      this.bestFriend = null;
    }
    if (other.isSetPetNames()) {
      this.petNames = TBaseHelper.deepCopy(other.petNames);
    } else {
      this.petNames = null;
    }
    if (other.isSetAfraidOfAnimal()) {
      this.afraidOfAnimal = TBaseHelper.deepCopy(other.afraidOfAnimal);
    } else {
      this.afraidOfAnimal = null;
    }
    if (other.isSetVehicles()) {
      this.vehicles = TBaseHelper.deepCopy(other.vehicles);
    } else {
      this.vehicles = null;
    }
  }

  public Person deepCopy() {
    return new Person(this);
  }

  public Long getId() {
    return this.id;
  }

  // Returns true if field id is set (has been assigned a value) and false otherwise
  public boolean isSetId() {
    return this.id != null;
  }

  public String getName() {
    return this.name;
  }

  // Returns true if field name is set (has been assigned a value) and false otherwise
  public boolean isSetName() {
    return this.name != null;
  }

  public Short getAge() {
    return this.age;
  }

  // Returns true if field age is set (has been assigned a value) and false otherwise
  public boolean isSetAge() {
    return this.age != null;
  }

  public String getAddress() {
    return this.address;
  }

  // Returns true if field address is set (has been assigned a value) and false otherwise
  public boolean isSetAddress() {
    return this.address != null;
  }

  public Color getFavoriteColor() {
    return this.favoriteColor;
  }

  // Returns true if field favoriteColor is set (has been assigned a value) and false otherwise
  public boolean isSetFavoriteColor() {
    return this.favoriteColor != null;
  }

  public Set<Long> getFriends() {
    return this.friends;
  }

  // Returns true if field friends is set (has been assigned a value) and false otherwise
  public boolean isSetFriends() {
    return this.friends != null;
  }

  public Long getBestFriend() {
    return this.bestFriend;
  }

  // Returns true if field bestFriend is set (has been assigned a value) and false otherwise
  public boolean isSetBestFriend() {
    return this.bestFriend != null;
  }

  public Map<Animal,String> getPetNames() {
    return this.petNames;
  }

  // Returns true if field petNames is set (has been assigned a value) and false otherwise
  public boolean isSetPetNames() {
    return this.petNames != null;
  }

  /**
   * 
   * @see Animal
   */
  public Animal getAfraidOfAnimal() {
    return this.afraidOfAnimal;
  }

  // Returns true if field afraidOfAnimal is set (has been assigned a value) and false otherwise
  public boolean isSetAfraidOfAnimal() {
    return this.afraidOfAnimal != null;
  }

  public List<Vehicle> getVehicles() {
    return this.vehicles;
  }

  // Returns true if field vehicles is set (has been assigned a value) and false otherwise
  public boolean isSetVehicles() {
    return this.vehicles != null;
  }

  @Override
  public boolean equals(Object _that) {
    if (_that == null)
      return false;
    if (this == _that)
      return true;
    if (!(_that instanceof Person))
      return false;
    Person that = (Person)_that;

    if (!TBaseHelper.equalsNobinary(this.isSetId(), that.isSetId(), this.id, that.id)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetName(), that.isSetName(), this.name, that.name)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetAge(), that.isSetAge(), this.age, that.age)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetAddress(), that.isSetAddress(), this.address, that.address)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetFavoriteColor(), that.isSetFavoriteColor(), this.favoriteColor, that.favoriteColor)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetFriends(), that.isSetFriends(), this.friends, that.friends)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetBestFriend(), that.isSetBestFriend(), this.bestFriend, that.bestFriend)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetPetNames(), that.isSetPetNames(), this.petNames, that.petNames)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetAfraidOfAnimal(), that.isSetAfraidOfAnimal(), this.afraidOfAnimal, that.afraidOfAnimal)) { return false; }

    if (!TBaseHelper.equalsNobinary(this.isSetVehicles(), that.isSetVehicles(), this.vehicles, that.vehicles)) { return false; }

    return true;
  }

  @Override
  public int hashCode() {
    return Arrays.deepHashCode(new Object[] {id, name, age, address, favoriteColor, friends, bestFriend, petNames, afraidOfAnimal, vehicles});
  }

  // This is required to satisfy the TBase interface, but can't be implemented on immutable struture.
  public void read(TProtocol iprot) throws TException {
    throw new TException("unimplemented in android immutable structure");
  }

  public static Person deserialize(TProtocol iprot) throws TException {
    Long tmp_id = null;
    String tmp_name = null;
    Short tmp_age = null;
    String tmp_address = null;
    Color tmp_favoriteColor = null;
    Set<Long> tmp_friends = null;
    Long tmp_bestFriend = null;
    Map<Animal,String> tmp_petNames = null;
    Animal tmp_afraidOfAnimal = null;
    List<Vehicle> tmp_vehicles = null;
    TField __field;
    iprot.readStructBegin();
    while (true)
    {
      __field = iprot.readFieldBegin();
      if (__field.type == TType.STOP) {
        break;
      }
      switch (__field.id)
      {
        case ID:
          if (__field.type == TType.I64) {
            tmp_id = iprot.readI64();
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case NAME:
          if (__field.type == TType.STRING) {
            tmp_name = iprot.readString();
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case AGE:
          if (__field.type == TType.I16) {
            tmp_age = iprot.readI16();
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case ADDRESS:
          if (__field.type == TType.STRING) {
            tmp_address = iprot.readString();
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case FAVORITECOLOR:
          if (__field.type == TType.STRUCT) {
            tmp_favoriteColor = Color.deserialize(iprot);
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case FRIENDS:
          if (__field.type == TType.SET) {
            {
              TSet _set0 = iprot.readSetBegin();
              tmp_friends = new HashSet<Long>(Math.max(0, 2*_set0.size));
              for (int _i1 = 0; 
                   (_set0.size < 0) ? iprot.peekSet() : (_i1 < _set0.size); 
                   ++_i1)
              {
                Long _elem2;
                _elem2 = iprot.readI64();
                tmp_friends.add(_elem2);
              }
              iprot.readSetEnd();
            }
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case BESTFRIEND:
          if (__field.type == TType.I64) {
            tmp_bestFriend = iprot.readI64();
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case PETNAMES:
          if (__field.type == TType.MAP) {
            {
              TMap _map3 = iprot.readMapBegin();
              tmp_petNames = new HashMap<Animal,String>(Math.max(0, 2*_map3.size));
              for (int _i4 = 0; 
                   (_map3.size < 0) ? iprot.peekMap() : (_i4 < _map3.size); 
                   ++_i4)
              {
                Animal _key5;
                String _val6;
                _key5 = Animal.findByValue(iprot.readI32());
                _val6 = iprot.readString();
                tmp_petNames.put(_key5, _val6);
              }
              iprot.readMapEnd();
            }
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case AFRAIDOFANIMAL:
          if (__field.type == TType.I32) {
            tmp_afraidOfAnimal = Animal.findByValue(iprot.readI32());
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        case VEHICLES:
          if (__field.type == TType.LIST) {
            {
              TList _list7 = iprot.readListBegin();
              tmp_vehicles = new ArrayList<Vehicle>(Math.max(0, _list7.size));
              for (int _i8 = 0; 
                   (_list7.size < 0) ? iprot.peekList() : (_i8 < _list7.size); 
                   ++_i8)
              {
                Vehicle _elem9;
                _elem9 = Vehicle.deserialize(iprot);
                tmp_vehicles.add(_elem9);
              }
              iprot.readListEnd();
            }
          } else {
            TProtocolUtil.skip(iprot, __field.type);
          }
          break;
        default:
          TProtocolUtil.skip(iprot, __field.type);
          break;
      }
      iprot.readFieldEnd();
    }
    iprot.readStructEnd();

    Person _that;
    _that = new Person(
      tmp_id
      ,tmp_name
      ,tmp_age
      ,tmp_address
      ,tmp_favoriteColor
      ,tmp_friends
      ,tmp_bestFriend
      ,tmp_petNames
      ,tmp_afraidOfAnimal
      ,tmp_vehicles
    );
    _that.validate();
    return _that;
  }

  public void write(TProtocol oprot) throws TException {
    validate();

    oprot.writeStructBegin(STRUCT_DESC);
    if (this.id != null) {
      oprot.writeFieldBegin(ID_FIELD_DESC);
      oprot.writeI64(this.id);
      oprot.writeFieldEnd();
    }
    if (this.name != null) {
      oprot.writeFieldBegin(NAME_FIELD_DESC);
      oprot.writeString(this.name);
      oprot.writeFieldEnd();
    }
    if (this.age != null) {
      if (isSetAge()) {
        oprot.writeFieldBegin(AGE_FIELD_DESC);
        oprot.writeI16(this.age);
        oprot.writeFieldEnd();
      }
    }
    if (this.address != null) {
      if (isSetAddress()) {
        oprot.writeFieldBegin(ADDRESS_FIELD_DESC);
        oprot.writeString(this.address);
        oprot.writeFieldEnd();
      }
    }
    if (this.favoriteColor != null) {
      if (isSetFavoriteColor()) {
        oprot.writeFieldBegin(FAVORITE_COLOR_FIELD_DESC);
        this.favoriteColor.write(oprot);
        oprot.writeFieldEnd();
      }
    }
    if (this.friends != null) {
      if (isSetFriends()) {
        oprot.writeFieldBegin(FRIENDS_FIELD_DESC);
        {
          oprot.writeSetBegin(new TSet(TType.I64, this.friends.size()));
          for (Long _iter10 : this.friends)          {
            oprot.writeI64(_iter10);
          }
          oprot.writeSetEnd();
        }
        oprot.writeFieldEnd();
      }
    }
    if (this.bestFriend != null) {
      if (isSetBestFriend()) {
        oprot.writeFieldBegin(BEST_FRIEND_FIELD_DESC);
        oprot.writeI64(this.bestFriend);
        oprot.writeFieldEnd();
      }
    }
    if (this.petNames != null) {
      if (isSetPetNames()) {
        oprot.writeFieldBegin(PET_NAMES_FIELD_DESC);
        {
          oprot.writeMapBegin(new TMap(TType.I32, TType.STRING, this.petNames.size()));
          for (Map.Entry<Animal, String> _iter11 : this.petNames.entrySet())          {
            oprot.writeI32(_iter11.getKey() == null ? 0 : _iter11.getKey().getValue());
            oprot.writeString(_iter11.getValue());
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
    }
    if (this.afraidOfAnimal != null) {
      if (isSetAfraidOfAnimal()) {
        oprot.writeFieldBegin(AFRAID_OF_ANIMAL_FIELD_DESC);
        oprot.writeI32(this.afraidOfAnimal == null ? 0 : this.afraidOfAnimal.getValue());
        oprot.writeFieldEnd();
      }
    }
    if (this.vehicles != null) {
      if (isSetVehicles()) {
        oprot.writeFieldBegin(VEHICLES_FIELD_DESC);
        {
          oprot.writeListBegin(new TList(TType.STRUCT, this.vehicles.size()));
          for (Vehicle _iter12 : this.vehicles)          {
            _iter12.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
    }
    oprot.writeFieldStop();
    oprot.writeStructEnd();
  }

  @Override
  public String toString() {
    return toString(1, true);
  }

  @Override
  public String toString(int indent, boolean prettyPrint) {
    return TBaseHelper.toStringHelper(this, indent, prettyPrint);
  }

  public void validate() throws TException {
    // check for required fields
  }

}

