#include "maComClasses.h"
#pragma hdrstop

int printfBufLen;
//**********************************************************************************************************
//**********************************************************************************************************

HRESULT maLastError=0;

HRESULT maGetLastError(){
	HRESULT r=maLastError;
	maLastError=0;
	return r;
}

double CmaCell::default_double=0.0;
maString CmaCell::default_string=0;


HRESULT CmaComponent::GetLastError() const{
	HRESULT r=maLastError;
	maLastError=0;
	return r;
}


//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaCell                                            ----
//----                                                                        ----
//--------------------------------------------------------------------------------

CmaCell CmaCell::operator[] (long i){
	ImaList* l;	
	if(!intf) return *this;
	if(Type()==MA_LIST) {
		intf->GetAsComponent(MA_LIST,(ImaComponent**)&l);
	}else{
		l=maListNewInstance();
		intf->SetAsComponent(MA_LIST,l);
	}
	ImaCell* r;
	if(l){ 
		l->CreateCells(i);
		l->GetCell(i,&r);
		CmaCell c(r);
		if(r) r->Release();
		l->Release();  
		return c;
	}
	return *this;
}

CmaCell CmaCell::operator[] (maString i){
	if(!intf) return *this;
	ImaList* l;	
	if(Type()==MA_LIST) {
		intf->GetAsComponent(MA_LIST,(ImaComponent**)&l);
	}else{
		l=maListNewInstance();
		intf->SetAsComponent(MA_LIST,l);
		
	}
	ImaCell* r;
	if(l){ 
		l->FindCreateCell(i,&r);
		CmaCell c(r);
		if(r) r->Release();
		l->Release();
		return c;
	}
	return *this;
}

int CmaCell::Size() const{
	ImaList* l;	
	int i;
	if(Type()==MA_LIST) {
		intf->GetAsComponent(MA_LIST,(ImaComponent**)&l);
		l->GetSize(&i);
		l->Release();

		return i;
	}
	return 0;
}

bool  CmaCell::IsEmpty()  const{
  if(intf)
	return intf->IsEmpty()!=MA_FALSE;
  return true;
}



CmaCell::operator int (){
	int r=(int)default_double;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsLong(&r);
		else
		  intf->SetAsLong(r);
	}
	return r;
}
CmaCell::operator boolean (){
	boolean r=(boolean)default_double;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsBoolean(&r);
		else
		  intf->SetAsBoolean(r);
	}
	return r;
}

CmaCell::operator double (){
	double r=default_double;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsDouble(&r);
		else
		  intf->SetAsDouble(r);
	}
	return r;
}
maString CmaCell::AsString(){
	maString r=default_string;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsString(&r);
		else 
		  intf->SetAsString(r);
	}
	return r;
}


int CmaCell::operator= (int rvalue){
	if(intf) intf->SetAsLong(rvalue);
	return rvalue;
}
boolean CmaCell::operator= (boolean rvalue){
	if(intf) intf->SetAsBoolean(rvalue);
	return rvalue;
}

double CmaCell::operator= (double rvalue){
	if(intf) intf->SetAsDouble(rvalue);
	return rvalue;
}


maString CmaCell::operator= (maString rvalue){
	if(intf) intf->SetAsString(rvalue);
	return rvalue;
}

CmaCell& CmaCell::Default (double rvalue){
	default_double=rvalue;
	return *this;
}
CmaCell& CmaCell::Default (maString rvalue){
	default_string=rvalue;
	return *this;
}



CmaMatrix& CmaCell::operator= (CmaMatrix& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_MATRIX,rvalue.intf);
	return rvalue;
}
CmaList&   CmaCell::operator= (CmaList& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_LIST,rvalue.intf);
	return rvalue;
}
CmaStream& CmaCell::operator= (CmaStream& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_STREAM,rvalue.getIntf());
	return rvalue;
}
CmaAlgorithm& CmaCell::operator= (CmaAlgorithm& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_ALGORITHM,rvalue.getIntf());
	return rvalue;
}
void CmaCell::Copy(CmaCell& source){
	if(intf && &source) intf->Copy(source.intf);
}

