// aplPluginItem.cpp: implementation of the CaplPluginItem class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <afxtempl.h>
#include "aplPluginItem.h"
#include "InfoBar.h"
#include "PSMDoc.h"
#include "MainFrm.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

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

CString CaplPluginItem::m_sDisableItems= _T("");

CWnd* CaplPluginItem::m_parent= NULL;
CPSMDoc* CaplPluginItem::m_doc= NULL;
CMainFrame* CaplPluginItem::m_frame= NULL;
UINT CaplPluginItem::m_msg = -1;
UINT CaplPluginItem::m_allMess[2];

CaplPluginItem::CaplPluginItem()
{	
	m_sPath = _T("");
	m_sName = _T("");
	m_sDescr = _T("");
	m_hModule = NULL;

	m_bShowWarningMessage = true;

	m_global_views = NULL;
	m_local_views= new CaplAddinViews;

	m_sFileContents= _T("");
}

CaplPluginItem::~CaplPluginItem()
{
	m_Functions.Clear();
	delete m_local_views;
}

CStringArray CaplPluginItem::m_arForcedPlagins;
void CaplPluginItem::CheckForcedPlagins(CString& sPath)
{
	for (int i= 0; i<m_arForcedPlagins.GetSize(); i++)
	{
		if(m_arForcedPlagins[i]==sPath)
		{
			m_arForcedPlagins.RemoveAt(i);
			break;
		}
	}
}

void CaplPluginItem::InitForcedPlagins()
{
	m_arForcedPlagins.RemoveAll();

	m_arForcedPlagins.Add("plg_docview.dll");
}


CString CaplPluginItem::GetMenuPath(CString menu)
{
	int ind=0;
	while((ind=menu.Find(_T('['),0))>-1)
	{
		int ind2 = menu.Find(_T(']'),ind);
		menu.Delete(ind,ind2-ind+1);
	}
	ind = menu.ReverseFind(_T('\\'));
	if(ind==menu.GetLength()-1)
		menu+= APL_T("разделитель");
	return menu;
}

CaplPluginItem &CaplPluginItem::operator = (CaplPluginItem &item)
{
	m_Functions.Clear();

	m_hModule = item.m_hModule;
	m_sPath = item.m_sPath;
	m_sName = item.m_sName;
	m_index = item.m_index;

	for(int i= 0; i<item.m_Functions.GetSize(); i++)
		m_Functions.Add(item.m_Functions[i]);
	
	m_global_views = item.m_global_views;
	m_local_views = item.m_local_views;

	return *this;		
}
CaplPluginItem::CaplPluginItem(const CaplPluginItem & item )
{
	m_msg = 0;

	m_hModule = item.m_hModule;
	m_sPath = item.m_sPath;
	m_sName = item.m_sName;
	m_index = item.m_index;

	for(int i= 0; i<item.m_Functions.GetSize(); i++)
		m_Functions.Add(item.m_Functions[i]);

	m_global_views = item.m_global_views;
	m_local_views = item.m_local_views;
}

void CaplPluginItem::WriteDataToFile(CaplStringFile &f)
{
	CStringArray psmadd;
	CString str,str1,exepath;
	GetExePath(exepath);
	bool find=  false;
	int ind = -1;
	int i=0;
	if(!GetOnlyDirName(m_sPath).CompareNoCase(exepath)){
		m_sPath=GetOnlyFileName(m_sPath);
	}

	if(-2==m_index || -1==m_index)
	{
		//дополнение не удалось загрузить. сохраняем в файл то, что прочитали первоначально
		f.WriteString(m_sFileContents);
		return;
	}

	f.WriteString(m_sPath+_T("\n"));
	for(int i=0; i<m_Functions.GetSize();i++)
		if(m_Functions[i]->flag==0) f.WriteString(_T("-f")+m_Functions[i]->sType+_T(":")+m_Functions[i]->sFunction+_T("\n"));
	if(m_local_views)
	{
		for(int i=0; i<m_local_views->GetSize();i++)
		{
			if(m_local_views->GetAt(i)->show==false) f.WriteString(_T("-v:")+m_local_views->GetAt(i)->tab_name+_T("\n"));
		}	
	}
}

