// ManagerEffectivityDlg.cpp : implementation file
//

#include "stdafx.h"
#include <apl_gui.h>
#include "apl_api.h"

#include "ManagerEffectivityDlg.h"
#include "AddRuleDate.h"
#include "AddSerialNum.h"
#include "StepData.h"

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

//IMPLEMENT_DYNAMIC(CManagerEffectivityDlg, CDialog );

CManagerEffectivityDlg::CManagerEffectivityDlg(CWnd* pParent)
	: CResizableDialog (CManagerEffectivityDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CManagerEffectivityDlg)
	m_width = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_api=0;
	m_pdf=0;
	m_rel=0;
	isSize=false;
	isDraw=false;

}

void CManagerEffectivityDlg::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog ::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CManagerEffectivityDlg)
	DDX_Control(pDX, IDC_CHANGE, m_change_btn);
	DDX_Control(pDX, IDC_DELETE, m_del_btn);
	DDX_Control(pDX, IDC_ADD, m_add_btn);
	DDX_Control(pDX, IDC_SAMPLE, m_sample);
	DDX_Control(pDX, IDC_SPINWIDTH, m_spinWidth);
	DDX_Control(pDX, IDC_PRODUCT, m_in_prd_ctrl);
	DDX_Control(pDX, IDC_EFFECT, m_eff_ctrl);
	DDX_Control(pDX, IDC_SPINTAB, m_spinTab);
	DDX_Control(pDX, IDC_EDIT_VERSION, m_version);
	DDX_Control(pDX, IDC_EDIT_NAME, m_name);
	DDX_Control(pDX, IDC_EDIT_IDENT, m_ident);
	DDX_Control (pDX, IDC_TAB, m_tab);
	DDX_Text(pDX, IDC_EDITWIDTH, m_width);
	DDX_Control(pDX, IDCANCEL, m_cancel_btn);
	DDX_Control(pDX, IDOK, m_ok_btn);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CManagerEffectivityDlg, CResizableDialog )
	//{{AFX_MSG_MAP(CManagerEffectivityDlg)
	ON_WM_PAINT()
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, OnSelchangeTab)
	ON_NOTIFY(NM_RCLICK, IDC_EFFECT, OnRclickEffect)
	ON_NOTIFY (NM_CUSTOMDRAW, IDC_EFFECT, OnCustomdrawList)
	ON_NOTIFY(NM_CLICK, IDC_EFFECT, OnClickEffect)
	ON_NOTIFY(NM_CLICK, IDC_PRODUCT, OnClickProduct)
	ON_NOTIFY(NM_RCLICK, IDC_PRODUCT, OnRclickProduct)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINTAB, OnDeltaposSpintab)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINWIDTH, OnDeltaposSpinwidth)
	ON_WM_SIZE()
	ON_NOTIFY(NM_SETFOCUS, IDC_EFFECT, OnSetfocusEffect)
	ON_BN_CLICKED(IDC_CHANGE, OnChange)
	ON_BN_CLICKED(IDC_ADD, OnAdd)
	ON_BN_CLICKED(IDC_DELETE, OnDelete)
	ON_WM_DRAWITEM()
	ON_NOTIFY(NM_DBLCLK, IDC_EFFECT, OnDblclkEffect)
	//}}AFX_MSG_MAP
	//ON_MESSAGE(WM_SCR, OnScr)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CManagerEffectivityDlg message handlers

BOOL CManagerEffectivityDlg::OnInitDialog()
{
	CResizableDialog ::OnInitDialog();

	if(m_api==0) return FALSE;
	if(m_pdf==0)  return FALSE;
	if(m_rel==0)  return FALSE;

	if(m_pdf->GetAccessmode()>=aplRO)
	{
		m_add_btn.EnableWindow(FALSE);
		m_del_btn.EnableWindow(FALSE);
		m_change_btn.SetWindowText( APL_T("Показать"));
	}

	m_cancel_btn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_cancel_btn.SetFlat(FALSE);
	m_ok_btn.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_ok_btn.SetFlat(FALSE);

	m_in_prd_ctrl.m_list1=&m_eff_ctrl;
	m_eff_ctrl.m_list1=&m_in_prd_ctrl;
	m_in_prd_ctrl.maindlg=this;
	m_eff_ctrl.maindlg=this;
	//задаем возможные перемещения при изменении размеров главного окна
	AddAnchor(IDC_STATICGROUP,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_EDIT_IDENT,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_EDIT_NAME,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_EDIT_VERSION,TOP_LEFT, TOP_RIGHT);
	//AddAnchor(IDC_COMBO_CONFIG,TOP_LEFT, TOP_RIGHT);
	//AddAnchor(IDC_EDIT_CONTEXT,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_TAB,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_EFFECT,TOP_LEFT, TOP_RIGHT);

	AddAnchor(IDOK,BOTTOM_RIGHT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);
	AddAnchor(IDC_CHANGE,TOP_RIGHT);
	AddAnchor(IDC_ADD,TOP_RIGHT);
	AddAnchor(IDC_DELETE,TOP_RIGHT);
	AddAnchor(IDC_SPINWIDTH,BOTTOM_LEFT);
	AddAnchor(IDC_EDITWIDTH,BOTTOM_LEFT);
	AddAnchor(IDC_STATICWIDTH,BOTTOM_LEFT);
	AddAnchor(IDC_STATICWIDTH2,BOTTOM_LEFT);

	AddAnchor(IDC_EFFECT,TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_PRODUCT,TOP_LEFT, BOTTOM_LEFT);
	AddAnchor(IDC_SAMPLE,TOP_LEFT, BOTTOM_LEFT);
	AddAnchor(IDC_SPINTAB,MIDDLE_LEFT);
	
	CString buf;
	CaplInstance *inst;

	TC_ITEM tci;
	tci.mask = TCIF_TEXT;
	tci.iImage = -1;
	tci.pszText  =  (LPTSTR)APL_T("Дата");
	m_tab.InsertItem(0, &tci);
	tci.pszText =  (LPTSTR)APL_T("Серийный Номер");
	m_tab.InsertItem(1, &tci);
	/*tci.pszText  = APL_T("Партия");
	m_tab.InsertItem(2, &tci);*/
	//вывод данных об изделии, для которого
	//будет показана применяемость
	apidata.GetAttrBN(m_pdf,_T("of_product"),inst);
	apidata.GetAttrBN(inst,_T("id"),buf);

	m_ident.SetWindowText(buf);
	apidata.GetAttrBN(inst,_T("name"),buf);

	m_name.SetWindowText(buf);
	apidata.GetAttrBN(m_pdf,_T("id"), buf);

	m_version.SetWindowText(buf);
	//m_width - начальная ширина столбца списков применяемости
	m_width=80;
	//DrawOfSelTab() отрисовывает применяемости
	//по умолчанию - по дате
	DrawOfSelTab();
	//флаг, передаваемый в обработчик OnSize(), если значение "true" -
	//список применяемости существует 
	isSize=true;

	//получение хэндлеров окон списков изделий и продуктов
	m_prHwnd=m_in_prd_ctrl.GetSafeHwnd();
	m_efHwnd=m_eff_ctrl.GetSafeHwnd();
	//задание диапазона для изменения ширины столбца списков применяемости
	m_spinWidth.SetRange( 5, 1000 );
	m_spinWidth.SetPos(m_width);
	UpdateData(false);
	
	CRect rect(0,0,0,0);
	//создание разделителя между списком изделий и применяемости
	m_wndVSplitterBar.Create(WS_CHILD|WS_BORDER|WS_DLGFRAME|WS_VISIBLE,rect,this,IDC_SPLITTER);
	m_wndVSplitterBar.SetPanes(&m_in_prd_ctrl,&m_eff_ctrl);
	//задаем изменение размера для раздилителя между списками
	AddAnchor(IDC_SPLITTER,TOP_LEFT, BOTTOM_LEFT);
	//задание диапазона для перемещения строки списков
	m_spinTab.SetRange(5,1000);
	m_spinTab.SetPos(m_width);
	RedrawWindow();
	return TRUE;  
}

