// aplEntryView.cpp : implementation file
//

#include "stdafx.h"
#include "aplEntryView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CaplEntryView

IMPLEMENT_DYNCREATE(CaplEntryView, CaplPropsView)

CaplEntryView::CaplEntryView()
{
	m_bCanEdit = true;
	m_bIsActiveVer = false;
	m_pParent = NULL;
	m_edit_wnd = NULL;
	m_list = NULL;

	m_nCurrentItem = -1;
}

CaplEntryView::~CaplEntryView()
{
}


BEGIN_MESSAGE_MAP(CaplEntryView, CaplPropsView)
	//{{AFX_MSG_MAP(CaplEntryView)
	ON_WM_LBUTTONDBLCLK()
	ON_WM_DESTROY()		
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CaplEntryView drawing

void CaplEntryView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CaplEntryView diagnostics

#ifdef _DEBUG
void CaplEntryView::AssertValid() const
{
	CView::AssertValid();
}

void CaplEntryView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CaplEntryView message handlers


BOOL CaplEntryView::InitColumns(void)
{
	CaplInstance *inst = NULL;
	
	// смотрим является ли текущая версия активной
	
	if(m_inst)
	{
		if(m_inst->GetAccessmode()<aplNO)
		{
			apidata.GetAttr(m_inst, m_api->m_doc_mgr.a_apl_doc_rev_doc, inst);
			apidata.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_active, inst);
			m_api->m_doc_mgr.LoadDocInfo(m_inst);
				
			if(inst == m_inst)
				m_bIsActiveVer = true;
			else
				m_api->m_doc_mgr.LoadDocInfo(inst);
			
			// смотрим есть ли права
			if(m_inst->GetAccessmode() >= aplRO)
				m_bCanEdit = false;

			// смотрим есть ли специальная роль
			if(UserHasSpecialRole())
				m_bCanEdit = true;
		}
	}
	else
	{
		m_bIsActiveVer = true;
	}	
	
	CListCtrl*	pList	=	NULL;

	CString		csTxt1[] = 	{ APL_T("Постоянный"), APL_T("Код"),  APL_T("Реквизит"), APL_T("Значение активной версии"),  APL_T("Значение текущей версии"),  APL_T("Описание")};	
	int			iSz1[]	=	{40, 60, 150, 120, 120, 400};

	CString		csTxt2[] = 	{ APL_T("Постоянный"), APL_T("Код"),  APL_T("Реквизит"), APL_T("Значение текущей версии"),  APL_T("Описание")};	
	int			iSz2[]	=	{80, 80, 200, 120, 400};

	int			i;
	int			*pSz = NULL;
	CString		*pTxt = NULL;

	pList=&GetListCtrl();
	if(NULL==pList)
		return FALSE;

	if(!m_bIsActiveVer)
	{
		for(i=0;i<sizeof(iSz1)/sizeof(int);i++)
			pList->InsertColumn(i,csTxt1[i],LVCFMT_LEFT,iSz1[i]);
	}
	else
	{
		for(i=0;i<sizeof(iSz2)/sizeof(int);i++)
			pList->InsertColumn(i,csTxt2[i],LVCFMT_LEFT,iSz2[i]);
	}

	m_image.Create(16, 16, ILC_COLOR16|ILC_MASK, 0, 5);
	m_image.Add(GetAplStdIco16(APL_STD_24STAR));
	pList->SetImageList(&m_image, LVSIL_SMALL);
	//pList->SetImageList(aplGetInstImageList(),LVSIL_SMALL);
				
	long lStyles=::GetWindowLong(GetListCtrl().m_hWnd,GWL_STYLE);
	lStyles|=LVS_SINGLESEL|LVS_SHOWSELALWAYS;
	::SetWindowLong(GetListCtrl().m_hWnd,GWL_STYLE,lStyles);

	m_pProps->EnableWindow(FALSE);

	return TRUE;
}

