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

package org.bouncycastle.oer;

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;
import java.util.Map;
import org.bouncycastle.asn1.ASN1Encodable;
import java.math.BigInteger;
import java.util.List;

public class Element
{
    private final OERDefinition.BaseType baseType;
    private final List<Element> children;
    private final boolean explicit;
    private final String label;
    private final BigInteger lowerBound;
    private final BigInteger upperBound;
    private final boolean extensionsInDefinition;
    private final BigInteger enumValue;
    private final ASN1Encodable defaultValue;
    private final Switch aSwitch;
    private final boolean defaultValuesInChildren;
    private List<Element> optionalChildrenInOrder;
    private List<ASN1Encodable> validSwitchValues;
    private final ElementSupplier elementSupplier;
    private final boolean mayRecurse;
    private final String typeName;
    private final Map<String, ElementSupplier> supplierMap;
    private Element parent;
    private final int optionals;
    private final int block;
    
    public Element(final OERDefinition.BaseType baseType, final List<Element> children, final boolean explicit, final String label, final BigInteger lowerBound, final BigInteger upperBound, final boolean extensionsInDefinition, final BigInteger enumValue, final ASN1Encodable defaultValue, final Switch aSwitch, final List<ASN1Encodable> list, final ElementSupplier elementSupplier, final boolean mayRecurse, final String typeName, final Map<String, ElementSupplier> supplierMap, final int block, final int optionals, final boolean defaultValuesInChildren) {
        this.baseType = baseType;
        this.children = children;
        this.explicit = explicit;
        this.label = label;
        this.lowerBound = lowerBound;
        this.upperBound = upperBound;
        this.extensionsInDefinition = extensionsInDefinition;
        this.enumValue = enumValue;
        this.defaultValue = defaultValue;
        this.aSwitch = aSwitch;
        this.validSwitchValues = ((list != null) ? Collections.unmodifiableList((List<? extends ASN1Encodable>)list) : null);
        this.elementSupplier = elementSupplier;
        this.mayRecurse = mayRecurse;
        this.typeName = typeName;
        this.block = block;
        this.optionals = optionals;
        this.defaultValuesInChildren = defaultValuesInChildren;
        if (supplierMap == null) {
            this.supplierMap = Collections.emptyMap();
        }
        else {
            this.supplierMap = supplierMap;
        }
        final Iterator<Element> iterator = children.iterator();
        while (iterator.hasNext()) {
            iterator.next().parent = this;
        }
    }
    
    public Element(final Element element, final Element parent) {
        this.baseType = element.baseType;
        this.children = new ArrayList<Element>(element.children);
        this.explicit = element.explicit;
        this.label = element.label;
        this.lowerBound = element.lowerBound;
        this.upperBound = element.upperBound;
        this.extensionsInDefinition = element.extensionsInDefinition;
        this.enumValue = element.enumValue;
        this.defaultValue = element.defaultValue;
        this.aSwitch = element.aSwitch;
        this.validSwitchValues = element.validSwitchValues;
        this.elementSupplier = element.elementSupplier;
        this.mayRecurse = element.mayRecurse;
        this.typeName = element.typeName;
        this.supplierMap = element.supplierMap;
        this.parent = parent;
        this.block = element.block;
        this.optionals = element.optionals;
        this.defaultValuesInChildren = element.defaultValuesInChildren;
        final Iterator<Element> iterator = this.children.iterator();
        while (iterator.hasNext()) {
            iterator.next().parent = this;
        }
    }
    
    public static Element expandDeferredDefinition(Element build, final Element element) {
        if (build.elementSupplier != null) {
            build = build.elementSupplier.build();
            if (build.getParent() != element) {
                build = new Element(build, element);
            }
        }
        return build;
    }
    
    public String rangeExpression() {
        return "(" + ((this.getLowerBound() != null) ? this.getLowerBound().toString() : "MIN") + " ... " + ((this.getUpperBound() != null) ? this.getUpperBound().toString() : "MAX") + ")";
    }
    
    public String appendLabel(final String str) {
        return "[" + ((this.getLabel() == null) ? "" : this.getLabel()) + (this.isExplicit() ? " (E)" : "") + "] " + str;
    }
    
    public List<Element> optionalOrDefaultChildrenInOrder() {
        synchronized (this) {
            if (this.getOptionalChildrenInOrder() == null) {
                final ArrayList list = new ArrayList();
                for (final Element e : this.getChildren()) {
                    if (!e.isExplicit() || e.getDefaultValue() != null) {
                        list.add(e);
                    }
                }
                this.optionalChildrenInOrder = (List<Element>)Collections.unmodifiableList((List<?>)list);
            }
            return this.getOptionalChildrenInOrder();
        }
    }
    