void CManagerEffectivityDlg::OnPaint() 
{
	CRect rcSample,rcPr,rcSpl,rcdlg,rcEff;
	m_eff_ctrl.GetItemRect(0,&rcEff,LVIR_BOUNDS);
	m_sample.GetWindowRect(&rcSample);
	m_in_prd_ctrl.GetWindowRect(&rcPr);
	m_wndVSplitterBar.GetWindowRect(&rcSpl);
	GetClientRect( &rcdlg );
	ScreenToClient(rcEff);
	ScreenToClient(rcSample);
	ScreenToClient(rcPr);
	ScreenToClient(rcSpl);

	int t=m_in_prd_ctrl.GetTopIndex();
	int c=m_in_prd_ctrl.GetCountPerPage();

	int max=0;
	//max - максимальноу значение полосы прокутки
	//в случае отсутствия полосы прокрутки max=0
	max=m_in_prd_ctrl.GetScrollLimit(SB_HORZ);
	//изменение размеров списков применяемости и описания продукта
	if(max==0)
	{
		m_in_prd_ctrl.SetWindowPos(	NULL,
									rcPr.left,
									rcPr.top,
									rcPr.right-rcPr.left,
									rcSample.bottom-rcSample.top-(rcEff.bottom-rcEff.top+2),
									SWP_NOZORDER);
		
		m_wndVSplitterBar.SetWindowPos(	NULL,
										rcSpl.left,
										rcSpl.top,
										4,
										rcSample.bottom-rcSample.top-(rcEff.bottom-rcEff.top+2),
										SWP_NOZORDER);
	}
	else
	{
		m_in_prd_ctrl.SetWindowPos(	NULL,
									rcPr.left,
									rcPr.top,
									rcPr.right-rcPr.left,
									rcSample.bottom-rcSample.top,
									SWP_NOZORDER);
		
		m_wndVSplitterBar.SetWindowPos(	NULL,
										rcSpl.left,
										rcSpl.top,
										4,
										rcSample.bottom-rcSample.top,
										SWP_NOZORDER);
	}
	//обеспечение относительного положения скроллов списков
	m_in_prd_ctrl.EnsureVisible(t+c-1,false);	
	max=m_eff_ctrl.GetScrollLimit(SB_HORZ);
	if(max!=0)
	{
		m_eff_ctrl.SetWindowPos(NULL,
								rcPr.right+3,
								rcPr.top,
								rcdlg.right-rcPr.right-8,
								rcSample.bottom-rcSample.top,
								SWP_NOZORDER);
		//совмещаем скролл списка применяемости со скроллом списка изделия
		m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
	}
	else
	{
		m_eff_ctrl.SetWindowPos(NULL,
								rcPr.right+3,
								rcPr.top,
								rcdlg.right-rcPr.right-8,
								rcSample.bottom-rcSample.top-(rcEff.bottom-rcEff.top+2),
								SWP_NOZORDER);
		//совмещаем скролл списка применяемости со скроллом списка изделия
		m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
	}
	CResizableDialog ::OnPaint();
}

void CManagerEffectivityDlg::OnChange() 
{
	//изменение правила применяемости
	LVHITTESTINFO lvhti;
	POSITION pos;
	pos=m_in_prd_ctrl.GetFirstSelectedItemPosition();
	//к - номер выбранной строки
	int k=m_in_prd_ctrl.GetNextSelectedItem(pos);
	//если строка не выбрана - возврат
	if(k<0) 
	{
		AfxMessageBox( APL_T("Не выбрано входящее изделие"));
		return;
	}
	//mouseclick - координаты клика мыши
	ScreenToClient(&mouseclick);
	//совмещаем координаты списка применяемости с началом координат
	CRect rect;
	m_eff_ctrl.GetWindowRect(rect);
	ScreenToClient(rect);
	mouseclick.x=mouseclick.x-rect.left; 
	lvhti.pt= mouseclick;
	//проверяем элемент, на которм произведен клик мышью
	m_eff_ctrl.SubItemHitTest(&lvhti);
	//SubItemPosition - номер указанного элемента списка
	int SubItemPosition=lvhti.iSubItem;
	//ячейка не указана - возврат
	if(SubItemPosition<0) return;
	//PutIn - экземпляр объекта для передачи в класс изменения
	CaplInstance *PutIn;
	int m_numRow=k;
	//поиск указанной строки в массиве, содержащем правила применяемости
	//для каждого элемента
	for(int i=3; i<=NumItemWithEff.GetUpperBound();i++)
	{
		if((int)NumItemWithEff.GetAt(i)==m_numRow)
		{
			int start,end;
			start=NumItemWithEff.GetAt(i-3);
			end=NumItemWithEff.GetAt(i-2);
			for(int j=start; j<end; j++)
			{
				//данный элемент указан для выбранной строки
				if(j==SubItemPosition)
				{
					//получения экземпляра объекта применяемости
					//для передачи в класс изменения
					PutIn=(CaplInstance *)NumItemWithEff.GetAt(i-1);
					if(m_tab.GetCurSel()==0)
					{
						//класс добавления применяемости по дате
						CAddRuleDate dlg;
						if(m_pdf->GetAccessmode()>=aplRO) dlg.m_RO=true;
						dlg.m_data=&m_api->m_data;
						//flag - определяет выполняемое действие
						//flag=2 - производим изменение
						dlg.flag=2;
						dlg.m_eff=PutIn;
						//передача указателя на класс CaplProductManager
						dlg.m_PrMan=&m_api->m_prd_mgr;
						if(dlg.DoModal()==IDOK)
						{
							//перерисовка окна
							DrawOfSelTab();
							
							//m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
							m_eff_ctrl.RedrawWindow();
							cancel().EnableWindow(false);
							return;
						}
					}
					else if(m_tab.GetCurSel()==1)
					{//класс добавления применяемости по серийному номеру
						CAddSerialNum dlg;
						if(m_pdf->GetAccessmode()>=aplRO) dlg.m_RO=true;
						dlg.m_data=&m_api->m_data;
						dlg.m_PrMan=&m_api->m_prd_mgr;
						dlg.maindlg=this;
						dlg.flag=2;
						dlg.m_eff=PutIn;
						if(dlg.DoModal()==IDOK)
						{
							//перерисовка окна
							DrawOfSelTab();
							
							//m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
							m_eff_ctrl.RedrawWindow();	
							cancel().EnableWindow(false);
							return;
						}
					}
				}
			}
		}	
		i++; i++; i++;
	}
}