void CaplPluginItem::LoadFileContent(CaplTAggr <CaplPluginItem*, CaplPluginItem*, APLAGGR_AUTOKILLREF|APLAGGR_LIST> &arPLItems, CString* sErrorDscr)
{
	arPLItems.Clear();

	CString sExePath;
	CString sString;
	GetExePath(sExePath);

	CaplStringFile psd_add_file;

	if(!psd_add_file.Open(sExePath+_T("psm.add"),CFile::modeRead|CFile::shareDenyNone))
		return;

	CStringArray arFileContent;
	while(psd_add_file.ReadString(sString))
		arFileContent.Add(sString);

	CaplPluginItem::m_sDisableItems= _T("");

	int iIndex (-1);

	CaplPluginItem* pItem= new CaplPluginItem;
	if(!pItem) return;

	pItem->ReadItem(arFileContent, iIndex, arPLItems, sErrorDscr);

	return;
}

void CaplPluginItem::FillFunctions(CArray<CaplItemInfo*, CaplItemInfo*>& items)
{
	if(!m_hModule) return;

	LPFUNCTION lpFunc;

	for(int i=0; i<items.GetSize(); i++)
	{
		lpFunc= NULL;
		CaplItemInfo *item = items.GetAt(i);

		FunctionInfo* func_info= new FunctionInfo;

		func_info->sFunction= item->m_menuName;
		func_info->sType= item->m_treeItemType;
		if(!(0==item->m_image || -1==item->m_image))
		{
			func_info->ico=LoadIcon(m_hModule,MAKEINTRESOURCE(item->m_image));
		}
		func_info->sDescr= item->m_description;
		func_info->flag= 1;
		func_info->iFunctionParamType=item->m_funcParamType;

		if(!item->m_functionName.IsEmpty())
		{
#ifdef _UNICODE
			CaplStringAdapter sFunctionName(item->m_functionName);
			(FARPROC&)lpFunc = GetProcAddress(m_hModule,(LPCSTR)sFunctionName);
#else
			(FARPROC&)lpFunc = GetProcAddress(m_hModule, item->m_functionName);
#endif
		}
		else
			lpFunc = NULL;
		func_info->lpFunction= lpFunc;

		m_Functions.Add(func_info);
	}

	return;
}

