/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Id: ContentSpecNode.cpp 568078 2007-08-21 11:43:25Z amassari $
 */


// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  ContentSpecNode: Copy Constructor
//
//  Note: this copy constructor has dependency on various get*() methods
//        and shall be placed after those method's declaration.
//        aka inline function compilation error on AIX 4.2, xlC 3 r ev.1
// ---------------------------------------------------------------------------

ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :
    XSerializable(toCopy)
    , XMemory(toCopy)
    , fMemoryManager(toCopy.fMemoryManager)
    , fElement(0)
    , fElementDecl(toCopy.fElementDecl)
    , fFirst(0)
    , fSecond(0)
    , fType(toCopy.fType)
    , fAdoptFirst(true)
    , fAdoptSecond(true)
    , fMinOccurs(toCopy.fMinOccurs)
    , fMaxOccurs(toCopy.fMaxOccurs)
{
    const QName* tempElement = toCopy.getElement();
    if (tempElement)
        fElement = new (fMemoryManager) QName(*tempElement);

    const ContentSpecNode *tmp = toCopy.getFirst();
    if (tmp)
        fFirst = new (fMemoryManager) ContentSpecNode(*tmp);

    tmp = toCopy.getSecond();
    if (tmp)
        fSecond = new (fMemoryManager) ContentSpecNode(*tmp);
}

// ---------------------------------------------------------------------------
//  Local methods
// ---------------------------------------------------------------------------
static void formatNode( const   ContentSpecNode* const      curNode
                        , const ContentSpecNode::NodeTypes  parentType
                        ,       XMLBuffer&                  bufToFill)
{
    if (!curNode)
        return;

    const ContentSpecNode* first = curNode->getFirst();
    const ContentSpecNode* second = curNode->getSecond();
    const ContentSpecNode::NodeTypes curType = curNode->getType();

    // Get the type of the first node
    const ContentSpecNode::NodeTypes firstType = first ?
                                                 first->getType() :
                                                 ContentSpecNode::Leaf;

    // Calculate the parens flag for the rep nodes
    bool doRepParens = false;
    if (((firstType != ContentSpecNode::Leaf)
            && (parentType != ContentSpecNode::UnknownType))
    ||  ((firstType == ContentSpecNode::Leaf)
            && (parentType == ContentSpecNode::UnknownType)))
    {
        doRepParens = true;
    }

    // Now handle our type
    switch(curType & 0x0f)
    {
        case ContentSpecNode::Leaf :
            if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
                bufToFill.append(XMLElementDecl::fgPCDataElemName);
            else
                bufToFill.append(curNode->getElement()->getRawName());
            break;

        case ContentSpecNode::ZeroOrOne :
            if (doRepParens)
                bufToFill.append(chOpenParen);
            formatNode(first, curType, bufToFill);
            if (doRepParens)
                bufToFill.append(chCloseParen);
            bufToFill.append(chQuestion);
            break;

        case ContentSpecNode::ZeroOrMore :
            if (doRepParens)
                bufToFill.append(chOpenParen);
            formatNode(first, curType, bufToFill);
            if (doRepParens)
                bufToFill.append(chCloseParen);
            bufToFill.append(chAsterisk);
            break;

        case ContentSpecNode::OneOrMore :
            if (doRepParens)
                bufToFill.append(chOpenParen);
            formatNode(first, curType, bufToFill);
            if (doRepParens)
                bufToFill.append(chCloseParen);
            bufToFill.append(chPlus);
            break;

        case ContentSpecNode::Choice :
            if (parentType != curType)
                bufToFill.append(chOpenParen);
            formatNode(first, curType, bufToFill);
            bufToFill.append(chPipe);
            formatNode(second, curType, bufToFill);
            if (parentType != curType)
                bufToFill.append(chCloseParen);
            break;

        case ContentSpecNode::Sequence :
            if (parentType != curType)
                bufToFill.append(chOpenParen);
            formatNode(first, curType, bufToFill);
            bufToFill.append(chComma);
            formatNode(second, curType, bufToFill);
            if (parentType != curType)
                bufToFill.append(chCloseParen);
            break;

        case ContentSpecNode::All :
            if (parentType != curType)
			{
                bufToFill.append(chLatin_A);
                bufToFill.append(chLatin_l);
                bufToFill.append(chLatin_l);
                bufToFill.append(chOpenParen);
			}
            formatNode(first, curType, bufToFill);
            bufToFill.append(chComma);
            formatNode(second, curType, bufToFill);
            if (parentType != curType)
                bufToFill.append(chCloseParen);
            break;
    }
}


