// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.asn1.x500;

import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Object;

public class X500Name extends ASN1Object implements ASN1Choice
{
    private static X500NameStyle defaultStyle;
    private boolean isHashCodeCalculated;
    private int hashCodeValue;
    private X500NameStyle style;
    private RDN[] rdns;
    private DERSequence rdnSeq;
    
    @Deprecated
    public X500Name(final X500NameStyle style, final X500Name x500Name) {
        this.style = style;
        this.rdns = x500Name.rdns;
        this.rdnSeq = x500Name.rdnSeq;
    }
    
    public static X500Name getInstance(final ASN1TaggedObject asn1TaggedObject, final boolean b) {
        return getInstance(ASN1Sequence.getInstance(asn1TaggedObject, true));
    }
    
    public static X500Name getInstance(final Object o) {
        if (o instanceof X500Name) {
            return (X500Name)o;
        }
        if (o != null) {
            return new X500Name(ASN1Sequence.getInstance(o));
        }
        return null;
    }
    
    public static X500Name getInstance(final X500NameStyle x500NameStyle, final Object o) {
        if (o instanceof X500Name) {
            return new X500Name(x500NameStyle, (X500Name)o);
        }
        if (o != null) {
            return new X500Name(x500NameStyle, ASN1Sequence.getInstance(o));
        }
        return null;
    }
    
    private X500Name(final ASN1Sequence asn1Sequence) {
        this(X500Name.defaultStyle, asn1Sequence);
    }
    
    private X500Name(final X500NameStyle style, final ASN1Sequence asn1Sequence) {
        final int size = asn1Sequence.size();
        this.style = style;
        this.rdns = new RDN[size];
        boolean b = true;
        for (int i = 0; i < size; ++i) {
            final ASN1Encodable object = asn1Sequence.getObjectAt(i);
            final RDN instance = RDN.getInstance(object);
            b &= (instance == object);
            this.rdns[i] = instance;
        }
        if (b) {
            this.rdnSeq = DERSequence.convert(asn1Sequence);
        }
        else {
            this.rdnSeq = new DERSequence(this.rdns);
        }
    }
    
    public X500Name(final RDN[] array) {
        this(X500Name.defaultStyle, array);
    }
    
    public X500Name(final X500NameStyle style, final RDN[] array) {
        this.style = style;
        this.rdns = array.clone();
        this.rdnSeq = new DERSequence(this.rdns);
    }
    
    public X500Name(final String s) {
        this(X500Name.defaultStyle, s);
    }
    
    public X500Name(final X500NameStyle style, final String s) {
        this(style.fromString(s));
        this.style = style;
    }
    
    public RDN[] getRDNs() {
        return this.rdns.clone();
    }
    
    public ASN1ObjectIdentifier[] getAttributeTypes() {
        final int length = this.rdns.length;
        int n = 0;
        for (int i = 0; i < length; ++i) {
            n += this.rdns[i].size();
        }
        final ASN1ObjectIdentifier[] array = new ASN1ObjectIdentifier[n];
        int n2 = 0;
        for (int j = 0; j < length; ++j) {
            n2 += this.rdns[j].collectAttributeTypes(array, n2);
        }
        return array;
    }
    
    public RDN[] getRDNs(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        RDN[] array = new RDN[this.rdns.length];
        int n = 0;
        for (int i = 0; i != this.rdns.length; ++i) {
            final RDN rdn = this.rdns[i];
            if (rdn.containsAttributeType(asn1ObjectIdentifier)) {
                array[n++] = rdn;
            }
        }
        if (n < array.length) {
            final RDN[] array2 = new RDN[n];
            System.arraycopy(array, 0, array2, 0, array2.length);
            array = array2;
        }
        return array;
    }
    
    public int size() {
        return this.rdns.length;
    }
    
    @Override
    public ASN1Primitive toASN1Primitive() {
        return this.rdnSeq;
    }
    
    @Override
    public int hashCode() {
        if (this.isHashCodeCalculated) {
            return this.hashCodeValue;
        }
        this.isHashCodeCalculated = true;
        return this.hashCodeValue = this.style.calculateHashCode(this);
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof X500Name) && !(o instanceof ASN1Sequence)) {
            return false;
        }
        if (this.toASN1Primitive().equals(((ASN1Encodable)o).toASN1Primitive())) {
            return true;
        }
        try {
            return this.style.areEqual(this, getInstance(o));
        }
        catch (final Exception ex) {
            return false;
        }
    }
    
    @Override
    public String toString() {
        return this.style.toString(this);
    }
    
    public static void setDefaultStyle(final X500NameStyle defaultStyle) {
        if (defaultStyle == null) {
            throw new NullPointerException("cannot set style to null");
        }
        X500Name.defaultStyle = defaultStyle;
    }
    
    public static X500NameStyle getDefaultStyle() {
        return X500Name.defaultStyle;
    }
    
    static {
        X500Name.defaultStyle = BCStyle.INSTANCE;
    }
}
