/**
 * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.financial.security.equity;

import java.util.Map;

import org.joda.beans.Bean;
import org.joda.beans.BeanBuilder;
import org.joda.beans.BeanDefinition;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaProperty;
import org.joda.beans.Property;
import org.joda.beans.PropertyDefinition;
import org.joda.beans.impl.direct.DirectBeanBuilder;
import org.joda.beans.impl.direct.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;

import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.FinancialSecurityVisitor;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.master.security.SecurityDescription;
import com.opengamma.util.money.Currency;


/**
 * A class representing an American depositary receipt security.
 */
@BeanDefinition
@SecurityDescription(type = AmericanDepositaryReceiptSecurity.SECURITY_TYPE, description = "Adr")
public class AmericanDepositaryReceiptSecurity extends FinancialSecurity {

  /** Serialization version */
  private static final long serialVersionUID = 1L;

  /**
   * The security type.
   */
  public static final String SECURITY_TYPE = "ADR";

  /**
   * The short name.
   */
  @PropertyDefinition
  private String _shortName;

  /**
   * The exchange description.
   */
  @PropertyDefinition(validate = "notNull")
  private String _exchange;

  /**
   * The exchange code.
   */
  @PropertyDefinition(validate = "notNull")
  private String _exchangeCode;

  /**
   * The company name.
   */
  @PropertyDefinition(validate = "notNull")
  private String _companyName;

  /**
   * Security currency.
   */
  @PropertyDefinition(validate = "notNull")
  private Currency _currency;

  /**
   * The foreign currency.
   */
  @PropertyDefinition(validate = "notNull")
  private Currency _foreignCurrency;

  /**
   * The GICS code.
   */
  @PropertyDefinition
  private GICSCode _gicsCode;

  /**
   * The id bundle of the foreign equity.
   */
  @PropertyDefinition(validate = "notNull")
  private ExternalIdBundle _underlyingIdBundle;

  /**
   * For the builder.
   */
  /* package */ AmericanDepositaryReceiptSecurity() {
    super(SECURITY_TYPE);
  }

  /**
   * Creates an instance without setting the GICS code or the short name.
   * @param exchange The exchange, not null
   * @param exchangeCode The exchange code, not null
   * @param companyName The company name, not null
   * @param currency The currency, not null
   * @param foreignCurrency The foreign currency, not null
   * @param underlyingIdBundle The underlying id bundle, not null
   */
  public AmericanDepositaryReceiptSecurity(final String exchange, final String exchangeCode, final String companyName, final Currency currency,
      final Currency foreignCurrency, final ExternalIdBundle underlyingIdBundle) {
    super(SECURITY_TYPE);
    setExchange(exchange);
    setExchangeCode(exchangeCode);
    setCompanyName(companyName);
    setCurrency(currency);
    setForeignCurrency(foreignCurrency);
    setUnderlyingIdBundle(underlyingIdBundle);
  }

  /**
   * Creates an instance.
   * @param shortName The short name
   * @param exchange The exchange, not null
   * @param exchangeCode The exchange code, not null
   * @param companyName The company name, not null
   * @param currency The currency, not null
   * @param foreignCurrency The foreign currency, not null
   * @param gicsCode The GICS code
   * @param underlyingIdBundle The underlying id bundle, not null
   */
  public AmericanDepositaryReceiptSecurity(final String shortName, final String exchange, final String exchangeCode, final String companyName, final Currency currency,
      final Currency foreignCurrency, final GICSCode gicsCode, final ExternalIdBundle underlyingIdBundle) {
    super(SECURITY_TYPE);
    setExchange(exchange);
    setExchangeCode(exchangeCode);
    setCompanyName(companyName);
    setCurrency(currency);
    setForeignCurrency(foreignCurrency);
    setGicsCode(gicsCode);
    setUnderlyingIdBundle(underlyingIdBundle);
  }

  @Override
  public <T> T accept(final FinancialSecurityVisitor<T> visitor) {
    return visitor.visitAmericanDepositaryReceiptSecurity(this);
  }