bool CaplEntryView::UserHasSpecialRole()
{
	aplExtent ext;
	CString t_str, buf;
	//CaplInstance *user = m_api->m_data.GetCurrUser();
	CaplInstance *inst=m_api->m_appr_mgr.GetCurrentPerson();
	if(!inst) return false;
	// ищем у пользователя роль технолога по расцеховке
	m_api->m_data.GetAttr(inst, m_api->m_appr_mgr.a_pers_roles, ext);

	m_api->m_options_mgr.GetOptionValueBN( APL_NO_T("Роли\\Роль для изменения реквизитов электронных документов"), t_str, _T(""));
	if(t_str.IsEmpty()) return false;

	if(m_api->m_appr_mgr.CheckPersonRole(0,t_str))
	{
		if(!m_api->m_data.GetAdminMode())
		{
			m_adminmode.SetData(&(m_api->m_data));
			m_adminmode.StartAdminMode(-1,-1,DEF_SOURCE);
		}
		return true;
	}

	return false;
}

BOOL CaplEntryView::LoadData(void)
{
	m_list=&GetListCtrl();

	CaplInstance *ciDoc = NULL, *ciDocType = NULL;
	CListCtrl *pList=&GetListCtrl();

	pList->DeleteAllItems();
	m_aeItems.Clear();
	
	if(NULL==m_api)
		return TRUE;	

	// загружаем по порядку: реквизиты вида документа, реквизиты активной версии, реквизиты текущей версии
	
	if(m_inst == NULL)
	{
		m_aeItems.Add(m_pParent->m_dt);
		m_aeItems.Append(m_pParent->m_aeEntryToCreate);
	}
	else if(apidata.IsKindOf(m_inst,m_api->m_doc_mgr.e_apl_doc_rev))
	{
		if(m_inst->GetAccessmode()<aplNO)
		{
			//вид документа
			if(m_pParent->m_dt == NULL)
			{
				apidata.GetAttr(m_inst, m_api->m_doc_mgr.a_apl_doc_rev_doc, ciDoc);
				apidata.GetAttr(ciDoc, m_api->m_doc_mgr.a_doc_kind, ciDocType);
			}
			else
			{
				ciDocType = m_pParent->m_dt;
			}

			if(ciDocType) m_aeItems.Add(ciDocType);	
			m_api->LoadItemInfo(m_inst);
		}	
		//текущяя версия
		m_aeItems.Add(m_inst);				
	}

	return TRUE;
}

BOOL CaplEntryView::_FillItem(int iPos,CaplInstance* ciIn)
{
	CArray<int, int> caStringToDel;
	aplExtent ext;
	bool				bOptional = false;
	CaplInstance*		cit		=	NULL;
	CListCtrl*			pList	=	NULL;
	CString				t_str;
	
	m_pDel->ShowWindow(SW_HIDE);
	m_pAdd->ShowWindow(SW_HIDE);

	if(NULL==m_api)
		return FALSE;

	if(NULL==ciIn)
		return FALSE;

	pList=&GetListCtrl();
	if(NULL==pList)
		return FALSE;

	if(ciIn->GetAccessmode()>aplRO)
		return FALSE;

	// заполняем информацию о реквизите (из вида документа)
	if(apidata.IsKindOf(ciIn, m_api->m_doc_mgr.e_dt))
	{		
		apidata.GetAttr(ciIn, m_api->m_doc_mgr.a_dt_entries, ext);
		m_api->LoadExtentInfo(ext);
		int i;
		int col_descr=4;
		if(!m_bIsActiveVer)col_descr++;

		for (i = 0; i < ext.GetSize(); i++)
		{
			if(false == m_api->m_data.IsKindOf(ext[i], m_api->m_doc_mgr.e_dt_entry))
				continue;

			// структура для информации о строке
			apidata.GetAttr(ext[i], m_api->m_doc_mgr.a_dt_entry_opt, bOptional);
			int nIco = -1;
			if(!bOptional) nIco = 0;
			iPos=pList->InsertItem(i,_T(""), nIco);

			apidata.GetAttr(ext[i], m_api->m_doc_mgr.a_dt_entry_entry, cit);
			if(!cit) {caStringToDel.Add(i); continue;}
			
			apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_id, t_str);
			pList->SetItemText(iPos, 1, t_str);

			apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_name, t_str);
			pList->SetItemText(iPos, 2, t_str);

			apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_descr, t_str);
			pList->SetItemText(iPos, col_descr, t_str);

			sData *data = new sData;
			data->m_ciDocEntry = NULL;
			data->m_ciDocRevVal = NULL;
			data->m_ciDocEntry = ext[i];
			pList->SetItemData(i, (DWORD)data);
			m_caData.Add(data);			
		}

		for (i = 0; i < caStringToDel.GetSize(); i++)
			m_list->DeleteItem(caStringToDel[i]);
	}
	else if(apidata.IsKindOf(ciIn, m_api->m_doc_mgr.e_apl_doc_rev))
	{
		int nCol = 4;

		// заполняем информацию из текущей версии
		if(m_bIsActiveVer) nCol = 3;

		FillEntryFromDocVer(m_bIsActiveVer, ciIn, nCol);		
				
		// заполняем информацию из активной версии
		if(!m_bIsActiveVer)
		{
			apidata.GetAttr(ciIn, m_api->m_doc_mgr.a_apl_doc_rev_doc, cit);
			apidata.GetAttr(cit, m_api->m_doc_mgr.a_apl_doc_active, cit);
			
			FillEntryFromDocVer(true, cit, 3, false);
		}	
	}	
	else if(apidata.IsKindOf(ciIn, m_api->m_doc_mgr.e_doc_entry_val))
	{
		int nCol = 4;

		if(m_bIsActiveVer) nCol = 3;

		CreateListItem(ciIn, nCol, true);
	}
	
	return TRUE;
}