int CaplPluginItem::ReadItem(CStringArray& arFileContent, int &iIndex, 	
									 CaplTAggr <CaplPluginItem*, CaplPluginItem*, APLAGGR_AUTOKILLREF|APLAGGR_LIST> &arPLItems,
									 CString *sErrorDscr)
{
	arPLItems.Add(this);

	m_sPath=_T("");
	while(m_sPath==_T(""))
	{
		++iIndex;
		if(arFileContent.GetSize()<iIndex)
			return -2;

		m_sPath= arFileContent[iIndex];

		if(m_sPath.GetAt(0)==_T(';'))
		{
			CaplPluginItem::m_sDisableItems+=m_sPath+_T("\n");
			continue;
		}
	}

	m_Functions.Clear();
	m_sFileContents+=m_sPath+_T("\n");
	
	CString sExePath;
	GetExePath(sExePath);

	CString sLibPath;
	if(m_sPath.Find(_T("\\"))<0)
		sLibPath = sExePath+m_sPath;
	else
		sExePath= m_sPath;

	CFileStatus fs;
	if(!CFile::GetStatus(sExePath,fs)) 
	{
		m_sName =  APL_T("Не найден файл дополнения: ")+sExePath;
		m_index = -2;
		if(sErrorDscr!=0){
			*sErrorDscr+=_T("\n")+m_sName;
		}else if(m_bShowWarningMessage){
			AfxMessageBox(m_sName, MB_SYSTEMMODAL|MB_OK);
		}

		while(arFileContent.GetSize()<iIndex++)
		{
			if(arFileContent[iIndex]==_T("")) continue;
			if(arFileContent[iIndex].Left(1)!=_T("-")) break;
			m_sFileContents+=arFileContent[iIndex]+_T("\n");
		}

		return -3;
	}

	HMODULE hMod = 0;
	try
	{
		hMod = AfxLoadLibrary(sLibPath);
	}
	catch (...)
	{
		m_sName= APL_T("Ошибка присоединения дополнения ")+sLibPath+_T("!");
		if(sErrorDscr!=0){
			*sErrorDscr+=_T("\n")+m_sName;
		}else if(m_bShowWarningMessage){
			AfxMessageBox(m_sName, MB_SYSTEMMODAL|MB_OK);
		}
		return -4;
	}

	if(hMod)
	{
		m_hModule=hMod;
		bool (*lpGetFunctionsList)(CArray<CaplItemInfo*, CaplItemInfo*>*);
		(FARPROC&)lpGetFunctionsList = GetProcAddress(hMod,"GetFunctionsList"); //-V614
		if(lpGetFunctionsList)
		{
			CArray<CaplItemInfo*, CaplItemInfo*> items;
			lpGetFunctionsList(&items);

			FillFunctions(items);
		}
		else
			return -1;

		LPCTSTR(*lpGetAddInName)();
		(FARPROC&)lpGetAddInName = GetProcAddress(hMod,"GetAddInName"); //-V614
		if(lpGetAddInName)
		{
			m_sName =lpGetAddInName();
			//D			name += _T(" (")+GetOnlyFileName(path)+_T(")");
		}
		else{
			//D			name = GetOnlyFileName(path);
		}
		(FARPROC&)lpGetAddInName = GetProcAddress(hMod,"GetAddInDescription");
		if(lpGetAddInName)
			m_sDescr =lpGetAddInName();
		else m_sDescr = _T("");

		bool (*lpGetViews)(CaplAddinViews*);
		(FARPROC&)lpGetViews = GetProcAddress(hMod,"GetTabViews"); //-V614
		if(lpGetViews!=0) lpGetViews(m_local_views);
	}
	else
	{
		m_sName =  APL_T("!! Не удалось подключить дополнение: ")+m_sPath;
		if(sErrorDscr!=0){
			*sErrorDscr+=_T("\n")+m_sName;
		}else if(m_bShowWarningMessage){
			AfxMessageBox(m_sName, MB_SYSTEMMODAL|MB_OK);
		}
	}

	while(arFileContent.GetSize()<iIndex++)
	{
		if(arFileContent[iIndex]==_T("")) continue;
		if(arFileContent[iIndex].Left(1)==_T(";"))
		{
			CaplPluginItem::m_sDisableItems+=arFileContent[iIndex]+_T("\n");
			continue;
		}
		if(arFileContent[iIndex].Left(1)==_T("-"))
		{
			CString sStr1;
			bool bFinded(false);
			for(int i=0;i<m_Functions.GetSize()&&!bFinded;i++)
			{
				sStr1 = _T("-f")+m_Functions[i]->sType+_T(":")+m_Functions[i]->sFunction;
				if(sStr1==arFileContent[iIndex]) 
				{
					m_Functions[i]->flag= 0;
					bFinded= true;
				}
			}
			for(int i=0; i<m_local_views->GetSize()&&!bFinded;i++)
			{
				sStr1 = _T("-v:")+m_local_views->GetAt(i)->tab_name;
				if(sStr1==arFileContent[iIndex])
				{
					m_local_views->SetFlagAt(i,false);
					bFinded= true;
				}
				sStr1 = _T("-v")+m_local_views->GetAt(i)->tab_name;
				if(sStr1==arFileContent[iIndex])
				{
					m_local_views->SetFlagAt(i,false);
					bFinded= true;
				}
			}
			m_sFileContents+=arFileContent[iIndex]+_T("\n");
		}
		CaplPluginItem* pItem= new CaplPluginItem;
		if(pItem)
		{
			pItem->m_global_views=m_global_views;
			pItem->ReadItem(arFileContent, --iIndex, arPLItems, sErrorDscr);
		}
// 		return 0;	//???
	}

	return 0;
}