void CmaCell::Clear() const{
	if(intf) intf->Clear();
}

ImaReadList* CmaCell::AsReadList(){
	ImaComponent* i;
	intf->GetAsComponent(MA_READLIST,&i);
	return (ImaReadList*)i;
}
ImaList* CmaCell::AsList(){
	ImaComponent* i;
	intf->GetAsComponent(MA_LIST,&i);
	return (ImaList*)i;
}

ImaMatrix* CmaCell::AsMatrix(){
	ImaComponent* i;
	intf->GetAsComponent(MA_MATRIX,&i);
	return (ImaMatrix*)i;
}
ImaStream* CmaCell::AsStream(){
	ImaComponent* i;
	intf->GetAsComponent(MA_STREAM,&i);
	return (ImaStream*)i;
}
ImaAlgorithm* CmaCell::AsAlgorithm(){
	ImaComponent* i;
	intf->GetAsComponent(MA_ALGORITHM,&i);
	return (ImaAlgorithm*)i;
}



//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaMatrixIterator                                  ----
//----                                                                        ----
//--------------------------------------------------------------------------------

CmaMatrixIterator::CmaMatrixIterator(CmaMatrix& source){
	src=&source;
	cookie=0;
	if(src && src->intf)
		MA_THROW(src->intf->CreateIter(&cookie));
	if(src)
		curIndex=(maIndex) new double[src->Dim()+1];
	curIndex->count=0;
	First();
}
CmaMatrixIterator::~CmaMatrixIterator(){
	if(curIndex) 
		delete curIndex;
	if(src && src->intf) 
		src->intf->DeleteIter(cookie);
}
bool CmaMatrixIterator::First(){
	completed=true;
	if(src && src->intf)
		completed=src->intf->FirstIter(cookie,&curIndex)!=0;
	return !completed;
}	

void CmaMatrixIterator::operator ++(){
	completed=true;
	if(src && src->intf)
		completed=src->intf->NextIter(cookie,&curIndex)!=0;
}	
void CmaMatrixIterator::operator ++(int){
	completed=true;
	if(src && src->intf)
		completed=src->intf->NextIter(cookie,&curIndex)!=0;
}	

bool CmaMatrixIterator::Completed() const{
	return completed;
}

CmaMatrixIterator::operator bool () const{
	return !completed;
}
int CmaMatrixIterator::operator[] (int dimno)  const{
	return (dimno<curIndex->count)?curIndex->idx[dimno]:0;
}


//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaReadList                                        ----
//----                                                                        ----
//--------------------------------------------------------------------------------




long CmaReadList::Size() const{
	int s=0;
	if(intf) intf->GetSize(&s);
	return s;
}

CmaCell CmaReadList::operator[] (long i) const{
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->GetCell(i,&r));
		CmaCell c(r);
		if(r) r->Release();
		return c;
	}
	return CmaCell(0);
}

CmaCell CmaReadList::operator[] (maString i) const{
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->FindCell(i,&r));
		CmaCell c(r);
		if(r) r->Release();
		return c;
	}
	return CmaCell(0);
}

maString CmaReadList::NameOf(long index) const{
	maString s=0;
	if(intf) MA_THROW(intf->GetCellName(index,&s));
	return s;
}

long CmaReadList::IndexOf(maString name) const{
	int l=-1;
	if(intf) MA_THROW(intf->FindCellno(name,&l));
	return l;
}



//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaList                                            ----
//----                                                                        ----
//--------------------------------------------------------------------------------




long CmaList::Size() const{
	int s=0;
	if(intf) intf->GetSize(&s);
	return s;
}

CmaCell CmaList::operator[] (long i) const{
	ImaCell* r;
	if(intf){ 
		intf->CreateCells(i);
		MA_THROW(intf->GetCell(i,&r));
		CmaCell c(r);
		if(r) r->Release();
		return c;
		
	}
	return CmaCell(0);
}

CmaCell CmaList::operator[] (maString i) const{
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->FindCreateCell(i,&r));
		CmaCell c(r);
		if(r) r->Release();
		return c;
	}
	return CmaCell(0);
}