    public boolean isUnbounded() {
        return this.getUpperBound() == null && this.getLowerBound() == null;
    }
    
    public boolean isLowerRangeZero() {
        return BigInteger.ZERO.equals(this.getLowerBound());
    }
    
    public boolean isUnsignedWithRange() {
        return this.isLowerRangeZero() && this.getUpperBound() != null && BigInteger.ZERO.compareTo(this.getUpperBound()) < 0;
    }
    
    public boolean canBeNegative() {
        return this.getLowerBound() != null && BigInteger.ZERO.compareTo(this.getLowerBound()) > 0;
    }
    
    public int intBytesForRange() {
        if (this.getLowerBound() != null && this.getUpperBound() != null) {
            if (BigInteger.ZERO.equals(this.getLowerBound())) {
                for (int i = 0, n = 1; i < OERDefinition.uIntMax.length; ++i, n *= 2) {
                    if (this.getUpperBound().compareTo(OERDefinition.uIntMax[i]) < 0) {
                        return n;
                    }
                }
            }
            else {
                for (int j = 0, n2 = 1; j < OERDefinition.sIntRange.length; ++j, n2 *= 2) {
                    if (this.getLowerBound().compareTo(OERDefinition.sIntRange[j][0]) >= 0 && this.getUpperBound().compareTo(OERDefinition.sIntRange[j][1]) < 0) {
                        return -n2;
                    }
                }
            }
        }
        return 0;
    }
    
    public boolean hasPopulatedExtension() {
        return this.extensionsInDefinition;
    }
    
    public boolean hasDefaultChildren() {
        return this.defaultValuesInChildren;
    }
    
    public ASN1Encodable getDefaultValue() {
        return this.defaultValue;
    }
    
    public Element getFirstChid() {
        return this.getChildren().get(0);
    }
    
    public boolean isFixedLength() {
        return this.getLowerBound() != null && this.getLowerBound().equals(this.getUpperBound());
    }
    
    @Override
    public String toString() {
        return "[" + this.typeName + " " + this.baseType.name() + " '" + this.getLabel() + "']";
    }
    
    public OERDefinition.BaseType getBaseType() {
        return this.baseType;
    }
    
    public List<Element> getChildren() {
        return this.children;
    }
    
    public boolean isExplicit() {
        return this.explicit;
    }
    
    public String getLabel() {
        return this.label;
    }
    
    public BigInteger getLowerBound() {
        return this.lowerBound;
    }
    
    public BigInteger getUpperBound() {
        return this.upperBound;
    }
    
    public boolean isExtensionsInDefinition() {
        return this.extensionsInDefinition;
    }
    
    public BigInteger getEnumValue() {
        return this.enumValue;
    }
    
    public Switch getaSwitch() {
        return this.aSwitch;
    }
    
    public List<Element> getOptionalChildrenInOrder() {
        return this.optionalChildrenInOrder;
    }
    
    public List<ASN1Encodable> getValidSwitchValues() {
        return this.validSwitchValues;
    }
    
    public ElementSupplier getElementSupplier() {
        return this.elementSupplier;
    }
    
    public boolean isMayRecurse() {
        return this.mayRecurse;
    }
    
    public String getTypeName() {
        return this.typeName;
    }
    
    public int getOptionals() {
        return this.optionals;
    }
    
    public int getBlock() {
        return this.block;
    }
    
    public String getDerivedTypeName() {
        if (this.typeName != null) {
            return this.typeName;
        }
        return this.baseType.name();
    }
    
    public ElementSupplier resolveSupplier() {
        if (this.supplierMap.containsKey(this.label)) {
            return this.supplierMap.get(this.label);
        }
        if (this.parent != null) {
            return this.parent.resolveSupplier(this.label);
        }
        throw new IllegalStateException("unable to resolve: " + this.label);
    }
    
    protected ElementSupplier resolveSupplier(String string) {
        string = this.label + "." + string;
        if (this.supplierMap.containsKey(string)) {
            return this.supplierMap.get(string);
        }
        if (this.parent != null) {
            return this.parent.resolveSupplier(string);
        }
        throw new IllegalStateException("unable to resolve: " + string);
    }
    