int CaplPluginItem::ReadDataFromFile(CaplStringFile &f, CString &sPath, UINT flag, CString *err_log)
{
	CString tpath;
/*	оставил в знак солидарности с индусскими программистами, которых увольняют по вине Грефа
	if(sPath==_T(""))
		m_sPath=_T("");
	else
		m_sPath= sPath;*/

	m_sPath=sPath;

	while(m_sPath==_T("") || m_sPath.GetAt(0)==_T(';')|| m_sPath.GetAt(0)==_T('-'))
		if(!f.ReadString(m_sPath)) return -2;
	
	CaplPluginItem::CheckForcedPlagins(m_sPath);

	m_Functions.Clear();
	m_sFileContents+=m_sPath+_T("\n");
	sPath= _T("");

	if(tpath.Find(_T("\\"))<0)
	{
		CString str = AfxGetApp()->m_pszHelpFilePath;
		str = str.Left(str.ReverseFind(_T('\\'))+1);
		tpath = str+m_sPath;
	}

	CFileStatus fs;
	if(!CFile::GetStatus(tpath,fs)) 
	{
		m_sName =  APL_T("Не найден файл дополнения: ")+tpath;
		m_index = -2;
		if(err_log!=0){
			*err_log+=_T("\n")+m_sName;
		}else if(m_bShowWarningMessage){
			AfxMessageBox(m_sName, MB_SYSTEMMODAL|MB_OK);
		}

		CString str;
		while(f.ReadString(str))
		{
			if(str.IsEmpty()) continue;
			if(str[0]!=_T('-')){//костыли
				sPath= str;
				break;
			}
			else{
				m_sFileContents+=str+_T("\n");
			}
		}

		return -3;
	}

	HMODULE hMod = 0;
	try
	{
		hMod = AfxLoadLibrary(tpath);
	}
	catch (...)
	{
		m_sName= APL_T("Ошибка присоединения дополнения ")+tpath+_T("!");
		m_index = -1;
		if(err_log!=0){
			*err_log+=_T("\n")+m_sName;
		}else if(m_bShowWarningMessage){
			AfxMessageBox(m_sName, MB_SYSTEMMODAL|MB_OK);
		}

		CString str;
		while(f.ReadString(str))
		{
			if(str.IsEmpty()) continue;
			if(str[0]!=_T('-')){//костыли
				sPath= str;
				break;
			}
			else{
				m_sFileContents+=str+_T("\n");
			}
		}

		return -4;
	}
	if(hMod)
	{
		m_hModule=hMod;
		LPFUNCTION lpFunc;
		bool (*lpGetFunctionsList)(CArray<CaplItemInfo*, CaplItemInfo*>*);
		(FARPROC&)lpGetFunctionsList = GetProcAddress(hMod,"GetFunctionsList"); //-V614
		if(lpGetFunctionsList)
		{
			CArray<CaplItemInfo*, CaplItemInfo*> items;
			lpGetFunctionsList(&items);
			for(int i=0; i<items.GetSize(); i++)
			{
				CaplItemInfo *item = items.GetAt(i);

				FunctionInfo* func_info= new FunctionInfo;

				func_info->sFunction= item->m_menuName;
				func_info->sType= item->m_treeItemType;
				if(!(0==item->m_image || -1==item->m_image))
				{
					func_info->ico=LoadIcon(hMod,MAKEINTRESOURCE(item->m_image));
				}
				func_info->sDescr= item->m_description;
				func_info->flag= 1;
				func_info->iFunctionParamType=item->m_funcParamType;

				if(!item->m_functionName.IsEmpty())
				{
#ifdef _UNICODE
					CaplStringAdapter sFunctionName(item->m_functionName);
					(FARPROC&)lpFunc = GetProcAddress(hMod,(LPCSTR)sFunctionName);
#else
					(FARPROC&)lpFunc = GetProcAddress(hMod,item->m_functionName);
#endif
				}
				else
					lpFunc = NULL;
				func_info->lpFunction= lpFunc;

				m_Functions.Add(func_info);
			}
		}
		else
			return -1;
		LPCTSTR(*lpGetAddInName)();
		(FARPROC&)lpGetAddInName = GetProcAddress(hMod,"GetAddInName"); //-V614
		if(lpGetAddInName)
		{
			m_sName =lpGetAddInName();
//D			name += _T(" (")+GetOnlyFileName(path)+_T(")");
		}
		else{
//D			name = GetOnlyFileName(path);
		}
		(FARPROC&)lpGetAddInName = GetProcAddress(hMod,"GetAddInDescription");
		if(lpGetAddInName)
			m_sDescr =lpGetAddInName();
		else m_sDescr = _T("");
		if(flag==APL_LOAD_DATA)
		{
			bool (*lpGetViews)(CWnd*, RECT, UINT, CaplAddinViews*);
			bool (*lpCreateViewsEx)(CWnd*, RECT, UINT*, CaplAddinViews*);
			bool (*lpGetViewsEnum)(CaplAddinViews*);			

			(FARPROC&)lpCreateViewsEx = GetProcAddress(hMod,"CreateTabViewsEx"); //-V614
			if(lpCreateViewsEx)
			{
				lpCreateViewsEx(m_parent, CRect(0,0,0,0), m_allMess, m_global_views);		
			}
			else
			{
				(FARPROC&)lpGetViews = GetProcAddress(hMod,"CreateTabViews"); //-V614
				if(lpGetViews!=0)
					lpGetViews(m_parent,CRect(0,0,0,0),m_msg, m_global_views);
			}

			CaplAddinViews enumViews;
			(FARPROC&)lpGetViewsEnum = GetProcAddress(hMod,"GetTabViews"); //-V614
			if(lpGetViewsEnum!=0) lpGetViewsEnum(&enumViews);
			
			for(int n= 0; n<enumViews.GetSize(); n++)
			{
				CaplViewInfo* viewInfo= enumViews.GetAt(n);
				if(!viewInfo) continue;
				if(viewInfo->viewtype!=aplDocbar) continue;
				
				CreateDocbar(viewInfo, hMod);
			}
		}
		else
		{
			bool (*lpGetViews)(CaplAddinViews*);
			
			(FARPROC&)lpGetViews = GetProcAddress(hMod,"GetTabViews"); //-V614
			if(lpGetViews!=0) lpGetViews(m_local_views);
		}
	}
	else
	{
		m_sName =  APL_T("!! Не удалось подключить дополнение: ")+m_sPath;
		m_index = -1;

		if(err_log!=0){
			*err_log+=_T("\n")+m_sName;
		}else if(m_bShowWarningMessage){
			AfxMessageBox(m_sName, MB_SYSTEMMODAL|MB_OK);
		}

		CString str;
		while(f.ReadString(str))
		{
			if(str.IsEmpty()) continue;
			if(str[0]!=_T('-')){//костыли
				sPath= str;
				break;
			}
			else{
				m_sFileContents+=str+_T("\n");
			}
		}
		return -4;
	}

	CString str;
	while(f.ReadString(str))
	{
		int i;
		if(str.IsEmpty()) continue;

		m_sFileContents+=str+_T("\n");

		if(str[0]==_T('-'))
		{
			CString str1;
			for(i=0;i<m_Functions.GetSize();i++)
			{
				str1 = _T("-f")+m_Functions[i]->sType+_T(":")+m_Functions[i]->sFunction;
				if(str1==str) 
				{
					m_Functions[i]->flag= 0;
					break;
				}
			}
			for(i=0; i<m_local_views->GetSize();i++)
			{
				str1 = _T("-v:")+m_local_views->GetAt(i)->tab_name;
				if(str1==str)
				{
					m_local_views->SetFlagAt(i,false);
					break;
				}
				str1 = _T("-v")+m_local_views->GetAt(i)->tab_name;
				if(str1==str)
				{
					m_local_views->SetFlagAt(i,false);
					break;
				}
			}
		}
		else
		{
			//костыли
			sPath= str;
/*			f.Seek(file_pos,CFile::begin);*/
			return 0;
		}
//		file_pos = (DWORD)f.GetPosition();
	}
	return 0;
}