CmaCell CmaList::GetCell (long i) const{
	ImaCell* r=0;
	if(intf){
		MA_THROW(intf->GetCell(i,&r))
		CmaCell c(r);
		return c;
	}
	return CmaCell();

}

CmaCell CmaList::GetCell (maString i) const{
	ImaCell* r;
	if(intf){
		MA_THROW(intf->FindCell(i,&r));
			CmaCell c(r);
			return c;
		}
		
		return CmaCell();
}

long CmaList::AddCell(maString name) const{
	int r=-1;
	if(intf) MA_THROW(intf->AddCellno(name,&r));
	return r;
}

void CmaList::CreateCells(long count) const{
	if(intf) intf->CreateCells(count);
}

maString CmaList::NameOf(long index) const{
	maString s=0;
	if(intf) MA_THROW(intf->GetCellName(index,&s));
	return s;
}

long CmaList::IndexOf(maString name) const{
	int l=-1;
	if(intf) MA_THROW(intf->FindCellno(name,&l));
	return l;
}


void CmaList::Clear() const{
	if(intf) intf->Clear();
	
}



//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaMethod                                          ----
//----                                                                        ----
//--------------------------------------------------------------------------------




CmaCell CmaMethod::operator[] (long i) const{
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->GetCell(i,&r));
		CmaCell c(r);
		r->Release();
		return (c);
	}
	return CmaCell(0);
}

CmaCell CmaMethod::operator[] (maString i) const{
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->FindCell(i,&r));
		CmaCell c(r);
		r->Release();
		return c;
	}
	return CmaCell(0);
}

CmaList CmaMethod::Param () const{
	ImaList* i=0;
	if(intf) 
		MA_THROW(intf->GetParam(&i));
		CmaList ret(i);
	if(i) i->Release();
	return ret;
}


CmaReadList CmaMethod::Input () const{
	CmaCell c((*this)[L"Input"]);
	
	CmaReadList l(c);
	
	return l;
	
}
CmaReadList CmaMethod::Output () const{
	CmaCell c((*this)[L"Output"]);

	CmaReadList l(c);
	
	return l;
	
}

/*
CmaMatrix Input(maString name)const {
	ImaMatrix* m=0;
	if(intf) maLastError=intf->GetInput(name,&m);
	return CmaMatrix(m);
}
CmaMatrix Output(maString name)const {
	ImaMatrix* m=0;
	if(intf) maLastError=intf->GetOutput(name,&m);
	return CmaMatrix(m);
} */

CmaCell CmaMethod::Input (maString name) const{
	CmaCell ret=(Input()[name]);
	return ret;
}
CmaCell CmaMethod::Input (int cellno) const{
	CmaCell ret=(Input()[cellno]);
	return ret;
}

CmaCell CmaMethod::Output (maString name) const{
	CmaReadList l=Output();
	CmaCell ret=(l[name]);
	return ret;
}
CmaCell CmaMethod::Output (int cellno) const{
	CmaReadList l=Output();
	CmaCell ret=(l[cellno]);
	return ret;
}

void CmaMethod::Calc () const{
	if(intf) MA_THROW(intf->Calc());
}																		   
void CmaMethod::CalcCell (int cellno, CmaIndex& index, CmaCell& cell) const{
	if(intf) MA_THROW(intf->CalcCell(cellno,index.AsIndex(),cell.intf));
}


//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaAlgorithm                                       ----
//----                                                                        ----
//--------------------------------------------------------------------------------



CmaAlgorithm::CmaAlgorithm(maString name, CmaKernel* kernel){
	intf=0;
	if(kernel && (kernel->getIntf()))
		MA_THROW((kernel->getIntf())->CreateAlgorithm(name,&intf));
		
}

maString CmaAlgorithm::GetDescription(){
	maString res=0;
	if(intf) intf->GetDescription(&res);
	return res;
}


CmaCell CmaAlgorithm::operator[] (long i){
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->GetCell(i,&r));
		CmaCell c(r);//=new CmaCell(r);
		r->Release();
		return (c);
	}
	return CmaCell(0);
}