void CaplEntryView::CreateListItem(CaplInstance *ciIn, int nCol, bool bAddData)
{
	int nPos;
	CString t_str;
	sData *data = NULL;
	CaplInstance *cit = NULL;
	CListCtrl *pList = &GetListCtrl();	
	if(NULL==ciIn) return;

	apidata.GetAttr(ciIn, m_api->m_doc_mgr.a_doc_entry_val_entry, cit);
	if(NULL==cit) return;
	
	apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_name, t_str);
	nPos = GetSameEntryFromList(t_str);
	bool bDate = !t_str.CompareNoCase(APL_T("дата создания"));
	if(nPos != -1)
	{	

		apidata.GetAttr(ciIn, m_api->m_doc_mgr.a_doc_entry_val_val, t_str);
		if (bDate)
		{
			COleDateTime odt;
			aplString2Date(t_str,odt);
			t_str = odt.Format(_T("%d.%m.%Y %H:%M:%S"));
		}
		
		pList->SetItemText(nPos, nCol, t_str);
		
		if(bAddData)
		{
			data = (sData*)pList->GetItemData(nPos);
			data->m_ciDocRevVal = ciIn;
		}
	}
	else
	{
		// случай, когда реквизиты есть у версии, но нет у вида документа
		
		sData *data = new sData;
		data->m_ciDocEntry = NULL;
		data->m_ciDocRevVal = NULL;
		
		apidata.GetAttr(ciIn, m_api->m_doc_mgr.a_doc_entry_val_entry, cit);
		if(!cit) return;
		
		nPos=pList->InsertItem(pList->GetItemCount(),_T(""), -1);
		
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_id, t_str);
		pList->SetItemText(nPos, 1, t_str);
		
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_name, t_str);
		pList->SetItemText(nPos, 2, t_str);
		
		apidata.GetAttr(ciIn, m_api->m_doc_mgr.a_doc_entry_val_val, t_str);
		if (bDate)
		{
			COleDateTime odt;
			aplString2Date(t_str,odt);
			t_str = odt.Format(_T("%d.%m.%Y %H:%M:%S"));
		}
		pList->SetItemText(nPos, nCol, t_str);
		
		data->m_ciDocRevVal = ciIn;
		pList->SetItemData(nPos, (DWORD)data);
		m_caData.Add(data);		
	}	
}