void CaplPluginItem::FreeItem()
{
	AfxFreeLibrary(m_hModule);
}

bool CaplPluginItem::UpdateItem()
{
	AfxFreeLibrary(m_hModule);
	CFileStatus fs;
	if(!CFile::GetStatus(m_sPath,fs)) return false;


	HMODULE hMod = AfxLoadLibrary(m_sPath);
	if(hMod)
	{
		m_hModule=hMod;
		LPFUNCTION lpFunc;
		bool (*lpGetFunctionsList)(CArray<CaplItemInfo*, CaplItemInfo*>*);
		(FARPROC&)lpGetFunctionsList = GetProcAddress(hMod,"GetFunctionsList"); //-V614
		if(lpGetFunctionsList)
		{
			CArray<CaplItemInfo*, CaplItemInfo*> items;
			lpGetFunctionsList(&items);
			
			m_Functions.Clear();
			
			for(int i=0; i<items.GetSize(); i++)
			{
				CaplItemInfo *item = items.GetAt(i);

				FunctionInfo* func_info= new FunctionInfo;

				func_info->sFunction= item->m_menuName;
				func_info->sType= item->m_treeItemType;
				if(!(0==item->m_image || -1==item->m_image))
				{
					func_info->ico=LoadIcon(hMod,MAKEINTRESOURCE(item->m_image));
				}

				func_info->sDescr= item->m_description;
				func_info->flag= 1;
				
				if(!item->m_functionName.IsEmpty())
				{
#ifdef _UNICODE
					CaplStringAdapter sFunctionName(item->m_functionName);
					(FARPROC&)lpFunc = GetProcAddress(hMod, (LPCSTR)sFunctionName);
#else
					(FARPROC&)lpFunc = GetProcAddress(hMod,item->m_functionName);
#endif
				}
				else
					lpFunc = NULL;
				func_info->lpFunction= lpFunc;
				
				m_Functions.Add(func_info);
			}
		}
		else
			return false;
		LPCTSTR(*lpGetAddInName)();
		(FARPROC&)lpGetAddInName = GetProcAddress(hMod,"GetAddInName"); //-V614
		if(lpGetAddInName)
		{
			m_sName =lpGetAddInName();
			m_sName += _T(" (")+GetOnlyFileName(m_sPath)+_T(")");
		}
		else{
//D			name = GetOnlyFileName(path);
		}
		(FARPROC&)lpGetAddInName = GetProcAddress(hMod,"GetAddInDescription");
		if(lpGetAddInName)
			m_sDescr =lpGetAddInName();
		else m_sDescr = _T("");
		bool (*lpGetViews)(CWnd*, RECT, UINT, CaplAddinViews*);
		bool (*lpCreateViewsEx)(CWnd*, RECT, UINT*, CaplAddinViews*);

		(FARPROC&)lpCreateViewsEx = GetProcAddress(hMod,"CreateTabViewsEx"); //-V614
		if(lpCreateViewsEx)
		{
			lpCreateViewsEx(m_parent, CRect(0,0,0,0), m_allMess, m_global_views);		
		}
		else
		{
			(FARPROC&)lpGetViews = GetProcAddress(hMod,"CreateTabViews"); //-V614
			if(lpGetViews!=0)
				lpGetViews(m_parent,CRect(0,0,0,0),m_msg, m_global_views);
		}
	}
	return true;
}