    public Element getParent() {
        return this.parent;
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        final Element element = (Element)o;
        if (this.explicit != element.explicit) {
            return false;
        }
        if (this.extensionsInDefinition != element.extensionsInDefinition) {
            return false;
        }
        if (this.defaultValuesInChildren != element.defaultValuesInChildren) {
            return false;
        }
        if (this.mayRecurse != element.mayRecurse) {
            return false;
        }
        if (this.optionals != element.optionals) {
            return false;
        }
        if (this.block != element.block) {
            return false;
        }
        if (this.baseType != element.baseType) {
            return false;
        }
        Label_0155: {
            if (this.children != null) {
                if (this.children.equals(element.children)) {
                    break Label_0155;
                }
            }
            else if (element.children == null) {
                break Label_0155;
            }
            return false;
        }
        Label_0188: {
            if (this.label != null) {
                if (this.label.equals(element.label)) {
                    break Label_0188;
                }
            }
            else if (element.label == null) {
                break Label_0188;
            }
            return false;
        }
        Label_0221: {
            if (this.lowerBound != null) {
                if (this.lowerBound.equals(element.lowerBound)) {
                    break Label_0221;
                }
            }
            else if (element.lowerBound == null) {
                break Label_0221;
            }
            return false;
        }
        Label_0254: {
            if (this.upperBound != null) {
                if (this.upperBound.equals(element.upperBound)) {
                    break Label_0254;
                }
            }
            else if (element.upperBound == null) {
                break Label_0254;
            }
            return false;
        }
        Label_0287: {
            if (this.enumValue != null) {
                if (this.enumValue.equals(element.enumValue)) {
                    break Label_0287;
                }
            }
            else if (element.enumValue == null) {
                break Label_0287;
            }
            return false;
        }
        Label_0322: {
            if (this.defaultValue != null) {
                if (this.defaultValue.equals(element.defaultValue)) {
                    break Label_0322;
                }
            }
            else if (element.defaultValue == null) {
                break Label_0322;
            }
            return false;
        }
        Label_0357: {
            if (this.aSwitch != null) {
                if (this.aSwitch.equals(element.aSwitch)) {
                    break Label_0357;
                }
            }
            else if (element.aSwitch == null) {
                break Label_0357;
            }
            return false;
        }
        Label_0392: {
            if (this.optionalChildrenInOrder != null) {
                if (this.optionalChildrenInOrder.equals(element.optionalChildrenInOrder)) {
                    break Label_0392;
                }
            }
            else if (element.optionalChildrenInOrder == null) {
                break Label_0392;
            }
            return false;
        }
        Label_0427: {
            if (this.validSwitchValues != null) {
                if (this.validSwitchValues.equals(element.validSwitchValues)) {
                    break Label_0427;
                }
            }
            else if (element.validSwitchValues == null) {
                break Label_0427;
            }
            return false;
        }
        Label_0462: {
            if (this.elementSupplier != null) {
                if (this.elementSupplier.equals(element.elementSupplier)) {
                    break Label_0462;
                }
            }
            else if (element.elementSupplier == null) {
                break Label_0462;
            }
            return false;
        }
        if (this.typeName != null) {
            if (this.typeName.equals(element.typeName)) {
                return (this.supplierMap != null) ? (!this.supplierMap.equals(element.supplierMap)) : (element.supplierMap != null);
            }
        }
        else if (element.typeName == null) {
            return (this.supplierMap != null) ? (!this.supplierMap.equals(element.supplierMap)) : (element.supplierMap != null);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return 31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * (31 * ((this.baseType != null) ? this.baseType.hashCode() : 0) + ((this.children != null) ? this.children.hashCode() : 0)) + (this.explicit ? 1 : 0)) + ((this.label != null) ? this.label.hashCode() : 0)) + ((this.lowerBound != null) ? this.lowerBound.hashCode() : 0)) + ((this.upperBound != null) ? this.upperBound.hashCode() : 0)) + (this.extensionsInDefinition ? 1 : 0)) + ((this.enumValue != null) ? this.enumValue.hashCode() : 0)) + ((this.defaultValue != null) ? this.defaultValue.hashCode() : 0)) + ((this.aSwitch != null) ? this.aSwitch.hashCode() : 0)) + (this.defaultValuesInChildren ? 1 : 0)) + ((this.optionalChildrenInOrder != null) ? this.optionalChildrenInOrder.hashCode() : 0)) + ((this.validSwitchValues != null) ? this.validSwitchValues.hashCode() : 0)) + ((this.elementSupplier != null) ? this.elementSupplier.hashCode() : 0)) + (this.mayRecurse ? 1 : 0)) + ((this.typeName != null) ? this.typeName.hashCode() : 0)) + ((this.supplierMap != null) ? this.supplierMap.hashCode() : 0)) + this.optionals) + this.block;
    }
}