void CaplEntryView::FillEntryFromDocVer(bool bActive, CaplInstance *cit, int nCol, bool bAddData)
{
	int nPos = -1;
	aplExtent ext;
	sData *data = NULL;
	CString t_str, sName;
	CaplInstance *ciEntry = 0;
	CListCtrl *pList = &GetListCtrl();

	if(NULL==cit) return;
	if(cit->GetAccessmode()>aplRO) return;

	apidata.GetAttr(cit, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
	m_api->LoadExtentInfo(ext);
		
	for(int i=0; i<ext.Size; i++)
	{
		sName=_T("");
		m_api->m_data.GetAttr(ext[i], m_api->m_doc_mgr.a_doc_entry_val_entry, ciEntry);
		if(ciEntry) m_api->m_data.GetAttr(ciEntry, m_api->m_doc_mgr.a_entry_name, sName);
		sName.MakeLower();

		CreateListItem(ext[i], nCol, bAddData);					
	}
}

int CaplEntryView::GetSameEntryFromList( CString sName )
{
	CListCtrl* pList=&GetListCtrl();
	if(NULL==pList) return -1;
	
	for(int i=0; i<pList->GetItemCount(); i++)
	{
		if(!sName.CompareNoCase(pList->GetItemText(i, 2)))
			return i;
	}

	return -1;
}

bool CaplEntryView::CanChangeEntryVal(CaplInstance *cit)
{
	CString t_str;

	if(NULL==cit) return false;

	CStringArray saProtectedEntries;
	saProtectedEntries.Add( APL_T("вид документа")); 
	saProtectedEntries.Add( APL_T("код вида документа"));
	saProtectedEntries.Add( APL_T("имя файла"));
	saProtectedEntries.Add( APL_T("версия документа"));
	saProtectedEntries.Add( APL_T("дополнительный код вида документа"));
	saProtectedEntries.Add( APL_T("код документа в зависимости от характера использования"));
	saProtectedEntries.Add( APL_T("признак аутентичного документа"));
	saProtectedEntries.Add( APL_T("литера"));

	if(m_api->m_data.IsKindOf(cit, m_api->m_doc_mgr.e_entry))
	{
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_card_field, t_str);
	}
	else if(m_api->m_data.IsKindOf(cit, m_api->m_doc_mgr.e_dt_entry))
	{
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_dt_entry_entry, cit);
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_card_field, t_str);
	}
	else return false;

	t_str.MakeLower();
	for(int i=0; i<saProtectedEntries.GetSize(); i++)
	{
		if(t_str == saProtectedEntries[i])
		{
			AfxMessageBox( APL_T("Значение этого реквизита можно изменять только из карточки документа!"), MB_ICONINFORMATION);
			return false;
		}
	}

	return true;
}

void CaplEntryView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	if(m_bCanEdit)
	{
		aplExtent ext;
		CaplInstance *cit = NULL;

		// проверка на тип
		if(m_pParent->m_dt == NULL)
		{
			AfxMessageBox( APL_T("Не выбран вид документа"), MB_ICONINFORMATION);
			return;
		}
		else
		{
			if(m_inst)
				apidata.GetAttr(m_inst, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
			else
				ext.Append(m_pParent->m_aeEntryToCreate);

			if(ext.Size == 0)
			{
				apidata.GetAttr(m_pParent->m_dt, m_api->m_doc_mgr.a_dt_entries, ext);
				if(ext.Size == 0)
				{
					AfxMessageBox( APL_T("Для данного вида документа реквизиты не заданы!"), MB_ICONINFORMATION);
					return;
				}
			}
		}

		LVHITTESTINFO pInfo;
		pInfo.pt = point;
		m_list->SubItemHitTest(&pInfo);
		int j = pInfo.iSubItem;
		m_nCurrentItem = pInfo.iItem;

		if(pInfo.iItem == -1) return;
		
		cit = NULL;
		sData *data = (sData*)m_list->GetItemData(pInfo.iItem);
					
		cit = data->m_ciDocEntry;
		if(cit == NULL)
			apidata.GetAttr(data->m_ciDocRevVal, m_api->m_doc_mgr.a_doc_entry_val_entry, cit);
		
		if(!CanChangeEntryVal(cit)) return;

		CRect  rect( 10,0,200,30 );
		m_list->GetSubItemRect( m_nCurrentItem, j, LVIR_BOUNDS, rect);
			
		ext.Clear();
		if(j == m_list->GetHeaderCtrl()->GetItemCount()-2)
		{
			CString t_str;
			CaplAggr aggr;

			// получаем значения по умолчанию
			if(apidata.IsKindOf(cit, m_api->m_doc_mgr.e_dt_entry))
				apidata.GetAttr(cit, m_api->m_doc_mgr.a_dt_entry_entry, cit);				
			
			apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_val, aggr);
			
			while(m_edit.GetCount())
				m_edit.DeleteString(0);

			for(int i=0; i<aggr.GetSize(); i++)
			{
				aggr.GetByIndex(i, t_str);
				m_edit.InsertString(0, t_str);
			}

			rect.bottom+=200;
			m_edit.MoveWindow(rect);
			m_edit.ShowWindow(SW_SHOW);
			m_edit_wnd=&m_edit;	
			
			m_edit.SetWindowText(m_list->GetItemText(m_nCurrentItem, j));
			m_edit.SetFocus();
			m_edit.GetWindowText(m_sPrevVal);
		}
	}
	
	CaplPropsView::OnLButtonDblClk(nFlags, point);
}