CString CaplPluginItem::Create(LPCTSTR file_name)
{
	CString p_name;
	m_sPath = file_name;
	HMODULE hModule = AfxLoadLibrary(file_name);
	if(hModule)
	{
		LPFUNCTION lpFunc;
		
		bool (*lpGetFunctList)(CArray<CaplItemInfo*,CaplItemInfo*>*);
		(FARPROC&)lpGetFunctList = GetProcAddress(hModule,"GetFunctionsList"); //-V614
		if(lpGetFunctList)
		{
			CArray<CaplItemInfo*,CaplItemInfo*> funtions;
			lpGetFunctList(&funtions);

			m_Functions.Clear();

			for(int f=0; f<funtions.GetSize();f++)
			{
				CaplItemInfo *item = funtions.GetAt(f);

				FunctionInfo* func_info= new FunctionInfo;

				func_info->sFunction= item->m_menuName;
				func_info->sType= item->m_treeItemType;
				if(!(0==item->m_image || -1==item->m_image))
				{
					func_info->ico=LoadIcon(hModule,MAKEINTRESOURCE(item->m_image));
				}

				func_info->sDescr= item->m_description;
				func_info->flag= 1;
				
				if(!item->m_functionName.IsEmpty())
				{
#ifdef _UNICODE
					CaplStringAdapter sFunctionName(item->m_functionName);
					(FARPROC&)lpFunc = GetProcAddress(hModule, (LPCSTR)sFunctionName);
#else
					(FARPROC&)lpFunc = GetProcAddress(hModule,item->m_functionName);
#endif
				}
				else
					lpFunc = NULL;
				func_info->lpFunction= lpFunc;

				m_Functions.Add(func_info);
			}
		}
		else
		{
			//					AfxMessageBox(NON_PSM_ADDIN_MODULE);
			AfxFreeLibrary(hModule);
			return _T("");
		}
		
		LPCTSTR(*lpGetAddInName)();
		(FARPROC&)lpGetAddInName = GetProcAddress(hModule,"GetAddInName"); //-V614
		if(lpGetAddInName!=NULL)
		{
			p_name = lpGetAddInName();
			m_sName = p_name;					
//D			if(p_name==_T("")) p_name = file_name;
//D			else p_name =p_name + _T(" (")+file_name+_T(")");
		}
		else
		{
//D			name = file_name;
//D			p_name = name;
			p_name = file_name;
		}
		(FARPROC&)lpGetAddInName = GetProcAddress(hModule,"GetAddInDescription");
		if(lpGetAddInName)
			m_sDescr =lpGetAddInName();
		bool (*lpGetViews)(CaplAddinViews*);
		(FARPROC&)lpGetViews = GetProcAddress(hModule,"GetTabViews"); //-V614
		if(lpGetViews!=0)
			lpGetViews(m_local_views);
	}
	return p_name;
}