void CManagerEffectivityDlg::OnAdd() 
{
	 if(m_pdf->GetAccessmode()>=aplRO) return;
	 //добавление правли применяемости
	 if(m_tab.GetCurSel()==0)
	 {//класс добавления применяемости по дате
	  	CAddRuleDate dlg;
		dlg.flag=1;
 		dlg.m_data=&m_api->m_data;
		dlg.m_PrMan=&m_api->m_prd_mgr;
 		POSITION pos;
 		pos=m_in_prd_ctrl.GetFirstSelectedItemPosition();
		//получение номера выбранной строки
 		int k=m_in_prd_ctrl.GetNextSelectedItem(pos);
 		if(k<0) 
		{
			AfxMessageBox( APL_T("Не выбрано входящее изделие"));
			return;
		}
		//получение экземпляра обекта AQU для выбраного продукта
 		CaplInstance *inst0=(CaplInstance*)m_in_prd_ctrl.GetItemData(k);
 		if(inst0==0) return;
		if(dlg.DoModal()==IDOK)
 		{
 			apidata.PutAttrBN(dlg.m_eff,_T("usage"),inst0);
			DrawOfSelTab();
		//	m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
			m_eff_ctrl.RedrawWindow();
			cancel().EnableWindow(false);
		}
	}
	 else if(m_tab.GetCurSel()==1)
	 {//класс добавления применяемости по серийному номеру
	 	CAddSerialNum dlg;
		dlg.flag=1;
 		dlg.m_data=&m_api->m_data;
		dlg.maindlg=this;
		dlg.m_PrMan=&m_api->m_prd_mgr;
 		POSITION pos;
 		pos=m_in_prd_ctrl.GetFirstSelectedItemPosition();
 		int k=m_in_prd_ctrl.GetNextSelectedItem(pos);
		if(k<0) 
		{
			AfxMessageBox( APL_T("Не выбрано входящее изделие"));
			return;
		}
 		CaplInstance *inst0=(CaplInstance*)m_in_prd_ctrl.GetItemData(k);
 		if(inst0==0) return;
		if(dlg.DoModal()==IDOK)
 		{
 			apidata.PutAttrBN(dlg.m_eff,_T("usage"),inst0);
			DrawOfSelTab();
			//m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
			m_eff_ctrl.RedrawWindow();	
			cancel().EnableWindow(false);
		}
	}
	RedrawWindow();
}
void CManagerEffectivityDlg::OnDelete() 
{
	if(m_pdf->GetAccessmode()>=aplRO) return;
	//Удаление правлиа применяемости
	LVHITTESTINFO lvhti;
	POSITION pos;
 	pos=m_in_prd_ctrl.GetFirstSelectedItemPosition();
 	int k=m_in_prd_ctrl.GetNextSelectedItem(pos);
 	if(k<0) 
	{
		AfxMessageBox( APL_T("Не выбрано входящее изделие"));
		return;
	}
	//mouseclick - координаты клика мыши
	ScreenToClient(&mouseclick);
	//совмещаем начало координат для списка применяемости
	//и начала координат главного окна
	CRect rect;
	m_eff_ctrl.GetWindowRect(rect);
	ScreenToClient(rect);
	mouseclick.x=mouseclick.x-rect.left; 
	lvhti.pt= mouseclick;
	//определение номера элемента выбранного по клику
	m_eff_ctrl.SubItemHitTest(&lvhti);
	int SubItemPosition=lvhti.iSubItem;
	if(SubItemPosition<0) return;
	//Deleted - удаляемый экземпляр объекта применямости
	CaplInstance *Deleted;
	int m_numRow=k;
	//поиск указанной строки в массиве, содержащем правила применяемости
	//для каждого элемента
	for(int i=3; i<=NumItemWithEff.GetUpperBound();i++)
	{
		if((int)NumItemWithEff.GetAt(i)==m_numRow)
		{
			int start,end;
			start=NumItemWithEff.GetAt(i-3);
			end=NumItemWithEff.GetAt(i-2);
			for(int j=start; j<end; j++)
			{
				//выбранный элемент найдена
				if(j==SubItemPosition)
				{
					Deleted=(CaplInstance *)NumItemWithEff.GetAt(i-1);
					CString id;
					apidata.GetAttrBN(Deleted,_T("id"),id);
					CString buf;
					buf.Format( APL_T("Удаление правила применяемости\nОбозначение: %s\n\nВы уверены?"),id);
					int res=AfxMessageBox(buf, MB_YESNO);
					if(res==IDYES)
					{
						apidata.DeleteInstance(Deleted);
						//перерисовка списка применяемости
						DrawOfSelTab();
						//m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
						m_eff_ctrl.RedrawWindow();
						cancel().EnableWindow(false);
					}
					break;
				}
			}
		}
		i++; i++; i++;
	}
	RedrawWindow();
}

void CManagerEffectivityDlg::OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult) 
{	//выбор закладки на таб-контроле
	//перерисовка списка применяемости
	DrawOfSelTab();
	RedrawWindow();
	*pResult = 0;
}

void CManagerEffectivityDlg::OnRclickEffect(NMHDR* pNMHDR, LRESULT* pResult) 
{	
	//клик правой клавишей мыши на списке применяемости
	POSITION pos;
	pos=m_eff_ctrl.GetFirstSelectedItemPosition();
	//m_numRow - индекс выбраной строки
	m_numRow=m_eff_ctrl.GetNextSelectedItem(pos);
	//выделение строки в списке изделия 
	m_in_prd_ctrl.SetItemState(m_numRow,LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
	//в случае частичной видимости строки - перемещение
	m_in_prd_ctrl.EnsureVisible(m_numRow,true);
	m_eff_ctrl.EnsureVisible(m_numRow,false);
	//удаление выделения в списке применяемости
	m_eff_ctrl.SetItemState(-1,0, LVIS_SELECTED);
	m_eff_ctrl.RedrawWindow();
	msg=GetCurrentMessage();
	//mouseclick - координаты клика мыши
	mouseclick=msg->pt;
	UpdateData();
	CMenu menu;
 	CMenu* pPopup =0;
	//загружаем контекстное меню
 	VERIFY(menu.LoadMenu(IDR_CONTEXT_MENU));
 	ClientToScreen(&point);
  	pPopup = menu.GetSubMenu(0);

	if(m_pdf->GetAccessmode()>=aplRO)
	{
		pPopup->RemoveMenu(IDC_ADD,MF_BYCOMMAND);
		pPopup->RemoveMenu(IDC_DELETE,MF_BYCOMMAND);
		pPopup->ModifyMenu(IDC_CHANGE,MF_BYCOMMAND,IDC_CHANGE, APL_T("Показать"));
	}

  	BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN|
  		TPM_RIGHTBUTTON|TPM_RETURNCMD,msg->pt.x, msg->pt.y,this);
	//в зависимости от выбора строки контекстного меню :
	switch (res)
 	{
 		case IDC_ADD: OnAdd();      break;
 		case IDC_DELETE:OnDelete();	break;
  		case IDC_CHANGE:OnChange();	break;
 		default:break;
	}
	*pResult = 0;
}