bool CaplEntryView::ChangeDocCard(CaplInstance *ciEntryVal, CString sValue)
{
	CString sCardField;
	CaplInstance *cit = NULL;
	CWnd *pEdit = NULL;
	
	if(NULL==ciEntryVal)return false;

	apidata.GetAttr(ciEntryVal, m_api->m_doc_mgr.a_doc_entry_val_entry, cit);
	apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_card_field, sCardField);
	sCardField.MakeLower();

	if(!sCardField.CompareNoCase( APL_NO_T("обозначение")))
	{
		pEdit = &m_pParent->m_doc_id_ctrl;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("наименование"))) 
	{
		pEdit = &m_pParent->m_doc_name_ctrl;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("литера")))
	{
		pEdit = &m_pParent->m_litera_ctrl;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("формат")))
	{
		pEdit = &m_pParent->m_format_ctrl;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("метка")))
	{
		pEdit = &m_pParent->m_label_ctrl;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("версия документа")))
	{
		pEdit = &m_pParent->m_edit_rev_id;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("лист")))
	{
		pEdit = &m_pParent->m_of_list;	
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("листов")))
	{
		pEdit = &m_pParent->m_of_lists;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("признак аутентичного документа")))
	{
		if(sValue == _T("0")) m_pParent->m_autent.SetCheck(0);
		else m_pParent->m_autent.SetCheck(1);
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("дополнительный код вида документа")))
	{
		pEdit = &m_pParent->m_dkvd;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("инвентарный номер")))
	{
		pEdit = &m_pParent->m_inv_num_ctrl;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("код документа в зависимости от характера использования")))
	{
		pEdit = &m_pParent->m_kdvzohi;
	}
	else if(!sCardField.CompareNoCase( APL_NO_T("дата создания")))
	{
		COleDateTime dt;

		//0123456789012345678
		//11.11.1911 11:11:11

		int nYear,  nMonth,  nDay,  nHour,  nMin,  nSec;

		nYear=_atoi(LPCTSTR(sValue.Mid(6,4)));
		nMonth=_atoi(LPCTSTR(sValue.Mid(3,2)));
		nDay=_atoi(LPCTSTR(sValue.Mid(0,2)));
		nHour=_atoi(LPCTSTR(sValue.Mid(11,2)));
		nMin=_atoi(LPCTSTR(sValue.Mid(14,2)));
		nSec=_atoi(LPCTSTR(sValue.Mid(17,2)));
		nSec = nSec<60?nSec:0;
		nMin = nMin<60?nMin:0;
		nHour = nHour<24? nHour:0;
		dt.SetDateTime(nYear,  nMonth,  nDay,  nHour,  nMin,  nSec);
		m_pParent->m_rev_date_ctrl.SetTime(dt);
	}


	if(pEdit) pEdit->SetWindowText(sValue);
	return true;
}

