//
// See the file LICENSE for redistribution information.
//
// Copyright (c) 2002-2003
//	Sleepycat Software.  All rights reserved.
//

static const char revid[] = "$Id: SyntaxManager.cpp,v 1.10 2003/10/31 17:57:37 gmf Exp $";

#include "dbxml_config.h"
#include "dbxml/XmlPortability.hpp"
#include "SyntaxManager.hpp"

using namespace DbXml;

static SyntaxManager *syntaxManager = 0;
static void initSyntaxManager();

// GMF: remote static initializer/class when there is a single, global 
// initialization function.  initSyntaxManager MUST be called in
// a thread-safe manner
class _initSyntax {
public:
  _initSyntax() { initSyntaxManager(); }
};
static _initSyntax  init_syn;

static void initSyntaxManager()
{
	if (syntaxManager == 0) {
		//
		// Register Default Syntaxes
		//
		syntaxManager = new SyntaxManager();
		syntaxManager->registerSyntax(*(new NoneSyntax));
		syntaxManager->registerSyntax(*(new StringSyntax));
		syntaxManager->registerSyntax(*(new NumberSyntax));
	}
}

SyntaxManager *SyntaxManager::getInstance()
{
	if (syntaxManager == 0) {
		initSyntaxManager();
	}
	return syntaxManager;
}

SyntaxManager::SyntaxManager()
{}

SyntaxManager::~SyntaxManager()
{}

void SyntaxManager::registerSyntax(const Syntax &syntax)
{
	if ((int)sv_.size() <= syntax.getType()) {
		sv_.resize(syntax.getType() + 1);
	}
	sv_[syntax.getType()] = &syntax;
}

const Syntax *SyntaxManager::getSyntax(const std::string &name) const
{
	int i = findSyntax(name);
	return (i == -1 ? 0 : sv_[i]);
}

const Syntax *SyntaxManager::getNextSyntax(int &i) const
{
	const Syntax *syntax = 0;
	if (i > -1) {
		while (i < (int)sv_.size() && syntax == 0) {
			if (sv_[i] != 0) {
				syntax = sv_[i];
			}
			++i;
		}
		if (i == (int)sv_.size()) {
			i = -1;
		}
	}
	return syntax;
}

const Syntax *SyntaxManager::getSyntax(Syntax::Type type) const
{
	return sv_[type];
}

int SyntaxManager::findSyntax(const std::string &name) const
{
	for (unsigned int i = 0;i < sv_.size();++i) {
		if (sv_[i] != 0) {
			if (name.compare(sv_[i]->getName()) == 0) {
				return i;
			}
		}
	}
	return -1;
}

size_t SyntaxManager::size() const
{
	return sv_.size();
}