void CManagerEffectivityDlg::OnCustomdrawList(NMHDR *pNMHDR, LRESULT *pResult)
{
	int t, f, r;
	//отрисовка правил применямости
	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
    *pResult = CDRF_DODEFAULT;
	
    if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
	{
		*pResult = CDRF_NOTIFYITEMDRAW;
    }
	else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
    {
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
	}
	COLORREF crText=RGB(0,0,0), crBkgnd=RGB(255,255,255);
	
  if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage )
  {      
		pLVCD->clrText = crText;
        pLVCD->clrTextBk = crBkgnd;

		CHeaderCtrl* pHeader = (CHeaderCtrl*) m_eff_ctrl.GetDlgItem(0);
		int nColumnCount = pHeader->GetItemCount();
		//задаем цвет для фона выбранной строки
		for(f=0; f<nColumnCount;f++)
		{
			if (((int)pLVCD->iSubItem ==f)&((int)pLVCD->nmcd.dwItemSpec == m_numRow))
			{
				 crBkgnd = RGB(200,200,200);
				 pLVCD->clrTextBk = crBkgnd;
				 *pResult = CDRF_DODEFAULT;
			}
		}
		//задаем цвет для отображения правил применяемости
		for(t=(Pext0.GetSize()-1);t>=0;t--)
		{
			for(int r=3;r<NumItemWithEff.GetSize();r++)
			{	
				if(t==(int)NumItemWithEff.GetAt(r))
				{	
					for(int d=(int)NumItemWithEff.GetAt(r-3);d<(int)NumItemWithEff.GetAt(r-2);d++)
					{
						if (((int)pLVCD->iSubItem ==d) & ((int)pLVCD->nmcd.dwItemSpec == t) )
						{
							 crBkgnd = RGB(100,50,255);
							 crText = RGB(100,50,255);
							 pLVCD->clrText = crText;
							 pLVCD->clrTextBk = crBkgnd;
							 *pResult = CDRF_DODEFAULT;
						}
					}
				}
				r++;r++;r++;
			}
		}
		//задаем цвет для отображения элементов, содержащих 
		//правлиа применяемости, принадлежащих выделенной строке 
		//в списке
		for(r=3;r<NumItemWithEff.GetSize();r++)
		{	
			if(m_numRow==(int)NumItemWithEff.GetAt(r))
			{	
				for(int d=(int)NumItemWithEff.GetAt(r-3);d<(int)NumItemWithEff.GetAt(r-2);d++)
				{
					if (((int)pLVCD->iSubItem ==d) & ((int)pLVCD->nmcd.dwItemSpec == m_numRow) )
					{
						 crBkgnd = RGB(20,10,115);
						 crText = RGB(0,10,100);
	
						 pLVCD->clrText = crText;
						 pLVCD->clrTextBk = crBkgnd;
						 *pResult = CDRF_DODEFAULT;
					}
				}
			}
			r++;r++;r++;
		}
		//задаем цвет для повторяющихся элементов при задании
		//правил элементов
		for(t=(Pext0.GetSize()-1);t>=0;t--)
		{
			Uncell.GetSize();
			for(int r=1;r<Uncell.GetSize();r++)
			{	
				if(t==(int)Uncell.GetAt(r))
				{	
						int d=Uncell.GetAt(r-1);
						if (((int)pLVCD->iSubItem ==d) & ((int)pLVCD->nmcd.dwItemSpec == t) )
						{
							 crBkgnd = RGB(255,0,0);
							 crText = RGB(255,0,0);

							 pLVCD->clrText = crText;
							 pLVCD->clrTextBk = crBkgnd;
							 *pResult = CDRF_DODEFAULT;
						}
				}
				r++;
			}
		}
		for(r=1;r<Uncell.GetSize();r++)
		{	
			if(m_numRow==(int)Uncell.GetAt(r))
			{	
					int d=Uncell.GetAt(r-1);
					if (((int)pLVCD->iSubItem ==d) & ((int)pLVCD->nmcd.dwItemSpec == m_numRow) )
					{
						 crBkgnd = RGB(200,0,0);
						 crText = RGB(200,0,0);

						 pLVCD->clrText = crText;
						 pLVCD->clrTextBk = crBkgnd;
						 *pResult = CDRF_DODEFAULT;
					}
			}
			r++;
		}
		*pResult = CDRF_DODEFAULT;
	}
}