CaplInstance * CaplEntryView::CreateEntryValue( CaplInstance *ciDocRevValPrev, CaplInstance *ciEntry, CaplInstance *ciDocRev, CString sValue )
{
	aplExtent ext;
	CaplInstance *cit = NULL;
	if(!ciDocRevValPrev && sValue.IsEmpty()) return NULL;
	
	cit = apidata.CreateInstance(m_api->m_doc_mgr.e_doc_entry_val);
	apidata.PutAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_entry, ciEntry);
	apidata.PutAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_val, sValue);
	apidata.PutAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_stored, false);

	if(ciDocRev)
	{
		apidata.GetAttr(ciDocRev, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
		ext.Add(cit);
		apidata.PutAttr(ciDocRev, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
	}	

	m_api->SaveChanges();
	m_pParent->m_aeEntryToCreate.Add(cit);

	return cit;
}

CaplInstance* CaplEntryView::IsEntryAlreadyExist( CaplInstance *ciDocRev, CString sValue, CaplInstance *&ciDocEntryVal )
{
	aplExtent ext;
	CString t_str;
	CaplInstance *cit = NULL;

	if(ciDocRev)
		apidata.GetAttr(ciDocRev, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
	else
		ext.Append(m_pParent->m_aeEntryToCreate);

	for(int i=0; i<ext.GetSize(); i++)
	{
		apidata.GetAttr(ext[i], m_api->m_doc_mgr.a_doc_entry_val_entry, cit);
		if(!cit) continue;
		
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_entry_card_field, t_str);
		if(!t_str.CompareNoCase(sValue))
		{
			ciDocEntryVal = ext[i];			
		}
	}

	return ciDocEntryVal;	
}

void CaplEntryView::OnDestroy() 
{
	for(int i=0; i<m_caData.GetSize(); i++)
		delete m_caData[i];

	CaplPropsView::OnDestroy();
}

void CaplEntryView::CreateEditBox()
{
	CRect  rect( 0,0,1,0);
	DWORD dwStyle = WS_CHILD|CBS_DROPDOWN|CBS_SORT|WS_BORDER|CBS_AUTOHSCROLL;
	m_edit.Create(dwStyle, rect, m_list, IDC_EDIT_BOX_CTRL);
	
	m_edit.SetFont(m_list->GetFont());
}

void CaplEntryView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	LVHITTESTINFO pInfo;
	pInfo.pt = point;
	m_list->SubItemHitTest(&pInfo);
	
	HideEditBox();
	
	CaplPropsView::OnLButtonDown(nFlags, point);
}

bool CaplEntryView::ChangeEntryVal( CString sValue, CString sName, int nItem )
{
	if(nItem == -1) return false;

	CString sEntryName;
	bool bStored = false;
	sData *data = (sData*)m_list->GetItemData(nItem);
	CaplInstance *cit = NULL, *ciEntryVal = NULL, *ciEntry;
	
	// смотрим: есть ли такой реквизит уже
	// cit будет последним значением реквизита в сете

	cit = data->m_ciDocRevVal;
	//IsEntryAlreadyExist(m_inst, sName, cit);

	if(cit)
	{
		apidata.GetAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_stored, bStored);
		
		// подписей не было
		if(!bStored)	
		{
			apidata.PutAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_val, sValue);					
		}
		// подписи были
		else
		{
			// если значения совпадают, то объект apl_document_rev_entry не создаем
			CString sTemp;
			apidata.GetAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_val, sTemp);
			if(!sTemp.Compare(sValue)) return false;
			
			aplExtent ext;
			apidata.GetAttr(cit, m_api->m_doc_mgr.a_doc_entry_val_entry, ciEntry);
			
			ciEntryVal = m_api->m_data.CreateInstance(m_api->m_doc_mgr.e_doc_entry_val);
			apidata.PutAttr(ciEntryVal, m_api->m_doc_mgr.a_doc_entry_val_stored, true);
			apidata.PutAttr(ciEntryVal, m_api->m_doc_mgr.a_doc_entry_val_val, sValue);
			apidata.PutAttr(ciEntryVal, m_api->m_doc_mgr.a_doc_entry_val_prev, cit);
			apidata.PutAttr(ciEntryVal, m_api->m_doc_mgr.a_doc_entry_val_entry, ciEntry);
			
			apidata.GetAttr(m_inst, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
			ext.Add(ciEntryVal);
			apidata.PutAttr(m_inst, m_api->m_doc_mgr.a_apl_doc_rev_entries, ext);
			
			// новое значение заносим в список карточки документа
			data->m_ciDocRevVal = ciEntryVal;
		}
	}
	else
	{
		m_api->m_data.GetAttr(data->m_ciDocEntry, m_api->m_doc_mgr.a_dt_entry_entry, cit);
		cit = CreateEntryValue(NULL, cit, m_inst, sValue);
		m_pParent->m_aeEntryToCreate.Add(cit);
		
		if(m_inst == NULL)
			data->m_ciDocRevVal = cit;
	}
	
	// добавляем новый элемент
	if(cit)
	{
		m_list->SetItemText(nItem, m_list->GetHeaderCtrl()->GetItemCount()-2, sValue);				
		sName.MakeLower();
		
		// изменяем иформацию о версии документа в карточке "Свойсвта документа"
		if(data->m_ciDocEntry)
		{
			m_api->m_data.GetAttr(data->m_ciDocEntry, m_api->m_doc_mgr.a_dt_entry_entry, ciEntry);
			m_api->m_data.GetAttr(ciEntry, m_api->m_doc_mgr.a_entry_name, sEntryName);
			sEntryName.MakeLower();

			if(m_bIsActiveVer)
			{
				ChangeDocCard(cit, sValue);
			}
			else
			{
				if(m_api->m_doc_mgr.EntryForDocumentVersion(ciEntry))
					ChangeDocCard(cit, sValue);
			}
		}
	}

	m_api->SaveChanges();
	
	return true;
}