CmaCell CmaAlgorithm::operator[] (maString i){
	ImaCell* r;
	if(intf){ 
		MA_THROW(intf->FindCell(i,&r));
		CmaCell c(r);//=new CmaCell(r);
		r->Release();
		return (c);
	}
	return CmaCell(0);
	
}


CmaList CmaAlgorithm::Param (){
	CmaCell c=operator[](L"Param");
	CmaList l(c);
	return l;
}

CmaMethod CmaAlgorithm::Method (maString name){
	ImaMethod* m=0;
	if(intf) MA_THROW(intf->GetMethod(name,&m));
	CmaMethod c(m);
	if(m) m->Release();
	return c;
}
void CmaAlgorithm::SetMethod(ImaMethodDef *mdef){
	if(intf) MA_THROW(intf->SetMethod(mdef));
}

void CmaAlgorithm::Verify (){
	if(intf) MA_THROW(intf->Verify());
}
void CmaAlgorithm::Verify(int cellno){
	if(intf) MA_THROW(intf->VerifyMethod(cellno));
}

void CmaAlgorithm::Verify(maString name){
	if(intf) MA_THROW(intf->VerifyMethodByName(name));
}




//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaKernel                                          ----
//----                                                                        ----
//--------------------------------------------------------------------------------


CmaKernel::CmaKernel(){
	intf=maKernelNewInstance();
#ifdef MA_USE_EXCEPTIONS
		if(!intf) MA_THROW(MA_ERR_NOINTERFACE);
#endif

}
CmaKernel::CmaKernel(maString logName){
	intf=maKernelNewInstance();
#ifdef MA_USE_EXCEPTIONS
		if(!intf) MA_THROW(MA_ERR_NOINTERFACE);
#endif
	if(intf){
		MA_THROW(intf->OpenLogFile(logName))
		if(maLastError){ 
			intf->Release();
			intf=0;
		}
	}
}
CmaKernel::~CmaKernel(){
	if(intf){
		intf->Release();
	}
}

void CmaKernel::LoadLibraryByName (maString clsname){
	if(intf) 
		MA_THROW(intf->LoadLibraryByName(clsname));
}
void CmaKernel::LoadLibraryByClsid (maString clsid){
	if(intf) 
		MA_THROW(intf->LoadLibraryByClsid(clsid));
}
void CmaKernel::RegisterLibrary(ImaLibrary* lib){
	if(intf) 
		MA_THROW(intf->RegisterLibrary(lib));
}
void CmaKernel::UnloadLibraries(){
	if(intf) intf->UnloadLibraries();
}

void CmaKernel::OpenLogFile(maString name){
	if(intf) 
		MA_THROW(intf->OpenLogFile(name));
}

CmaStream CmaKernel::GetDebugStream (){
	ImaStream* s=0;
	if(intf)
		MA_THROW(intf->GetDebugStream(&s));
	CmaStream* m=new CmaStream(s);
	if(s) s->Release();
	return *m;
}

void CmaKernel::SetDebugStream (CmaStream stream){
	if(intf && (&stream)) 
		MA_THROW(intf->SetDebugStream((ImaStream*)stream.getIntf()));
	
}
void CmaKernel::LogError(ImaComponent *sender,HRESULT ecode,maString message){
	if(intf) 
		intf->LogError(sender,ecode,message);
}
void CmaKernel::LogMessage( ImaComponent *sender,maString message){
	if(intf) 
		intf->LogMessage(sender,message);
}

void CmaKernel::DebugLevel(int level){
	if(intf) 
		intf->SetDebugLevel(level);
}

int CmaKernel::DebugLevel(){
	int l=-1;
	if(intf) 
		intf->GetDebugLevel(&l);
	return l;
}

void CmaKernel::LogMemoryReport(){
	if(intf) 
		intf->LogMemoryReport();
}

void CmaKernel::SetProgressHandler(ImaProgressHandler *handler){
	if(intf) 
		intf->SetProgressHandler(handler);
}