  //------------------------- AUTOGENERATED START -------------------------
  ///CLOVER:OFF
  /**
   * The meta-bean for {@code AmericanDepositaryReceiptSecurity}.
   * @return the meta-bean, not null
   */
  public static AmericanDepositaryReceiptSecurity.Meta meta() {
    return AmericanDepositaryReceiptSecurity.Meta.INSTANCE;
  }

  static {
    JodaBeanUtils.registerMetaBean(AmericanDepositaryReceiptSecurity.Meta.INSTANCE);
  }

  @Override
  public AmericanDepositaryReceiptSecurity.Meta metaBean() {
    return AmericanDepositaryReceiptSecurity.Meta.INSTANCE;
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the short name.
   * @return the value of the property
   */
  public String getShortName() {
    return _shortName;
  }

  /**
   * Sets the short name.
   * @param shortName  the new value of the property
   */
  public void setShortName(String shortName) {
    this._shortName = shortName;
  }

  /**
   * Gets the the {@code shortName} property.
   * @return the property, not null
   */
  public final Property<String> shortName() {
    return metaBean().shortName().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the exchange description.
   * @return the value of the property, not null
   */
  public String getExchange() {
    return _exchange;
  }

  /**
   * Sets the exchange description.
   * @param exchange  the new value of the property, not null
   */
  public void setExchange(String exchange) {
    JodaBeanUtils.notNull(exchange, "exchange");
    this._exchange = exchange;
  }

  /**
   * Gets the the {@code exchange} property.
   * @return the property, not null
   */
  public final Property<String> exchange() {
    return metaBean().exchange().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the exchange code.
   * @return the value of the property, not null
   */
  public String getExchangeCode() {
    return _exchangeCode;
  }

  /**
   * Sets the exchange code.
   * @param exchangeCode  the new value of the property, not null
   */
  public void setExchangeCode(String exchangeCode) {
    JodaBeanUtils.notNull(exchangeCode, "exchangeCode");
    this._exchangeCode = exchangeCode;
  }

  /**
   * Gets the the {@code exchangeCode} property.
   * @return the property, not null
   */
  public final Property<String> exchangeCode() {
    return metaBean().exchangeCode().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the company name.
   * @return the value of the property, not null
   */
  public String getCompanyName() {
    return _companyName;
  }

  /**
   * Sets the company name.
   * @param companyName  the new value of the property, not null
   */
  public void setCompanyName(String companyName) {
    JodaBeanUtils.notNull(companyName, "companyName");
    this._companyName = companyName;
  }

  /**
   * Gets the the {@code companyName} property.
   * @return the property, not null
   */
  public final Property<String> companyName() {
    return metaBean().companyName().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets security currency.
   * @return the value of the property, not null
   */
  public Currency getCurrency() {
    return _currency;
  }

  /**
   * Sets security currency.
   * @param currency  the new value of the property, not null
   */
  public void setCurrency(Currency currency) {
    JodaBeanUtils.notNull(currency, "currency");
    this._currency = currency;
  }

  /**
   * Gets the the {@code currency} property.
   * @return the property, not null
   */
  public final Property<Currency> currency() {
    return metaBean().currency().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the foreign currency.
   * @return the value of the property, not null
   */
  public Currency getForeignCurrency() {
    return _foreignCurrency;
  }

  /**
   * Sets the foreign currency.
   * @param foreignCurrency  the new value of the property, not null
   */
  public void setForeignCurrency(Currency foreignCurrency) {
    JodaBeanUtils.notNull(foreignCurrency, "foreignCurrency");
    this._foreignCurrency = foreignCurrency;
  }

  /**
   * Gets the the {@code foreignCurrency} property.
   * @return the property, not null
   */
  public final Property<Currency> foreignCurrency() {
    return metaBean().foreignCurrency().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the GICS code.
   * @return the value of the property
   */
  public GICSCode getGicsCode() {
    return _gicsCode;
  }

  /**
   * Sets the GICS code.
   * @param gicsCode  the new value of the property
   */
  public void setGicsCode(GICSCode gicsCode) {
    this._gicsCode = gicsCode;
  }

  /**
   * Gets the the {@code gicsCode} property.
   * @return the property, not null
   */
  public final Property<GICSCode> gicsCode() {
    return metaBean().gicsCode().createProperty(this);
  }

  //-----------------------------------------------------------------------
  /**
   * Gets the id bundle of the foreign equity.
   * @return the value of the property, not null
   */
  public ExternalIdBundle getUnderlyingIdBundle() {
    return _underlyingIdBundle;
  }

  /**
   * Sets the id bundle of the foreign equity.
   * @param underlyingIdBundle  the new value of the property, not null
   */
  public void setUnderlyingIdBundle(ExternalIdBundle underlyingIdBundle) {
    JodaBeanUtils.notNull(underlyingIdBundle, "underlyingIdBundle");
    this._underlyingIdBundle = underlyingIdBundle;
  }

  /**
   * Gets the the {@code underlyingIdBundle} property.
   * @return the property, not null
   */
  public final Property<ExternalIdBundle> underlyingIdBundle() {
    return metaBean().underlyingIdBundle().createProperty(this);
  }

  //-----------------------------------------------------------------------
  @Override
  public AmericanDepositaryReceiptSecurity clone() {
    return JodaBeanUtils.cloneAlways(this);
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj != null && obj.getClass() == this.getClass()) {
      AmericanDepositaryReceiptSecurity other = (AmericanDepositaryReceiptSecurity) obj;
      return JodaBeanUtils.equal(getShortName(), other.getShortName()) &&
          JodaBeanUtils.equal(getExchange(), other.getExchange()) &&
          JodaBeanUtils.equal(getExchangeCode(), other.getExchangeCode()) &&
          JodaBeanUtils.equal(getCompanyName(), other.getCompanyName()) &&
          JodaBeanUtils.equal(getCurrency(), other.getCurrency()) &&
          JodaBeanUtils.equal(getForeignCurrency(), other.getForeignCurrency()) &&
          JodaBeanUtils.equal(getGicsCode(), other.getGicsCode()) &&
          JodaBeanUtils.equal(getUnderlyingIdBundle(), other.getUnderlyingIdBundle()) &&
          super.equals(obj);
    }
    return false;
  }

  @Override
  public int hashCode() {
    int hash = 7;
    hash = hash * 31 + JodaBeanUtils.hashCode(getShortName());
    hash = hash * 31 + JodaBeanUtils.hashCode(getExchange());
    hash = hash * 31 + JodaBeanUtils.hashCode(getExchangeCode());
    hash = hash * 31 + JodaBeanUtils.hashCode(getCompanyName());
    hash = hash * 31 + JodaBeanUtils.hashCode(getCurrency());
    hash = hash * 31 + JodaBeanUtils.hashCode(getForeignCurrency());
    hash = hash * 31 + JodaBeanUtils.hashCode(getGicsCode());
    hash = hash * 31 + JodaBeanUtils.hashCode(getUnderlyingIdBundle());
    return hash ^ super.hashCode();
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder(288);
    buf.append("AmericanDepositaryReceiptSecurity{");
    int len = buf.length();
    toString(buf);
    if (buf.length() > len) {
      buf.setLength(buf.length() - 2);
    }
    buf.append('}');
    return buf.toString();
  }

  @Override
  protected void toString(StringBuilder buf) {
    super.toString(buf);
    buf.append("shortName").append('=').append(JodaBeanUtils.toString(getShortName())).append(',').append(' ');
    buf.append("exchange").append('=').append(JodaBeanUtils.toString(getExchange())).append(',').append(' ');
    buf.append("exchangeCode").append('=').append(JodaBeanUtils.toString(getExchangeCode())).append(',').append(' ');
    buf.append("companyName").append('=').append(JodaBeanUtils.toString(getCompanyName())).append(',').append(' ');
    buf.append("currency").append('=').append(JodaBeanUtils.toString(getCurrency())).append(',').append(' ');
    buf.append("foreignCurrency").append('=').append(JodaBeanUtils.toString(getForeignCurrency())).append(',').append(' ');
    buf.append("gicsCode").append('=').append(JodaBeanUtils.toString(getGicsCode())).append(',').append(' ');
    buf.append("underlyingIdBundle").append('=').append(JodaBeanUtils.toString(getUnderlyingIdBundle())).append(',').append(' ');
  }

  //-----------------------------------------------------------------------
  /**
   * The meta-bean for {@code AmericanDepositaryReceiptSecurity}.
   */
  public static class Meta extends FinancialSecurity.Meta {
    /**
     * The singleton instance of the meta-bean.
     */
    static final Meta INSTANCE = new Meta();

    /**
     * The meta-property for the {@code shortName} property.
     */
    private final MetaProperty<String> _shortName = DirectMetaProperty.ofReadWrite(
        this, "shortName", AmericanDepositaryReceiptSecurity.class, String.class);
    /**
     * The meta-property for the {@code exchange} property.
     */
    private final MetaProperty<String> _exchange = DirectMetaProperty.ofReadWrite(
        this, "exchange", AmericanDepositaryReceiptSecurity.class, String.class);
    /**
     * The meta-property for the {@code exchangeCode} property.
     */
    private final MetaProperty<String> _exchangeCode = DirectMetaProperty.ofReadWrite(
        this, "exchangeCode", AmericanDepositaryReceiptSecurity.class, String.class);
    /**
     * The meta-property for the {@code companyName} property.
     */
    private final MetaProperty<String> _companyName = DirectMetaProperty.ofReadWrite(
        this, "companyName", AmericanDepositaryReceiptSecurity.class, String.class);
    /**
     * The meta-property for the {@code currency} property.
     */
    private final MetaProperty<Currency> _currency = DirectMetaProperty.ofReadWrite(
        this, "currency", AmericanDepositaryReceiptSecurity.class, Currency.class);
    /**
     * The meta-property for the {@code foreignCurrency} property.
     */
    private final MetaProperty<Currency> _foreignCurrency = DirectMetaProperty.ofReadWrite(
        this, "foreignCurrency", AmericanDepositaryReceiptSecurity.class, Currency.class);
    /**
     * The meta-property for the {@code gicsCode} property.
     */
    private final MetaProperty<GICSCode> _gicsCode = DirectMetaProperty.ofReadWrite(
        this, "gicsCode", AmericanDepositaryReceiptSecurity.class, GICSCode.class);
    /**
     * The meta-property for the {@code underlyingIdBundle} property.
     */
    private final MetaProperty<ExternalIdBundle> _underlyingIdBundle = DirectMetaProperty.ofReadWrite(
        this, "underlyingIdBundle", AmericanDepositaryReceiptSecurity.class, ExternalIdBundle.class);
    /**
     * The meta-properties.
     */
    private final Map<String, MetaProperty<?>> _metaPropertyMap$ = new DirectMetaPropertyMap(
        this, (DirectMetaPropertyMap) super.metaPropertyMap(),
        "shortName",
        "exchange",
        "exchangeCode",
        "companyName",
        "currency",
        "foreignCurrency",
        "gicsCode",
        "underlyingIdBundle");

    /**
     * Restricted constructor.
     */
    protected Meta() {
    }

    @Override
    protected MetaProperty<?> metaPropertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case -2028219097:  // shortName
          return _shortName;
        case 1989774883:  // exchange
          return _exchange;
        case 1429202608:  // exchangeCode
          return _exchangeCode;
        case -508582744:  // companyName
          return _companyName;
        case 575402001:  // currency
          return _currency;
        case 854442245:  // foreignCurrency
          return _foreignCurrency;
        case 762040799:  // gicsCode
          return _gicsCode;
        case 1485088762:  // underlyingIdBundle
          return _underlyingIdBundle;
      }
      return super.metaPropertyGet(propertyName);
    }

    @Override
    public BeanBuilder<? extends AmericanDepositaryReceiptSecurity> builder() {
      return new DirectBeanBuilder<AmericanDepositaryReceiptSecurity>(new AmericanDepositaryReceiptSecurity());
    }

    @Override
    public Class<? extends AmericanDepositaryReceiptSecurity> beanType() {
      return AmericanDepositaryReceiptSecurity.class;
    }

    @Override
    public Map<String, MetaProperty<?>> metaPropertyMap() {
      return _metaPropertyMap$;
    }

    //-----------------------------------------------------------------------
    /**
     * The meta-property for the {@code shortName} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<String> shortName() {
      return _shortName;
    }

    /**
     * The meta-property for the {@code exchange} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<String> exchange() {
      return _exchange;
    }

    /**
     * The meta-property for the {@code exchangeCode} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<String> exchangeCode() {
      return _exchangeCode;
    }

    /**
     * The meta-property for the {@code companyName} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<String> companyName() {
      return _companyName;
    }

    /**
     * The meta-property for the {@code currency} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<Currency> currency() {
      return _currency;
    }

    /**
     * The meta-property for the {@code foreignCurrency} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<Currency> foreignCurrency() {
      return _foreignCurrency;
    }

    /**
     * The meta-property for the {@code gicsCode} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<GICSCode> gicsCode() {
      return _gicsCode;
    }

    /**
     * The meta-property for the {@code underlyingIdBundle} property.
     * @return the meta-property, not null
     */
    public final MetaProperty<ExternalIdBundle> underlyingIdBundle() {
      return _underlyingIdBundle;
    }

    //-----------------------------------------------------------------------
    @Override
    protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -2028219097:  // shortName
          return ((AmericanDepositaryReceiptSecurity) bean).getShortName();
        case 1989774883:  // exchange
          return ((AmericanDepositaryReceiptSecurity) bean).getExchange();
        case 1429202608:  // exchangeCode
          return ((AmericanDepositaryReceiptSecurity) bean).getExchangeCode();
        case -508582744:  // companyName
          return ((AmericanDepositaryReceiptSecurity) bean).getCompanyName();
        case 575402001:  // currency
          return ((AmericanDepositaryReceiptSecurity) bean).getCurrency();
        case 854442245:  // foreignCurrency
          return ((AmericanDepositaryReceiptSecurity) bean).getForeignCurrency();
        case 762040799:  // gicsCode
          return ((AmericanDepositaryReceiptSecurity) bean).getGicsCode();
        case 1485088762:  // underlyingIdBundle
          return ((AmericanDepositaryReceiptSecurity) bean).getUnderlyingIdBundle();
      }
      return super.propertyGet(bean, propertyName, quiet);
    }

    @Override
    protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
      switch (propertyName.hashCode()) {
        case -2028219097:  // shortName
          ((AmericanDepositaryReceiptSecurity) bean).setShortName((String) newValue);
          return;
        case 1989774883:  // exchange
          ((AmericanDepositaryReceiptSecurity) bean).setExchange((String) newValue);
          return;
        case 1429202608:  // exchangeCode
          ((AmericanDepositaryReceiptSecurity) bean).setExchangeCode((String) newValue);
          return;
        case -508582744:  // companyName
          ((AmericanDepositaryReceiptSecurity) bean).setCompanyName((String) newValue);
          return;
        case 575402001:  // currency
          ((AmericanDepositaryReceiptSecurity) bean).setCurrency((Currency) newValue);
          return;
        case 854442245:  // foreignCurrency
          ((AmericanDepositaryReceiptSecurity) bean).setForeignCurrency((Currency) newValue);
          return;
        case 762040799:  // gicsCode
          ((AmericanDepositaryReceiptSecurity) bean).setGicsCode((GICSCode) newValue);
          return;
        case 1485088762:  // underlyingIdBundle
          ((AmericanDepositaryReceiptSecurity) bean).setUnderlyingIdBundle((ExternalIdBundle) newValue);
          return;
      }
      super.propertySet(bean, propertyName, newValue, quiet);
    }

    @Override
    protected void validate(Bean bean) {
      JodaBeanUtils.notNull(((AmericanDepositaryReceiptSecurity) bean)._exchange, "exchange");
      JodaBeanUtils.notNull(((AmericanDepositaryReceiptSecurity) bean)._exchangeCode, "exchangeCode");
      JodaBeanUtils.notNull(((AmericanDepositaryReceiptSecurity) bean)._companyName, "companyName");
      JodaBeanUtils.notNull(((AmericanDepositaryReceiptSecurity) bean)._currency, "currency");
      JodaBeanUtils.notNull(((AmericanDepositaryReceiptSecurity) bean)._foreignCurrency, "foreignCurrency");
      JodaBeanUtils.notNull(((AmericanDepositaryReceiptSecurity) bean)._underlyingIdBundle, "underlyingIdBundle");
      super.validate(bean);
    }

  }

  ///CLOVER:ON
  //-------------------------- AUTOGENERATED END --------------------------
}