void CaplEntryView::ParseMailList(CString& csInMailList,CString csDepotSep,CString csGrpSep,
							  CStringArray* csapOutDepots,CStringArray* csapOutGrps)
{
	CString		csAll,csPart,csDep,csGrp;

	int			iLen4Del=-1;
	if(csInMailList.IsEmpty()) return;

	csAll=csInMailList;
	
	int nIndex = csAll.Find(APL_T("П"));
	if(nIndex != -1)
	{
		csAll = csAll.Left(nIndex - 1);
	}
	else 
	{
		nIndex = csAll.Find(APL_T("Т"));
		if(nIndex != -1)
		{
			csAll = csAll.Left(nIndex - 1);
		}
	}

	do 
	{
		csPart=_T("");csDep=_T("");csGrp=_T("");
		
		//	получаем цех (и группу, если есть)
		csPart=csAll.SpanExcluding(csDepotSep); //-V519
		//	получаем только цех
		csDep=csPart.SpanExcluding(csGrpSep); //-V519

		//	получаем группу
		if(csDep.GetLength()<csPart.GetLength())
			csGrp=csPart.Right(csPart.GetLength()-csDep.GetLength()-1);

		if(NULL!=csapOutDepots)
			csapOutDepots->Add(csDep);

		if(NULL!=csapOutGrps)
			csapOutGrps->Add(csGrp);

		iLen4Del=csPart.GetLength();
		if(csAll.GetLength()>=csPart.GetLength()+1)
			iLen4Del++;
		csAll.Delete(0,iLen4Del);
	} 
	while(_T("")!=csAll);
}

bool CaplEntryView::CheckForValidDepot(CString sMailList)
{
	CString sTemp = _T("");
	CaplInstance *inst = NULL;
	CString sPokrCeh, sTermoCeh;
	CStringArray sOutDepot, sOutGrp;
	ParseMailList(sMailList, _T(";"), _T("/"), &sOutDepot, &sOutGrp);

	//проверяем есть ли такие цеха вообче
	for(int i=0; i<sOutDepot.GetSize(); i++)
	{
		inst = m_api->m_appr_mgr.FindOrganizationById(sOutDepot[i]);
		if(inst == NULL) sTemp = sTemp  + sOutDepot[i] + _T(", ");
	}

	if(!sTemp.IsEmpty())
	{
		CString t_str;
		sTemp = sTemp.Left(sTemp.GetLength()-2);
		t_str.Format( APL_T("Не удалось найти следующие цеха: %s."), sTemp);
		AfxMessageBox(t_str, MB_OK|MB_ICONSTOP);
		return false;
	}
	
	return true;
}