bool CmaKernel::Progress(double percent,maString message){
	if(intf) 
		return intf->Progress(percent,message)==0;
	return true;
}
void CmaKernel::SetMinProgressStep(double minProgressStep){
	if(intf) 
		intf->SetMinProgressStep(minProgressStep);
}
// Добавляет в буфер результат форматной печати (не более inc_portion байт)
void CmaKernel::VPrintF(maString buf,maString format, va_list varg) {
	int ret = _vsnwprintf(buf, printfBufLen, format, varg);
	if (ret>0) {
		buf[ret] = L'\0';
	}
} 

// Добавляет в буфер результат форматной печати (не более inc_portion байт)
void CmaKernel::Message(maString format, ...) {
	va_list varg;
	if(printfBufLen==0) printfBufLen=2048;
	va_start (varg, format);
	if (format && *format){
		maString buf=new wchar_t[printfBufLen+1];
		VPrintF (buf,format, varg);
		LogMessage(0,buf);
		delete[] buf;
	}
	va_end (varg);
}
void CmaKernel::Error(int eCode,maString format, ...) {
	va_list varg;
	if(printfBufLen==0) printfBufLen=2048;
	va_start (varg, format);
	if (format && *format){
		maString buf=new wchar_t[printfBufLen+1];
		VPrintF (buf,format, varg);
		LogError(0,eCode,buf);
		delete[] buf;
	}
	va_end (varg);
}

//--------------------------------------------------------------------------------
//----                                                                        ----
//----                     CmaList2                                            ----
//----                                                                        ----
//--------------------------------------------------------------------------------

