//------------------------------------------------------------------------------
// addSymbol() - adds a symbol to our array list;
// -- return the symbol's index; range [ 1 .. getMaxSymbols() ]
//    or zero if not added.
//------------------------------------------------------------------------------
int SymbolLoader::addSymbol(const int nType, const char* const id, int specName)
{
    int idx = 0;

    if (templates != 0) {

        // Find the graphic template for this type symbol, and make
        // sure that the template is a BasicGL::Graphic, since it
        // will be use as the symbol's graphical component.
        Basic::Pair* tpair = templates->getPosition(nType);
        if (tpair != 0) {
            BasicGL::Graphic* tg = dynamic_cast<BasicGL::Graphic*>(tpair->object());
            if (tg != 0) {

                // Find an empty symbol slot in our master symbol table
                for (int i = 0; i < MAX_SYMBOLS && idx == 0; i++) {
                    if ( symbols[i] == 0 ) {

                        // Create a new SlSymbol object to manage this symbol.
                        symbols[i] = symbolFactory();

                        // Clone the graphic template and set it as the
                        // symbol's graphical component.
                        Basic::Pair* newPair = tpair->clone();
                        BasicGL::Graphic* newGraph = (BasicGL::Graphic*)(newPair->object());

                        // Set the new graphical component's select name
                        GLuint mySelName = 0;
                        if (specName > 0) mySelName = specName;
                        else mySelName = BasicGL::Graphic::getNewSelectName();
                        newGraph->setSelectName(mySelName);

                        // Add the symbol's graphical component to our component list.
                        {
                            Basic::PairStream* comp = getComponents();
                            Basic::Component::processComponents(comp, typeid(BasicGL::Graphic), newPair);
                            if (comp != 0) comp->unref();
                        }

                        // Set the symbol's graphical component pointer
                        symbols[i]->setSymbolPair( newPair );
                        newPair->unref(); // symbol[i] now owns it.

                        // Set the symbol's type and ID.
                        symbols[i]->setType( nType );
                        symbols[i]->setId( id );

                        // And this is the new symbol's index
                        idx = (i + 1);
                    }
                }
            }
        }
    }

    return idx;
}
//------------------------------------------------------------------------------
// setSymbolType() - change an existing symbol type to another type
//------------------------------------------------------------------------------
bool SymbolLoader::setSymbolType(const int idx, const int nType)
{
    bool ok = false;

    // Find the symbol
    if (idx >= 1 && idx <= MAX_SYMBOLS) {
        const int i = (idx - 1);
        if (symbols[i] != 0) {

            // Find the graphic template for this type symbol, and make
            // sure that the template is a BasicGL::Graphic, since it
            // will be use as the symbol's graphical component.
            if (templates != 0) {
                Basic::Pair* tpair = templates->getPosition(nType);
                if (tpair != 0) {
                    BasicGL::Graphic* tg = dynamic_cast<BasicGL::Graphic*>(tpair->object());
                    if (tg != 0) {

                        // Get the symbol's old graphical component
                        Basic::Pair* oldPair = (Basic::Pair*) symbols[i]->getSymbolPair();
                        BasicGL::Graphic* oldG = (BasicGL::Graphic*) (oldPair->object());

                        // Clone the new graphical component from the template
                        Basic::Pair* newPair = tpair->clone();

                        // Set the new graphical component's select name using the old's
                        BasicGL::Graphic* newGraph = (BasicGL::Graphic*) newPair->object();
                        GLuint mySelName = oldG->getSelectName();
                        newGraph->setSelectName(mySelName);

                        // Add the new and remove the old components from our subcomponent list
                        {
                            Basic::PairStream* comp = getComponents();
                            Basic::Component::processComponents(comp, typeid(BasicGL::Graphic), newPair, oldG);
                            if (comp != 0) comp->unref();
                        }

                        // Set the symbol's graphical component pointer
                        symbols[i]->setSymbolPair( newPair );
                        newPair->unref(); // symbol[i] now owns it.

                        // Set new type
                        symbols[i]->setType( nType );

                        ok = true;
                    }

                }
            }
        }

    }
    return ok;
}
//------------------------------------------------------------------------------
// Update the symbol's select name
//------------------------------------------------------------------------------
bool SymbolLoader::updateSymbolSelectName(const int idx, const int newSN)
{
    bool ok = false;
    if (idx >= 1 && idx <= MAX_SYMBOLS) {
        const int i = (idx - 1);
        if (symbols[i] != 0) {

            Basic::Pair* pair = (Basic::Pair*)symbols[i]->getSymbolPair();
            if (pair != 0) {
                BasicGL::Graphic* graphic = (BasicGL::Graphic*)(pair->object());
                if (graphic != 0) graphic->setSelectName(newSN);
            }
            ok = true;

        }
    }
    return ok;
}