void CManagerEffectivityDlg::OnClickEffect(NMHDR* pNMHDR, LRESULT* pResult) 
{
	//клик левой клавишей мыши на списке применямости
	POSITION pos;
	pos=m_eff_ctrl.GetFirstSelectedItemPosition();
	//m_numRow - номер выбранной строки
	m_numRow=m_eff_ctrl.GetNextSelectedItem(pos);
	
	msg=GetCurrentMessage();
	mouseclick=msg->pt;
	//удаление предыдущего выделения
	m_in_prd_ctrl.SetItemState(-1,0, LVIS_SELECTED);
	
	//выделение сторки в списке изделия
	m_in_prd_ctrl.SetItemState(m_numRow,LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
	m_in_prd_ctrl.EnsureVisible(m_numRow,true);
	m_eff_ctrl.EnsureVisible(m_numRow,false);
	m_eff_ctrl.SetItemState(-1,0, LVIS_SELECTED);
	//перерисовка списка применяемости
	m_eff_ctrl.RedrawWindow();
	*pResult = 0;
}

void CManagerEffectivityDlg::OnClickProduct(NMHDR* pNMHDR, LRESULT* pResult) 
{
	//клик левой клавишей на списке изделий
	POSITION pos;
	pos=m_in_prd_ctrl.GetFirstSelectedItemPosition();
	m_numRow=m_in_prd_ctrl.GetNextSelectedItem(pos);
	CRect rect;
	m_eff_ctrl.EnsureVisible(m_numRow,true);
	m_in_prd_ctrl.EnsureVisible(m_numRow,false);
	
	//удаление выделения строки в списке применямости
	m_eff_ctrl.SetItemState(-1,0, LVIS_SELECTED);
	m_eff_ctrl.RedrawWindow();
	*pResult = 0;
}

void CManagerEffectivityDlg::OnRclickProduct(NMHDR* pNMHDR, LRESULT* pResult) 
{
	//клик правой клавишей мыши на списке изделий
	POSITION pos;
	pos=m_in_prd_ctrl.GetFirstSelectedItemPosition();
	m_numRow=m_in_prd_ctrl.GetNextSelectedItem(pos);
	
	m_in_prd_ctrl.EnsureVisible(m_numRow,FALSE);
	m_eff_ctrl.EnsureVisible(m_numRow,FALSE);
	//удаление предыдущего выделения в списке применямости
	m_eff_ctrl.SetItemState(-1,0, LVIS_SELECTED);
	m_eff_ctrl.RedrawWindow();
	*pResult = 0;
}

void CManagerEffectivityDlg::CalcTabDate()
{
	//вычисление правил применямости по дате и заполнение массивов
	//Pext0, Pext2, ArrDates, sdateUInt, NumItemWithEff
	//данными для правил применяемости по дате
	int counter=m_counterCom;
	//counter - счетик, применяестя для остутствия перерисовки
	//списка изделий
	CString id,name,ver,buf,sdate;
	CaplInstance  *inst0, *inst1, *i_pdf, *i_prd;
	aplExtent ext0, ext2;
	int year;

	if(counter==0)
	{	//уничтожение списка изделий
		int nColumnCountPrd=5;
		for(int i=0;i<nColumnCountPrd;i++)
		{
			m_in_prd_ctrl.DeleteColumn(0);
		}
		m_in_prd_ctrl.DeleteAllItems();
	}
	//уничтожение списка применямости
	CHeaderCtrl* pHeader = (CHeaderCtrl*) m_eff_ctrl.GetDlgItem(0);
	int nColumnCount = pHeader->GetItemCount();
	for(i=0;i<nColumnCount;i++)
		m_eff_ctrl.DeleteColumn(0);
	m_eff_ctrl.DeleteAllItems();
	//Уничтожение данных, содержащихся в массивах
	ArrDates.RemoveAll( );
	m_sdateUInt.RemoveAll( );
	Pext2.RemoveAll( );
	Pext0.RemoveAll( );
	NumItemWithEff.RemoveAll( );
	if(counter==0)
	{	//задание стиля списка
		ListView_SetExtendedListViewStyle(m_eff_ctrl.m_hWnd,
			ListView_GetExtendedListViewStyle(m_eff_ctrl.m_hWnd)
			|LVS_EX_UNDERLINECOLD|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
		ListView_SetExtendedListViewStyle(m_in_prd_ctrl.m_hWnd,
			ListView_GetExtendedListViewStyle(m_in_prd_ctrl.m_hWnd)
					|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_INFOTIP);

		if(m_rel==m_api->m_prd_mgr.e_acu)
			m_in_prd_ctrl.InsertColumn(0,  APL_T("Позиция")     );
		else if(m_rel==m_api->m_prd_mgr.e_make_from)
			m_in_prd_ctrl.InsertColumn(0,  APL_T("Приоритет")     );

		m_in_prd_ctrl.InsertColumn(1,  APL_T("Обозначение") );
		m_in_prd_ctrl.InsertColumn(2,  APL_T("Наименование"));
		m_in_prd_ctrl.InsertColumn(3,  APL_T("Версия")      );
		m_in_prd_ctrl.InsertColumn(4,  APL_T("Количество")      );
		m_in_prd_ctrl.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
		m_in_prd_ctrl.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
		m_in_prd_ctrl.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER);
		m_in_prd_ctrl.SetColumnWidth(3, LVSCW_AUTOSIZE_USEHEADER);
		m_in_prd_ctrl.SetColumnWidth(4, LVSCW_AUTOSIZE_USEHEADER);

	}	
	apidata.GetEntityExtent(m_rel,ext0);	
	//в случае отсутствия входящих продуктов
	if(ext0.GetSize()==0) return;

	for(i=0; i<ext0.Size;i++)
	{
		CString buf;
		apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_pdr_r_ting,inst1);

		if(inst1!=m_pdf) continue;

		apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_pdr_r_ted,i_pdf);
		apidata.GetAttr(i_pdf,m_api->m_prd_mgr.a_pdf_prd,i_prd);
				
		if(i_prd!=0)
		{	//добавление экземпляра объекта ACU
			Pext0.Add(ext0[i]);
			if(counter==0)
			{
				if(m_api->m_data.IsKindOf(ext0[i], m_api->m_prd_mgr.e_acu))
				{
					apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_pdr_id,id);					
				}
				else if(m_api->m_data.IsKindOf(ext0[i], m_api->m_prd_mgr.e_make_from))
				{
					int iRank;
					m_api->m_data.GetAttr(ext0[i], m_api->m_prd_mgr.a_make_from_ranking, iRank);
					id.Format(_T("%i"), iRank);
				}

				k=m_in_prd_ctrl.InsertItem(-1,id);
				m_in_prd_ctrl.SetItemData(k,(long)ext0[i]);

				apidata.GetAttr(i_prd,m_api->m_prd_mgr.a_prd_id,id);
				m_in_prd_ctrl.SetItemText(k,1,id);

				apidata.GetAttr(i_prd,m_api->m_prd_mgr.a_prd_name,name);
				m_in_prd_ctrl.SetItemText(k,2,name);
					
				apidata.GetAttr(i_pdf,m_api->m_prd_mgr.a_pdf_id,ver);
				m_in_prd_ctrl.SetItemText(k,3,ver);
				
				double count=1;
				if(apidata.IsKindOf(ext0[i],m_api->m_prd_mgr.e_qacu_nauo))
				{
					apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_apl_qacu_value,count);
					apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_apl_qacu_unit,inst1);
					m_api->m_charact_mgr.GetUnitName(inst1,buf);
				}
				else if(m_api->m_data.IsKindOf(ext0[i],m_api->m_prd_mgr.e_make_from))
				{
					apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_make_from_value, count);
					apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_make_from_unit, inst1);
					m_api->m_charact_mgr.GetUnitName(inst1, buf);				
				}

				id.Format(_T("%g %s"),count,buf);
				m_in_prd_ctrl.SetItemText(k,4,id);
			}		
			apidata.GetEntityExtent(m_api->m_prd_mgr.e_pd_eff,ext2);
			for(j=0;j<ext2.Size;j++)
			{	
				//не отрисовываем неактивные правила применяемости
				bool bNotActive= false;
				apidata.GetAttr(ext2[j],m_api->m_prd_mgr.a_pde_not_active, bNotActive);
				if(bNotActive) continue;
				
				apidata.GetAttr(ext2[j],m_api->m_prd_mgr.a_pde_usage,inst0);
				if(inst0==ext0[i])
				{					
					if(apidata.IsKindOf(ext2[j],m_api->m_prd_mgr.e_dat_eff))
					{	COleDateTime time;
						CString s_data;
						apidata.GetAttr(ext2[j],m_api->m_prd_mgr.a_dat_eff_start_s, s_data);

						//фиктивное правило применяемости
						if(s_data==_T("19000101000000")) continue;

						if(aplString2Date(s_data,time))
						{	
							sdate=time.Format( APL_T("%d.%m.%Y г. %H:%M:%S"));
							
							//в случае пустого массива уникальность не проверяем						
							if(ArrDates.GetSize()==0)
							{	
								//Добавление в массив даты, как строки
								ArrDates.Add(sdate);
								//Добавление в массив даты, пересчитанной в секундах
								m_sdateUInt.Add(s_data);
							}
							else
							{	//добавление с проверкой на уникальность
								//значения
								int sizeDates=ArrDates.GetSize();
								for(int t=0; t<sizeDates; t++)
								{
									if(ArrDates[t]==sdate)  break;
									if(t==ArrDates.GetUpperBound())
									{ 
										//Добавление в массив даты, как строки
										ArrDates.Add(sdate);
										//Добавление в массив даты, пересчитанной в секундах
										m_sdateUInt.Add(s_data);
									}
								}
							}
						}
						apidata.GetAttr(ext2[j],m_api->m_prd_mgr.a_dat_eff_end_s, s_data);
						if(aplString2Date(s_data,time))
						{
							year=time.GetYear();
							sdate=time.Format( APL_T("%d.%m.%Y г. %H:%M:%S"));
							//в случае не заданной даты добавления в массив
							//пустой строки не производим
							if(year==0) continue;
						
							if(ArrDates.GetUpperBound()==-1)
							{
								//Добавление в массив даты, как строки
								ArrDates.Add(sdate);
								//Добавление в массив даты, пересчитанной в секундах
								m_sdateUInt.Add(s_data);
							}
							else
							{	//добавление с проверкой на уникальность значения
								sizeDates=ArrDates.GetSize();
								for(int t=0; t<sizeDates; t++)
								{
									if(ArrDates[t]==sdate)  break;
									if(t==ArrDates.GetUpperBound()) 
									{
										//Добавление в массив даты, как строки
										ArrDates.Add(sdate);
										//Добавление в массив даты, пересчитанной в секундах
										m_sdateUInt.Add(s_data);
									}
								}
							}
						}
					}

					//добавление экземпляров ACU and Product_Definition_Effectivity
					Pext2.Add(ext2[j]);
					Pext2.Add(ext0[i]);//???
				}
			}
		}
	}
	counter++;
	m_counterCom=counter;
}