/*


CmaList2 CmaList2::operator[] (long i) {
	if(intf){
		if(curI){
			ImaList2* l;
			intf->GetAsComponent(curI,MA_LIST,(ImaComponent**)&l);
			if(!l){
				l=maList2NewInstance();
				intf->SetAsComponent(curI,MA_LIST,l);
			}
			CmaList2 L(l);
			L.curI=i;
			return L;
		}else
			curI=i;
	}
	return *this;
}

CmaList2 CmaList2::operator[] (maString i) {
	if(intf){
		if(curI){
			ImaList2* l;
			intf->GetAsComponent(curI,MA_LIST,(ImaComponent**)&l);
			if(!l){
				l=maList2NewInstance();
				intf->SetAsComponent(curI,MA_LIST,l);
			}
			CmaList2 L(l);
			intf->FindCellno(i,&L.curI);
			return L;
		}else{
			intf->FindCellno(i,&curI);
		}
	}
	return *this;
}


CmaCell CmaList2::GetCell (long i) {
	ImaCell* r=0;
	if(intf){
		r=maCellNewInstance();
		MA_THROW(intf->ValueToCell(i,&r))
		CmaCell c(r);
		return c;
	}
	return CmaCell();

}

CmaCell CmaList2::GetCell (maString i) {
	ImaCell* r;
	if(intf){
		r=maCellNewInstance();
		int n;
		intf->FindCellno(i,&n);
		MA_THROW(intf->ValueToCell(n,&r))
		CmaCell c(r);
		return c;
	}
		
		return CmaCell();
}

long CmaList2::AddCell(maString name) {
	int r=-1;
	if(intf) MA_THROW(intf->AddCellno(name,&r));
	return r;
}

void CmaList2::CreateCells(long count) {
	if(intf) intf->CreateCells(count);
}

maString CmaList2::NameOf(long index) {
	maString s=0;
	if(intf) MA_THROW(intf->GetCellName(index,&s));
	return s;
}

long CmaList2::IndexOf(maString name) {
	int l=-1;
	if(intf) MA_THROW(intf->FindCellno(name,&l));
	return l;
}


void CmaList2::Clear() {
	if(intf) intf->Clear();
	
}


bool  CmaList2::IsEmpty()  {
//  if(intf)
//	return intf->IsEmpty()!=MA_FALSE;
  return true;
}



CmaList2::operator int (){
	int r=(int)default_double;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsLong(&r);
		else
		  intf->SetAsLong(r);
	}
	return r;
}
CmaList2::operator boolean (){
	boolean r=(boolean)default_double;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsBoolean(&r);
		else
		  intf->SetAsBoolean(r);
	}
	return r;
}

CmaList2::operator double (){
	double r=default_double;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsDouble(&r);
		else
		  intf->SetAsDouble(r);
	}
	return r;
}
maString CmaList2::AsString(){
	maString r=default_string;
	if(intf) {
		if (intf->IsEmpty()!=MA_TRUE)
		  intf->GetAsString(&r);
		else 
		  intf->SetAsString(r);
	}
	return r;
}


int CmaList2::operator= (int rvalue){
	if(intf) intf->SetAsLong(rvalue);
	return rvalue;
}
boolean CmaList2::operator= (boolean rvalue){
	if(intf) intf->SetAsBoolean(rvalue);
	return rvalue;
}

double CmaList2::operator= (double rvalue){
	if(intf) intf->SetAsDouble(rvalue);
	return rvalue;
}


maString CmaList2::operator= (maString rvalue){
	if(intf) intf->SetAsString(rvalue);
	return rvalue;
}

CmaCell& CmaList2::Default (double rvalue){
	default_double=rvalue;
	return *this;
}
CmaCell& CmaList2::Default (maString rvalue){
	default_string=rvalue;
	return *this;
}



CmaMatrix& CmaList2::operator= (CmaMatrix& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_MATRIX,rvalue.intf);
	return rvalue;
}
CmaList&   CmaList2::operator= (CmaList& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_LIST,rvalue.intf);
	return rvalue;
}
CmaStream& CmaList2::operator= (CmaStream& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_STREAM,rvalue.getIntf());
	return rvalue;
}
CmaAlgorithm& CmaList2::operator= (CmaAlgorithm& rvalue){
	if(intf && &rvalue) intf->SetAsComponent(MA_ALGORITHM,rvalue.getIntf());
	return rvalue;
}
void CmaCell::CmaList2(CmaCell& source){
	if(intf && &source) intf->Copy(source.intf);
}

void CmaCell::CmaList2() const{
	if(intf) intf->Clear();
}

ImaReadList* CmaList2::AsReadList(){
	ImaComponent* i;
	intf->GetAsComponent(MA_READLIST,&i);
	return (ImaReadList*)i;
}
ImaList* CmaList2::AsList(){
	ImaComponent* i;
	intf->GetAsComponent(MA_LIST,&i);
	return (ImaList*)i;
}

ImaMatrix* CmaList2::AsMatrix(){
	ImaComponent* i;
	intf->GetAsComponent(MA_MATRIX,&i);
	return (ImaMatrix*)i;
}
ImaStream* CmaList2::AsStream(){
	ImaComponent* i;
	intf->GetAsComponent(MA_STREAM,&i);
	return (ImaStream*)i;
}
ImaAlgorithm* CmaList2::AsAlgorithm(){
	ImaComponent* i;
	intf->GetAsComponent(MA_ALGORITHM,&i);
	return (ImaAlgorithm*)i;
}

*/











			//--------------------------------------------------------------------------------
			//----                                                                        ----
			//----                     Class factories and instance creation funcs        ----
			//----                                                                        ----
			//--------------------------------------------------------------------------------




static IClassFactory *fmaCell,/**fmaDoubleMatrix,*fmaStringMatrix,*fmaBoolMatrix,*fmaByteMatrix,*fmaDSparseMatrix,*fmaSSparseMatrix,*/
*fmaSubMatrix,*fmaCompositeMatrix,
*fmaList,*fmaTextFileStream,*fmaBinaryFileStream,*fmaClientDataStream,*fmaMethod,*fmaAlgorithm,*fmaKernel,*fmaList2;

static ImaMatrixFactory* fmaMatrix;

static IClassFactory *fmaSparseMatrix;


ImaCell* maCellNewInstance(){
	ImaCell* res=0;
	if(!fmaCell){
		CoGetClassObject(CLSID_MaCell,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaCell);
	}
	fmaCell->CreateInstance(0,IID_ImaCell,(void**)&res);
	return res;
}

