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

package org.bouncycastle.asn1;

import java.io.IOException;

public class BERBitString extends ASN1BitString
{
    private static final int DEFAULT_SEGMENT_LIMIT = 1000;
    private final int segmentLimit;
    private final ASN1BitString[] elements;
    
    static byte[] flattenBitStrings(final ASN1BitString[] array) {
        final int length = array.length;
        switch (length) {
            case 0: {
                return new byte[] { 0 };
            }
            case 1: {
                return array[0].contents;
            }
            default: {
                final int n = length - 1;
                int n2 = 0;
                for (int i = 0; i < n; ++i) {
                    final byte[] contents = array[i].contents;
                    if (contents[0] != 0) {
                        throw new IllegalArgumentException("only the last nested bitstring can have padding");
                    }
                    n2 += contents.length - 1;
                }
                final byte[] contents2 = array[n].contents;
                final byte b = contents2[0];
                final byte[] array2 = new byte[n2 + contents2.length];
                array2[0] = b;
                int n3 = 1;
                for (int j = 0; j < length; ++j) {
                    final byte[] contents3 = array[j].contents;
                    final int n4 = contents3.length - 1;
                    System.arraycopy(contents3, 1, array2, n3, n4);
                    n3 += n4;
                }
                return array2;
            }
        }
    }
    
    public BERBitString(final byte[] array) {
        this(array, 0);
    }
    
    public BERBitString(final byte b, final int n) {
        super(b, n);
        this.elements = null;
        this.segmentLimit = 1000;
    }
    
    public BERBitString(final byte[] array, final int n) {
        this(array, n, 1000);
    }
    
    public BERBitString(final byte[] array, final int n, final int segmentLimit) {
        super(array, n);
        this.elements = null;
        this.segmentLimit = segmentLimit;
    }
    
    public BERBitString(final ASN1Encodable asn1Encodable) throws IOException {
        this(asn1Encodable.toASN1Primitive().getEncoded("DER"), 0);
    }
    
    public BERBitString(final ASN1BitString[] array) {
        this(array, 1000);
    }
    
    public BERBitString(final ASN1BitString[] elements, final int segmentLimit) {
        super(flattenBitStrings(elements), false);
        this.elements = elements;
        this.segmentLimit = segmentLimit;
    }
    
    BERBitString(final byte[] array, final boolean b) {
        super(array, b);
        this.elements = null;
        this.segmentLimit = 1000;
    }
    
    @Override
    boolean encodeConstructed() {
        return null != this.elements || this.contents.length > this.segmentLimit;
    }
    
    @Override
    int encodedLength(final boolean b) throws IOException {
        if (!this.encodeConstructed()) {
            return DLBitString.encodedLength(b, this.contents.length);
        }
        int n = b ? 4 : 3;
        if (null != this.elements) {
            for (int i = 0; i < this.elements.length; ++i) {
                n += this.elements[i].encodedLength(true);
            }
        }
        else if (this.contents.length >= 2) {
            final int n2 = (this.contents.length - 2) / (this.segmentLimit - 1);
            n = n + n2 * DLBitString.encodedLength(true, this.segmentLimit) + DLBitString.encodedLength(true, this.contents.length - n2 * (this.segmentLimit - 1));
        }
        return n;
    }
    
    @Override
    void encode(final ASN1OutputStream asn1OutputStream, final boolean b) throws IOException {
        if (!this.encodeConstructed()) {
            DLBitString.encode(asn1OutputStream, b, this.contents, 0, this.contents.length);
            return;
        }
        asn1OutputStream.writeIdentifier(b, 35);
        asn1OutputStream.write(128);
        if (null != this.elements) {
            asn1OutputStream.writePrimitives(this.elements);
        }
        else if (this.contents.length >= 2) {
            final byte b2 = this.contents[0];
            final int length = this.contents.length;
            int i = length - 1;
            for (int n = this.segmentLimit - 1; i > n; i -= n) {
                DLBitString.encode(asn1OutputStream, true, (byte)0, this.contents, length - i, n);
            }
            DLBitString.encode(asn1OutputStream, true, b2, this.contents, length - i, i);
        }
        asn1OutputStream.write(0);
        asn1OutputStream.write(0);
    }
}
