/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm.schema.model;

import java.util.ArrayList;
import java.util.List;

/**
 * <p><b>Purpose</b>: Class to represent a Choice in a Schema
 */
public class Choice extends TypeDefParticle implements NestedParticle {
    protected java.util.List orderedElements;

    public Choice() {
        orderedElements = new ArrayList();
    }

    public java.util.List getOrderedElements() {
        return orderedElements;
    }

    public void setOrderedElements(java.util.List newElements) {
        orderedElements = newElements;
        for (int i = 0; i < newElements.size(); i++) {
            Object next = newElements.get(i);
            if (next instanceof Element) {
                getElements().add((Element) next);
            }
        }
    }

    @Override
    public void setSequences(List<Sequence> sequences) {
        if ((sequences != null) && (sequences.size() > 0)) {
            for (int i = 0; i < sequences.size(); i++) {
                sequences.get(i).setOwner(this);
            }

            orderedElements.addAll(sequences);
        }
    }

    @Override
    public void setChoices(List<Choice> choices) {
        if ((choices != null) && (choices.size() > 0)) {
            for (int i = 0; i < choices.size(); i++) {
                choices.get(i).setOwner(this);
            }

            orderedElements.addAll(choices);
        }
    }

    public void setNestedParticles(java.util.List<NestedParticle> nestedParticles) {
        for (int i = 0; i < nestedParticles.size(); i++) {
            NestedParticle next = nestedParticles.get(i);
            if (next instanceof Choice) {
                addChoice((Choice)next);
            } else if (next instanceof Sequence) {
                addSequence((Sequence)next);
            }
        }
    }

    @Override
    public void addSequence(Sequence sequence) {
        orderedElements.add(sequence);
        sequence.setOwner(this);
    }

    @Override
    public void addChoice(Choice choice) {
        orderedElements.add(choice);
        choice.setOwner(this);
    }

    @Override
    public void addElement(Element elem) {
        orderedElements.add(elem);
        getElements().add(elem);
    }

    @Override
    public void addAny(Any any) {
        orderedElements.add(any);

    }

    @Override
    public void setElements(List<Element> elements) {
        orderedElements.addAll(elements);
        getElements().addAll(elements);
    }

    @Override
    public void setAnys(List<Any> anys) {
        orderedElements.addAll(anys);
    }

    @Override
    public boolean hasAny() {
        for (int i = 0; i < orderedElements.size(); i++) {
            Object next = orderedElements.get(i);
            if (next instanceof Any) {
                return true;
            }
        }
        return false;

    }

    @Override
    public boolean isEmpty() {
        return !(orderedElements.size() > 0);
    }

    @Override
    public void setOwner(TypeDefParticleOwner owner) {
        super.setOwner(owner);
        for (int i = 0; i < orderedElements.size(); i++) {
            Object next = orderedElements.get(i);
            if (next instanceof TypeDefParticle) {
                ((TypeDefParticle)next).setOwner(this);
            }
        }
    }
}
