// BGDNetNDSFunction.cpp: implementation of the NDSFunction class.
//
//////////////////////////////////////////////////////////////////////

#include "BGDNetPch.h"

#include "BGDNetNDSFunction.h"

#include "BGDNetContext.h"
#include "BGDNetNDSObject.h"

namespace BGDNet
{

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

NDSFunction::NDSFunction() :
	m_initialized(false)
{

}

NDSFunction::~NDSFunction()
{

}

bool NDSFunction::init(const char* prjName,
												const int fNum,
												const char* orgName)
{
	if(fNum <= 0)
	{
		return false;
	}

	if(!NWIsDSAuthenticated())
	{
		//puts("Must authenticate to NDS.\n");
		return false;
	}
 
	try
	{
		Context ctx(orgName);
		ctx.dckFlags(ctx.dckFlags() | DCV_CANONICALIZE_NAMES);

		NDSObject programs(ctx, "OU=Programs");

		NDSObjects collect;
		programs.getSubordinates(&collect);

		bool found = false;
		for(int i = 0; i < collect.size(); i++)
		{
			String objname;
			collect[i]->attr("CN", &objname);
			if (0 == stricmp(objname.ptr(), prjName))
			{
				//this program found
				found = true;
				break;
			}
		}
		
		if (!found)
		{
			//printf("Program %s NOT FOUND in tree. Usage not allowed :(", prjName);
			return false;
		}

		NDSObject& obj = *collect[i];

		NDSObject group(ctx, obj.dn());
		
		//Collection<String> formulas;
		String formula;
		if(!group.attr("Belgiprodor IT Office", &formula, fNum - 1))
		{
			return false;
		}

		if(formula.length() == 0)
		{
			return false;
		}
		
		/*String description;
		if(!group.attr("Description", &description) ||
				description.length() == 0)
		{
			//printf("Function %s was FOUND in program group, but usage not allowed :(\n", prjName);
			return false;
		}

		const char* s = description.ptr();
		char* str = new char[description.length()];
		
		//поле Description содержать символьные описания функций,
		//разделенные переводами строк.
		i = 0;
		while (true)
		{
			if(strlen(s) && sscanf(s, "%[^\x0D\x0A\x00]", str))
			{
				i++;
				
				if(i == fNum)
				{
					break;
				}
				else
				{
					s += strlen(str);
				}
			}
			else if (*s != 0)
			{
				s++;
			}
			else
			{
				break;
			}
		}

		if(i < fNum)
		{
			return false;
		}

		m_initialized = m_parser.assign(str);

		delete[] str;*/

		m_initialized = m_parser.assign(formula.ptr());

		return m_initialized;
	}
	catch(Exception e)
	{
		printf("NDS Error Code %d: %s\n\n", e.code(), e.what());
		return false;
	}
}

bool NDSFunction::evaluate (double* pVals, double* pRet)
{
	if(m_initialized)
	{
		return m_parser.evaluate(pVals, pRet);
	}

	return false;
}

} // namespace BGDNet