bool CManagerEffectivityDlg::MoveRow(int from, int to)
{	//перемещение строк списка
	
	int i;
	//перемещение не возможно в случае отрицательного или такого же индекса 
		if(from == to || from < 0 || to < 0)
		return FALSE;
	//для списка изделий
		long tempInst;
		int nColumnCountPrd = m_in_prd_ctrl.GetHeaderCtrl()->GetItemCount();
		tempInst=m_in_prd_ctrl.GetItemData(to);
		CStringArray Temp;
		for(i = 0; i < nColumnCountPrd; i++)
			Temp.Add(m_in_prd_ctrl.GetItemText(to, i));	
		
		m_in_prd_ctrl.SetItemData(to,m_in_prd_ctrl.GetItemData(from));
		m_in_prd_ctrl.SetItemData(from, tempInst);
		for(i = 0; i < nColumnCountPrd; i++)
		{	
			m_in_prd_ctrl.SetItemText(to,i,m_in_prd_ctrl.GetItemText(from, i));
			m_in_prd_ctrl.SetItemText(from,i,Temp.GetAt(i));
		}
	//для списка применямости
		Temp.RemoveAll();
		int nColumnCountEff = m_eff_ctrl.GetHeaderCtrl()->GetItemCount();
		for(i = 0; i < nColumnCountEff; i++)
			Temp.Add(m_eff_ctrl.GetItemText(to, i));	
		
		for(i = 0; i < nColumnCountEff; i++)
		{	
			m_eff_ctrl.SetItemText(to,i,m_eff_ctrl.GetItemText(from, i));
			m_eff_ctrl.SetItemText(from,i,Temp.GetAt(i));
		}
		return true;
}