bool CaplEntryView::DoesMailListCorrect(CString sMailList, bool bShowErrMsg)
{
	int i = 0;
	bool bResult = false;
	CStringArray saDp, saGrp;
	int nNotEmptyGrp=0, nComaPoint=0, nSlash=0, nIndex=0;

	// пустой - значит правильный
	if(sMailList.IsEmpty()) return true;

	// пробелов в списке рассылки быть не должно
	if(-1 == sMailList.Find(_T(' ')))
	{
		// по-началу все хорошо =))
		bResult = true;

		// ищем количество знаков ","
		for(i=0; i<sMailList.GetLength(); i++)
			if(sMailList[i] == _T(';')) nComaPoint++;			
		
		// получаем массив групп и цехов
		ParseMailList(sMailList, _T(";"), _T("/"), &saDp, &saGrp);

		// анализируем рацеховку на правильность
		if(nComaPoint+1 != saDp.GetSize()) bResult = false;
		for(i=0; i<saDp.GetSize(); i++) if(saDp[i].IsEmpty()) bResult = false;		
	}
	
	if(!bResult && bShowErrMsg) AfxMessageBox( APL_T("Список рассылки имеет неверный формат! Нужный формат:  Х,Х,Х"), MB_ICONSTOP);
	return bResult;			
}

void CaplEntryView::HideEditBox(bool bCreateVal)
{
	if(m_edit_wnd)
	{
		CString t_str, sName = m_list->GetItemText(m_nCurrentItem, 2), sEntryName;
		m_edit.GetWindowText(t_str);
		
		if(bCreateVal)
		{
			if(t_str.Compare(m_list->GetItemText(m_nCurrentItem, m_list->GetHeaderCtrl()->GetItemCount()-2)))
			{
				CaplInstance *cit = NULL;
				sData *data = (sData*)m_list->GetItemData(m_nCurrentItem);
				
				if(data->m_ciDocEntry)
				{
					m_api->m_data.GetAttr(data->m_ciDocEntry, m_api->m_doc_mgr.a_dt_entry_entry, cit);
					m_api->m_data.GetAttr(cit, m_api->m_doc_mgr.a_entry_card_field, sName);

					// список рассылки необходимо проверять на корректность
					m_api->m_data.GetAttr(cit, m_api->m_doc_mgr.a_entry_name, sEntryName);
					sEntryName.MakeLower();
					if(sEntryName ==  APL_T("список рассылки"))
						if(!DoesMailListCorrect(t_str, true) || !CheckForValidDepot(t_str))
							t_str = m_sPrevVal;	
					if (!sEntryName.CompareNoCase(APL_T("Дата создания")))
					{
						if (!IsDateCorrect(t_str))
							t_str = m_sPrevVal;	
					}
				}

				// меняем значение реквизита
				ChangeEntryVal(t_str, sName, m_nCurrentItem);			
			}
		}
				
		m_edit_wnd->ShowWindow(SW_HIDE);
		m_edit_wnd->SetWindowText(_T(""));
	}		
	
	m_nCurrentItem = -1;
	m_edit_wnd=0;	
}

BOOL CaplEntryView::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->message == WM_KEYDOWN)
	{
		if(m_edit_wnd)
		{
			if(pMsg->wParam == VK_RETURN)
			{
				HideEditBox();
				m_edit.ShowDropDown(FALSE);
				return TRUE;
			}
			else if(pMsg->wParam == VK_ESCAPE)
			{
				HideEditBox(false);		
				m_edit.ShowDropDown(FALSE);
				return TRUE;
			}
		}
	}
	
	return CaplPropsView::PreTranslateMessage(pMsg);
}

bool CaplEntryView::IsDateCorrect(CString sDate)
{
	if (sDate.GetLength()!=19)
		return false;
	COleDateTime odt;
	//0123456789012345678
	//11.11.1911 11:11:11
	if (sDate[2]!=_T('.')||sDate[5]!=_T('.')||sDate[10]!=_T(' ')||sDate[13]!=_T(':')||sDate[16]!=_T(':'))
		return false;

	return true;
}