void CaplPluginItem::CreateDocbar(CaplViewInfo *viewInfo, HMODULE hMod)
{
	CWnd*(*lpGetDBViews)(long, CWnd*, RECT, UINT, CaplAddinViews*);
	(FARPROC&)lpGetDBViews = GetProcAddress(hMod,"CreateDocbarViews"); //-V614
	if(!lpGetDBViews) return;
 	
	CaplAddInBar* new_bar= new CaplAddInBar;
	if(new_bar)
	{
		new_bar->m_type= viewInfo->type;
		new_bar->m_sAddInName= m_sName;
		new_bar->m_iViewID= viewInfo->viewid;
		new_bar->m_iBarID= m_doc->m_nIndex++;
		
		new_bar->LoadState(_T(""));
		CSize docSize(300, 50);

		if(new_bar->m_nRegDockBarID == AFX_IDW_DOCKBAR_TOP || 
			new_bar->m_nRegDockBarID == AFX_IDW_DOCKBAR_BOTTOM)
			docSize= new_bar->m_szHorz;
		else if(new_bar->m_nRegDockBarID == AFX_IDW_DOCKBAR_LEFT || 
			new_bar->m_nRegDockBarID == AFX_IDW_DOCKBAR_RIGHT)
			docSize= new_bar->m_szVert;

		if (!new_bar->Create(viewInfo->tab_name, m_frame, docSize, TRUE, new_bar->m_iBarID))
			return;
		
		new_bar->SetBarStyle(new_bar->GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

		new_bar->EnableDocking(CBRS_ALIGN_ANY);
		m_frame->EnableDocking(CBRS_ALIGN_ANY);
		m_frame->DockControlBar(new_bar, new_bar->m_nRegDockBarID);
		
		CWnd* viewWnd= lpGetDBViews(viewInfo->viewid, new_bar, CRect(0,0,0,0), m_msg, m_global_views);
		if(!viewWnd){ delete new_bar; return;}
		m_doc->m_additional_ctrlbars.Add(new_bar);
		
		new_bar->AttachWnd(viewWnd);
		m_frame->ShowControlBar(new_bar, FALSE, FALSE);
	}
}
bool CaplPluginItem::CreateDocbars()
{
	if(!m_hModule) 
		return false;

	bool (*lpGetViewsEnum)(CaplAddinViews*);			

	if(!m_local_views->GetSize())
	{
		(FARPROC&)lpGetViewsEnum = GetProcAddress(m_hModule,"GetTabViews"); //-V614
		if(lpGetViewsEnum!=0) lpGetViewsEnum(m_local_views);
	}

	for(int n= 0; n<m_local_views->GetSize(); n++)
	{
		CaplViewInfo* viewInfo= m_local_views->GetAt(n);
		if(!viewInfo) continue;
		if(viewInfo->viewtype!=aplDocbar) 
			continue;

		CreateDocbar(viewInfo, m_hModule);
	}

	return true;
}

bool CaplPluginItem::CreateTabViews()
{
	if(!m_hModule) 
		return false;

	bool (*lpGetViews)(CWnd*, RECT, UINT, CaplAddinViews*);
	bool (*lpCreateViewsEx)(CWnd*, RECT, UINT*, CaplAddinViews*);

	(FARPROC&)lpCreateViewsEx = GetProcAddress(m_hModule,"CreateTabViewsEx"); //-V614
	if(lpCreateViewsEx)
	{
		lpCreateViewsEx(m_parent, CRect(0,0,0,0), m_allMess, m_global_views);		
	}
	else
	{
		(FARPROC&)lpGetViews = GetProcAddress(m_hModule,"CreateTabViews"); //-V614
		if(lpGetViews!=0)
			lpGetViews(m_parent,CRect(0,0,0,0), m_msg, m_global_views);
	}

	return true;
}


bool CaplPluginItem::InitMenuItems(long &iIndex, CArray<CaplAddInMenuItem, CaplAddInMenuItem> & addin_menu_items)
{
	for(int i=0; i<m_Functions.GetSize();i++)
	{
		if(iIndex>ID_PLUGIN_150)
			break;

		CaplAddInMenuItem item(iIndex++, m_Functions[i]->sType,m_Functions[i]->sFunction,m_Functions[i]->ico,
			m_sPath,m_sName,m_Functions[i]->sFunction,(LPADDINFUNCTION)m_Functions[i]->lpFunction,
			m_hModule, (m_Functions[i]->flag==0)?false:true,m_Functions[i]->iFunctionParamType);

		CaplMenu::AddIcon(item.m_id,m_Functions[i]->ico,true);

		addin_menu_items.Add(item);
	}	

	return true;
}