void CManagerEffectivityDlg::OnDeltaposSpintab(NMHDR* pNMHDR, LRESULT* pResult) 
{//перемещение выбранной строки
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
	//перемещение выделенной строки вверх
	if(pNMUpDown->iDelta>0)
	{
		if(m_numRow<0) return;
		//верхнюю строку перемещать нельзя
		if(m_numRow==0) return;
		
		MoveRow(m_numRow, m_numRow-1);
		m_numRow-=1;
		//проверка полной видимости и установка нужного выделения строк
		m_in_prd_ctrl.EnsureVisible(m_numRow, FALSE);
		m_in_prd_ctrl.SetItemState(m_numRow,LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
		m_in_prd_ctrl.SetItemState(m_numRow+1,0, LVIS_SELECTED);
		m_eff_ctrl.SetItemState(m_numRow,LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
		m_eff_ctrl.SetItemState(m_numRow+1,0, LVIS_SELECTED);
		isDraw=true;//удаление колонок и элементов не производим
		//отрисовка списка применяемости
		switch(m_tab.GetCurSel()) 
		{
			case 0:
				DrawEffectivityDate();
				break;
			case 1:
				DrawEffectivitySerial();
				break;
			default: break;
		}
		//проверка видимости строки списка применяемости
		m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1,false);
	}
	//перемещение выдленной строки вниз
	if(pNMUpDown->iDelta<0)
	{	
		if(m_numRow<0) return;
		//в случае последней строки - возврат
		if(m_numRow==m_in_prd_ctrl.GetItemCount()-1) return;
		MoveRow(m_numRow, m_numRow+1);
		m_numRow+=1;
		m_in_prd_ctrl.EnsureVisible(m_numRow, FALSE);
		//проверка видимости и установка нужного выделения
		m_in_prd_ctrl.SetItemState(m_numRow,LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
		m_in_prd_ctrl.SetItemState(m_numRow-1,0, LVIS_SELECTED);
		m_eff_ctrl.SetItemState(m_numRow,LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
		m_eff_ctrl.SetItemState(m_numRow-1,0, LVIS_SELECTED);
		isDraw=true;//удаление колонок и элементов не производим
		switch(m_tab.GetCurSel()) 
		{
			case 0:  DrawEffectivityDate();   break;
			case 1:  DrawEffectivitySerial(); break;
			default: break;
		}
		//проверка видимости строки списка применяемости
		m_eff_ctrl.EnsureVisible(m_in_prd_ctrl.GetCountPerPage()+m_in_prd_ctrl.GetTopIndex()-1, false);
	}
	*pResult = 0;
}


void CManagerEffectivityDlg::CalcTabSerial()
{	
	//вычисление правил применямости по дате и заполнение массивов
	//Pext0, Pext2, ArrDates, sdateUInt, NumItemWithEff
	//данными для правил применяемости по дате

	CaplInstance  *inst0, *inst1,  *i_pdf, *i_prd;
	aplExtent ext0, ext2;
	//удаление списка применяемости
	CHeaderCtrl* pHeader = (CHeaderCtrl*) m_eff_ctrl.GetDlgItem(0);
	int nColumnCount = pHeader->GetItemCount();
	for(i=0;i<nColumnCount;i++)
		m_eff_ctrl.DeleteColumn(0);
	m_eff_ctrl.DeleteAllItems();
	//удаление данных используемых массивов
	ArrDates.RemoveAll( );
	m_sdateUInt.RemoveAll( );
	Pext2.RemoveAll( );
	Pext0.RemoveAll( );
	NumItemWithEff.RemoveAll( );

	apidata.GetEntityExtent(m_rel,ext0);	
	//в случае отстутствия входящих изделий
	if(ext0.GetSize()==0) return ;

	for(i=0; i<ext0.Size;i++)
	{
		CString buf;
		apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_pdr_r_ting,inst1);

		if(inst1!=m_pdf) continue;

		apidata.GetAttr(ext0[i],m_api->m_prd_mgr.a_pdr_r_ted,i_pdf);
		apidata.GetAttr(i_pdf,m_api->m_prd_mgr.a_pdf_prd,i_prd);
				
		if(i_prd!=0)
		{
			Pext0.Add(ext0[i]);
			apidata.GetEntityExtentBN(_T("product_definition_effectivity"),ext2);
			for(j=0;j<ext2.Size;j++)
			{	
				apidata.GetAttrBN(ext2[j],_T("usage"),inst0);
				if(inst0==ext0[i])
				{									
					if(apidata.IsKindOfBN(ext2[j],_T("serial_numbered_effectivity")))
					{
						apidata.GetAttrBN(ext2[j],_T("effectivity_start_id"),buf);

						//фиктивное правило применяемости
						if(buf.IsEmpty()) continue;

						if(buf!=_T(""))
						{
							if(ArrDates.GetSize()==0)
								ArrDates.Add(buf);
							else
							{
								for(int t=0; t<ArrDates.GetSize(); t++)
								{
									if(ArrDates[t]==buf)  break;
									if(t==ArrDates.GetUpperBound())
										ArrDates.Add(buf);
								}
							}
						}
						apidata.GetAttrBN(ext2[j],_T("effectivity_end_id"),buf);
						if(buf==_T(" ")) continue;
						if(!buf.IsEmpty())
						{
							for(int t=0; t<ArrDates.GetSize(); t++)
							{
								if(ArrDates[t]==buf)  break;
								if(t==ArrDates.GetUpperBound())
									ArrDates.Add(buf);
							}
						}
					}

					Pext2.Add(ext2[j]);
					Pext2.Add(ext0[i]);//???
				}
			}
		}
	}
}

bool CManagerEffectivityDlg::CmpSerialNum(CString string1, CString string2)
{//функция сравнения серийных номеров 
 //по умолчанию сравнивает как строки
	if(m_api->m_prd_mgr.funcCompareSN == NULL)
		return false;

	return m_api->m_prd_mgr.funcCompareSN(string1, string2)==1;

//	if(string1>string2) return true;
//	return false;
}



void  CManagerEffectivityDlg::DrawEffectivityDate()
{//отрисовка списка применямости по дате
	Uncell.RemoveAll( );
	NumItemWithEff.RemoveAll( );

	int g;
	CHeaderCtrl* pHeader = (CHeaderCtrl*) m_eff_ctrl.GetDlgItem(0);
	int nColumnCount = pHeader->GetItemCount();
	//удаляем столбцы только в нужном случае
	if(isDraw==false)
		for(i=0;i<nColumnCount;i++)
			m_eff_ctrl.DeleteColumn(0);
	m_eff_ctrl.DeleteAllItems();

	CRect rcPrd, rcdlg,rcSample;
	m_in_prd_ctrl.GetWindowRect(&rcPrd);
	m_sample.GetWindowRect(&rcSample);
	ScreenToClient(rcPrd);
	ScreenToClient(rcSample);
	GetClientRect( &rcdlg );
	//сортировка вручную массива строк, содержащих даты
	//и массива со  значениями дат, пересчитанными в целые
	int sizeDates=ArrDates.GetSize();
	if(sizeDates!=0)
	{
		char is=1;
		while(is)
		{
			is=0;
			for (int t=1; t<sizeDates; t++)
				if (m_sdateUInt.GetAt(t)<m_sdateUInt.GetAt(t-1))
				{
				 CString temp = m_sdateUInt.GetAt(t);
				 CString stemp = ArrDates.GetAt(t);
	             m_sdateUInt.SetAt(t,m_sdateUInt.GetAt(t-1));
				 ArrDates.SetAt(t, ArrDates.GetAt(t-1));
	             m_sdateUInt.SetAt((t-1),temp);
				 ArrDates.SetAt((t-1), stemp);
	             is=1;
	            }
		}
		//вставка колонок списка применямости
		//выполняется только в случае предыдущего удаления
		if(isDraw==false)
		{
			for(int t=0; t<sizeDates; t++)
			{
				m_eff_ctrl.InsertColumn(t, ArrDates[t]);
				m_eff_ctrl.SetColumnWidth(t, m_width);
			}
		}
		for(int t=m_in_prd_ctrl.GetItemCount()-1;t>=0;t--)
		{
			//поиск по всем правилам применямости и заполнение
			//массива NumItemWithEff(см. h-файл)
			int d=m_eff_ctrl.InsertItem(0,_T(""));
			for(int i=1;i<Pext2.GetSize();i++)
			{
				CaplInstance* prd_temp= (CaplInstance*) m_in_prd_ctrl.GetItemData(t);

				if(Pext2.GetAt(i)==(void*)m_in_prd_ctrl.GetItemData(t))
				{	CaplInstance *inst0;
					inst0=(CaplInstance*)Pext2.GetAt(i-1);
					CString start, end;
					if(apidata.IsKindOf(inst0,m_api->m_prd_mgr.e_dat_eff))
					{	
						COleDateTime time;
						CString s_data;
						apidata.GetAttr(inst0,m_api->m_prd_mgr.a_dat_eff_start_s, s_data);

						//!!!// Кривое правило!
						if(s_data.IsEmpty()) {i++; continue;} 

						if(aplString2Date(s_data,time))
						{
							start=time.Format( APL_T("%d.%m.%Y г. %H:%M:%S"));
						}
						apidata.GetAttr(inst0,m_api->m_prd_mgr.a_dat_eff_end_s, s_data);
						if(aplString2Date(s_data,time))
						{
							end=time.Format( APL_T("%d.%m.%Y г. %H:%M:%S"));
						}		
						int startDr=0, endDr=0;
						//поиск строки, содержащей начальную дату в массиве, 
						//содержащим даты для заполнения колонок
						for (g=0; g<ArrDates.GetSize();g++)
						{
							if(ArrDates.GetAt(g)==start)
							{
								startDr=g;
								//Добавление номера данного элемента
								//массива в массив NumItemWithEff 
								NumItemWithEff.Add(startDr);
							}

							if(ArrDates.GetAt(g)==end)
							{
								endDr=g;
								//Добавление номера данного элемента
								//массива в массив NumItemWithEff 
								NumItemWithEff.Add(endDr);
							}
						}
						//в случае не заданной конечной даты
						if(endDr==0)
						{
							//для данной строки в качестве конечного
							//номера элемента добаляем наибольший
							//индекс в массиве строк колонок
							endDr=ArrDates.GetUpperBound()+1;
							NumItemWithEff.Add(endDr);
						}
						//добавление экземпляра данной применяемости
						//приведенной к целому
						NumItemWithEff.Add((int)inst0);
						//добавление номера строки, содержащей данную
						//применяемость
						NumItemWithEff.Add(t);
						for(g=startDr; g<endDr; g++)
						{	//получаем текст, содержащийся в даном
							//элементе, если он не нулевая строка
							//то добавляем его номер и номер строки
							//в массив Uncell
							CString buf=m_eff_ctrl.GetItemText(d, g);
							if(!buf.IsEmpty())
							{
								Uncell.Add(g);
								Uncell.Add(t);
							}
							//в данный элемент записываем строку "  "
							m_eff_ctrl.SetItemText(d, g,_T("  "));
						}
					}
				}
				i++;
			}
		} 
	}
	else 
	{
		m_eff_ctrl.InsertColumn(0,_T(""));
		m_eff_ctrl.SetColumnWidth(0,0);
		m_eff_ctrl.InsertItem(0,_T(""));
		RedrawWindow();
	}
	isDraw=false;//устанавливаем значение для последующей перерисовки
	
}

void CManagerEffectivityDlg::OnDeltaposSpinwidth(NMHDR* pNMHDR, LRESULT* pResult) 
{//отработка нажатия спин-контроля для изменения ширины столбца
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
	pNMUpDown->iDelta*=5;//изменение равно 5
	//устанавливаем минимальную ширину колонки
	if ((m_width<55)&(pNMUpDown->iDelta<0)) return;
	//изменяем ширину колонки 
	m_width=m_width+pNMUpDown->iDelta;
	UpdateData(false);
	//отрисовка списка применяемости
	switch(m_tab.GetCurSel()) 
	{
		case 0:DrawEffectivityDate();break;
		case 1:DrawEffectivitySerial();break;
		default: break;
	}
	CRect rc;
	m_eff_ctrl.GetWindowRect(&rc);
	InvalidateRect(&rc);
	
	*pResult = 0;
}

void CManagerEffectivityDlg::DrawEffectivitySerial()
{//отрисовка списка применямости по серийному номеру

	int g;
	Uncell.RemoveAll( );
	NumItemWithEff.RemoveAll( );
	CaplInstance *inst0;
	
	CHeaderCtrl* pHeader = (CHeaderCtrl*) m_eff_ctrl.GetDlgItem(0);
	int nColumnCount = pHeader->GetItemCount();
	if(isDraw==false)
		for(i=0;i<nColumnCount;i++)
		m_eff_ctrl.DeleteColumn(0);
	m_eff_ctrl.DeleteAllItems();
    //сортировка массива содержащего даты для заполнения колонок
	sizeDates=ArrDates.GetSize();
	if(sizeDates!=0)
	{
		char is=1;
		while(is)
		{
			is=0;
			for (int t=1; t<ArrDates.GetSize(); t++)
				if(!CmpSerialNum(ArrDates.GetAt(t),ArrDates.GetAt(t-1)))
				{
					CString stemp = ArrDates.GetAt(t);
					ArrDates.SetAt(t, ArrDates.GetAt(t-1));
					ArrDates.SetAt((t-1), stemp);
					 is=1;
	            }
		}
		if(isDraw==false)
		{	//вставляе колонки только в случае их удаления
			for(int t=0; t<sizeDates; t++)
			{
				m_eff_ctrl.InsertColumn(t, ArrDates[t]);
				m_eff_ctrl.SetColumnWidth(t, m_width);
			}
		}

		for(int t=m_in_prd_ctrl.GetItemCount()-1;t>=0;t--)
		{
			int d=m_eff_ctrl.InsertItem(0,_T(""));
			for(int i=0;i<Pext2.GetSize();i++)
			{
				if(Pext2.GetAt(i)==(void*)m_in_prd_ctrl.GetItemData(t))
				{	
					inst0=(CaplInstance*)Pext2.GetAt(i-1);
					CString start, end;
					if(apidata.IsKindOfBN(inst0,_T("serial_numbered_effectivity")))
					{	
						apidata.GetAttrBN(inst0,_T("effectivity_start_id"), start);
						apidata.GetAttrBN(inst0,_T("effectivity_end_id"), end);
						if(end!=_T(""))
						{	//в случае если начальный серийный номер
							//больше конечного меняем их местами
							if(CmpSerialNum(start,end)==true)
							{
								CString temp=start;
								start=end;
								end=temp;
							}
						}						
						int startDr, endDr;
						startDr=0;
						endDr=0;
						//поиск в массиве серийных номеров для колонок
						//начальных и конечных серийных номеров
						for (g=0; g<ArrDates.GetSize();g++)
						{
							if(ArrDates.GetAt(g)==start)
							{
								startDr=g;
								//добавление в массив начального номера
								NumItemWithEff.Add(startDr);
							}

							if(ArrDates.GetAt(g)==end)
							{
								endDr=g;
								//добавление в массив конечного номера
								NumItemWithEff.Add(endDr);
							}
						}
		
						if(endDr==0)
						{//в случае если конечный номер не задан - 
						 //в качестве конечного индекса для конечного
						 //номера добавляется индекс последней колонки
							endDr=ArrDates.GetUpperBound()+1;
							NumItemWithEff.Add(endDr);
						}
						//добавление экземпляра данной применямости
						NumItemWithEff.Add((int)inst0);
						//добавление номера данной строки
						NumItemWithEff.Add(t);
						//проверка для данного правила применямости
						//на пересечение с другим правилом для данного
						//изделия
						for(g=startDr; g<endDr; g++)
						{	//получение текста из данного элемента	
							CString buf=m_eff_ctrl.GetItemText(d, g);
							if(buf!=_T(""))
							{
								//в случае ненулевоу строки добавляем
								//в массив номер элемента и строки
								Uncell.Add(g);
								Uncell.Add(t);
							}
							//устанавливаем в данный элемент строку ""
							m_eff_ctrl.SetItemText(d, g,_T("     "));
						}
					}
				}
			}
		} 
	}
	else 
	{
		m_eff_ctrl.InsertColumn(0,_T(""));
		m_eff_ctrl.SetColumnWidth(0,0);
		m_eff_ctrl.InsertItem(0,_T(""));
		RedrawWindow();
	}
	isDraw=false;
}


void CManagerEffectivityDlg::DrawOfSelTab()
{//вызов функций вычисления и отрисовки в зависимости
 //от выбора закладки
	CRect rect;
	m_eff_ctrl.GetWindowRect(&rect);
	switch(m_tab.GetCurSel()) 
	{
		case 0://выбрана закладка применяемости по дате
			{
				CalcTabDate();
				DrawEffectivityDate();
				InvalidateRect(rect);
				break;
			}
					
		case 1://выбрана закладка применяемости по серийному номеру
			{
				CalcTabSerial();
				DrawEffectivitySerial();
				InvalidateRect(rect);
				break;
			}
/*		case 2://выбрана закладка применяемости по партии
			{	//(удаление все колонок и элементов списка)
				CHeaderCtrl* pHeader = (CHeaderCtrl*) m_eff_ctrl.GetDlgItem(0);
				int nColumnCount = pHeader->GetItemCount();
				for(i=0;i<nColumnCount;i++)
					m_eff_ctrl.DeleteColumn(0);
				m_eff_ctrl.DeleteAllItems();
							
				break;
			}*/
		default: break;
	}
}

void CManagerEffectivityDlg::OnSize(UINT nType, int cx, int cy) 
{	//перерисовываем список применяемости только после вызова
	//функции OnInitDialod()
	CRect rcPr, rcEff, rcSp, rcPr1, rcEff1, rcSp1;
	if(isSize==true)
	{	
		m_wndVSplitterBar.GetWindowRect(&rcSp);
		m_in_prd_ctrl.GetWindowRect(&rcPr);
		m_eff_ctrl.GetWindowRect(&rcEff);
		ScreenToClient(rcSp);
		ScreenToClient(rcPr);
		ScreenToClient(rcEff);
	}
	CResizableDialog ::OnSize(nType, cx, cy);
	if(isSize==true)
	{
		m_wndVSplitterBar.GetWindowRect(&rcSp1);
		m_in_prd_ctrl.GetWindowRect(&rcPr1);
		m_eff_ctrl.GetWindowRect(&rcEff1);

		ScreenToClient(rcSp1);
		ScreenToClient(rcPr1);
		ScreenToClient(rcEff1);	
		rcPr1.right=rcPr.right;
		rcEff1.left=rcEff.left;
		rcSp1.left=rcSp.left;
		rcSp1.right=rcSp.right;


		m_wndVSplitterBar.MoveWindow(rcSp);
		m_in_prd_ctrl.MoveWindow(rcPr);
		m_eff_ctrl.MoveWindow(rcEff);
/*		m_wndVSplitterBar.SetWindowPos(NULL,
								       rcSp1.left,
								   	   rcSp1.top,
									   rcSp1.right-rcSp1.left,
									   rcSp1.bottom-rcSp1.top,
										SWP_NOZORDER);

		m_in_prd_ctrl.SetWindowPos(NULL,
								   rcPr1.left,
								   rcPr1.top,
								   rcPr1.right-rcPr1.left,
								   rcPr1.bottom-rcPr1.top,
								   SWP_NOZORDER);
		m_eff_ctrl.SetWindowPos(NULL,
								rcEff1.left,
								rcEff1.top,
								rcEff1.right-rcEff1.left,
								rcEff1.bottom-rcEff1.top,
								SWP_NOZORDER);*/
	
	}
	RedrawWindow();
}

void CManagerEffectivityDlg::OnSetfocusEffect(NMHDR* pNMHDR, LRESULT* pResult) 
{
	m_in_prd_ctrl.SetFocus();	
	*pResult = 0;
}

void CManagerEffectivityDlg::OnDblclkEffect(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnChange();
	*pResult = 0;
}