ImaMatrix* maMatrixNewInstance(maType type){
	ImaMatrix* res=0;
	if(!fmaMatrix){
		CoCreateInstance(CLSID_MaMatrixFactory,0,CLSCTX_INPROC_SERVER,IID_ImaMatrixFactory,(void**)&fmaMatrix);
	}
	if(fmaMatrix) fmaMatrix->Create(type,&res);
	return res;
}


ImaMatrix* maSubMatrixNewInstance(){
	ImaMatrix* res=0;
	if(!fmaSubMatrix){
		CoGetClassObject(CLSID_MaSubMatrix,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaSubMatrix);
	}
	fmaSubMatrix->CreateInstance(0,IID_ImaMatrix,(void**)&res);
	return res;
}
ImaMatrix* maCompositeMatrixNewInstance(){
	ImaMatrix* res=0;
	if(!fmaCompositeMatrix){
		CoGetClassObject(CLSID_MaCompositeMatrix,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaCompositeMatrix);
	}
	fmaCompositeMatrix->CreateInstance(0,IID_ImaMatrix,(void**)&res);
	return res;
}


ImaList* maListNewInstance(){
	ImaList* res=0;
	if(!fmaList){
		CoGetClassObject(CLSID_MaList,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaList);
	}
	fmaList->CreateInstance(0,IID_ImaList,(void**)&res);
	return res;
}

ImaFileStream* maTextFileStreamNewInstance(){
	ImaFileStream* res=0;
	if(!fmaTextFileStream)
		CoGetClassObject(CLSID_MaTextFileStream,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaTextFileStream);
	
	if(fmaTextFileStream)
		fmaTextFileStream->CreateInstance(0,IID_ImaFileStream,(void**)&res);
	return res;
}

ImaFileStream* maBinaryFileStreamNewInstance(){
	ImaFileStream* res=0;
	if(!fmaBinaryFileStream)
		CoGetClassObject(CLSID_MaBinaryFileStream,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaBinaryFileStream);

	if(fmaBinaryFileStream)
		fmaBinaryFileStream->CreateInstance(0,IID_ImaFileStream,(void**)&res);
	return res;
}

ImaClientDataStream* maClientDataStreamNewInstance(){
	ImaClientDataStream* res=0;
	if(!fmaClientDataStream)
		CoGetClassObject(CLSID_MaClientDataStream,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaClientDataStream);

	if(fmaClientDataStream)
		fmaClientDataStream->CreateInstance(0,IID_ImaClientDataStream,(void**)&res);
	return res;
}


ImaMethod* maMethodNewInstance(){
	ImaMethod* res=0;
	if(!fmaMethod){
		CoGetClassObject(CLSID_MaMethod,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaMethod);
	}
	fmaMethod->CreateInstance(0,IID_ImaMethod,(void**)&res);
	return res;
}
ImaAlgorithm* maAlgorithmNewInstance(){
	ImaAlgorithm* res=0;
	if(!fmaAlgorithm){
		CoGetClassObject(CLSID_MaAlgorithm,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaAlgorithm);
	}
	fmaAlgorithm->CreateInstance(0,IID_ImaAlgorithm,(void**)&res);
	return res;
}
ImaKernel* maKernelNewInstance(){
	ImaKernel* res=0;
	if(!fmaKernel){
		CoGetClassObject(CLSID_MaKernel,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaKernel);
	}
	fmaKernel->CreateInstance(0,IID_ImaKernel,(void**)&res);
	return res;
}


ImaSparseMatrix* maSparseMatrixNewInstance(){
	ImaSparseMatrix* res=0;
	if(!fmaSparseMatrix){
		CoGetClassObject(CLSID_MaSparseMatrix,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaSparseMatrix);
	}
	fmaSparseMatrix->CreateInstance(0,IID_ImaSparseMatrix,(void**)&res);
	return res;
}

ImaList2* maList2NewInstance(){
	ImaList2* res=0;
	if(!fmaList2){
		CoGetClassObject(CLSID_MaList2,CLSCTX_INPROC_SERVER,0,IID_IClassFactory,(void**)&fmaList2);
	}
	fmaList2->CreateInstance(0,IID_ImaList2,(void**)&res);
	return res;
}