// ---------------------------------------------------------------------------
//  ContentSpecNode: Miscellaneous
// ---------------------------------------------------------------------------
void ContentSpecNode::formatSpec(XMLBuffer&      bufToFill) const
{
    // Clean out the buffer first
    bufToFill.reset();

    if (fType == ContentSpecNode::Leaf)
        bufToFill.append(chOpenParen);
    formatNode
    (
        this
        , UnknownType
        , bufToFill
    );
    if (fType == ContentSpecNode::Leaf)
        bufToFill.append(chCloseParen);
}

int ContentSpecNode::getMinTotalRange() const {

    int min = fMinOccurs;

    if ((fType & 0x0f) == ContentSpecNode::Sequence
        || fType == ContentSpecNode::All
        || (fType & 0x0f) == ContentSpecNode::Choice) {

        int minFirst = fFirst->getMinTotalRange();

        if (fSecond) {

            int minSecond = fSecond->getMinTotalRange();

            if ((fType & 0x0f) == ContentSpecNode::Choice) {
                min = min * ((minFirst < minSecond)? minFirst : minSecond);
            }
            else {
                min = min * (minFirst + minSecond);
            }
        }
        else
            min = min * minFirst;
    }

    return min;
}

int ContentSpecNode::getMaxTotalRange() const {

    int max = fMaxOccurs;

    if (max == SchemaSymbols::XSD_UNBOUNDED) {
         return SchemaSymbols::XSD_UNBOUNDED;
    }

    if ((fType & 0x0f) == ContentSpecNode::Sequence
        || fType == ContentSpecNode::All
        || (fType & 0x0f) == ContentSpecNode::Choice) {

        int maxFirst = fFirst->getMaxTotalRange();

        if (maxFirst == SchemaSymbols::XSD_UNBOUNDED) {
             return SchemaSymbols::XSD_UNBOUNDED;
        }

        if (fSecond) {

            int maxSecond = fSecond->getMaxTotalRange();

            if (maxSecond == SchemaSymbols::XSD_UNBOUNDED) {
                return SchemaSymbols::XSD_UNBOUNDED;
            }
            else {

                if ((fType & 0x0f) == ContentSpecNode::Choice) {
                    max = max * (maxFirst > maxSecond) ? maxFirst : maxSecond;
                }
                else {
                    max = max * (maxFirst + maxSecond);
                }
            }
        }
        else {
            max = max * maxFirst;
        }
    }

    return max;
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(ContentSpecNode)

void ContentSpecNode::serialize(XSerializeEngine& serEng)
{
    /***
     *  Since fElement, fFirst, fSecond are NOT created by the default 
     *  constructor, we need to create them dynamically.
     ***/

    if (serEng.isStoring())
    {
        serEng<<fElement;
        XMLElementDecl::storeElementDecl(serEng, fElementDecl);
        serEng<<fFirst;
        serEng<<fSecond;

        serEng<<(int)fType;
        serEng<<fAdoptFirst;
        serEng<<fAdoptSecond;
        serEng<<fMinOccurs;
        serEng<<fMaxOccurs;
    }
    else
    {
        serEng>>fElement;
        fElementDecl = XMLElementDecl::loadElementDecl(serEng);
        serEng>>fFirst;
        serEng>>fSecond;

        int type;
        serEng>>type;
        fType = (NodeTypes)type;

        serEng>>fAdoptFirst;
        serEng>>fAdoptSecond;
        serEng>>fMinOccurs;
        serEng>>fMaxOccurs;
    }

}

XERCES_CPP_NAMESPACE_END

