// ChangeWhereUsed.cpp : implementation file
//

#include "stdafx.h"
#include "apl_api.h"
#include "ChangeWhereUsed.h"

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

#include "ChangeParamDlg.h"

/////////////////////////////////////////////////////////////////////////////
// CChangeWhereUsed dialog


CChangeWhereUsed::CChangeWhereUsed(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CChangeWhereUsed::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChangeWhereUsed)
	m_sProductId = _T("");
	m_sProductName = _T("");
	m_sProductVer = _T("");
	m_iCont = -1;
	m_bDateSelected = TRUE;
	m_oleDate = COleDateTime::GetCurrentTime();
	m_bSNSelected = FALSE;
	m_sSN = _T("");
	m_bNotShow = TRUE;
	//}}AFX_DATA_INIT

	m_api = NULL;
	
	m_psc = NULL;
	m_assPdf = NULL;
	
	m_items = NULL;
	m_newItems = NULL;
	m_delItems = NULL;
	
	m_curItem = NULL;
	m_index = -1;
	m_curPSC = NULL;
	m_curPSCInfo = NULL;
	
	m_sEffType = _T("none");
	m_sStartCond = _T("");
	m_sEndCond = _T("");
	
	m_change = NULL;
	
	m_bReadOnly = false;

	// при запеске диалога фильтруем список по текущей дате
	m_bFilteredByDate = true;
	m_bFilteredBySN = false;
	m_bFilteredByContext = false;

	m_iDefaultPdf = NULL;
}


void CChangeWhereUsed::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChangeWhereUsed)
	DDX_Control(pDX, IDC_CHG2_SN_CTRL, m_sn);
	DDX_Control(pDX, IDC_CHG2_SET_EFF, m_setEffBtn);
	DDX_Control(pDX, IDC_CHG2_PROP, m_itemPropBtn);
	DDX_Control(pDX, IDC_CHG2_ITEM_DELETE, m_itemDeleteBtn);
	DDX_Control(pDX, IDC_CHG2_ITEM_CHANGE, m_itemChngBtn);
	DDX_Control(pDX, IDC_CHG2_DATE_CTRL, m_dateCtrl);
	DDX_Control(pDX, IDC_CHG2_CONTEXT_COMBO, m_contCtrl);
	DDX_Control(pDX, IDC_CHG2_CLEAR, m_itemClearBtn);
	DDX_Control(pDX, IDC_CHG2_ASS_SELECT, m_selectBtn);
	DDX_Control(pDX, IDC_CHG2_ASS_REFRESH, m_refreshBtn);
	DDX_Control(pDX, IDCANCEL, m_CancelBtn);
	DDX_Control(pDX, IDOK, m_okBtn);
	DDX_Control(pDX, IDC_CHG_WHERE_USED_LIST, m_WhereUsedList);
	DDX_Text(pDX, IDC_CHG2_ASS_ID, m_sProductId);
	DDX_Text(pDX, IDC_CHG2_ASS_NAME, m_sProductName);
	DDX_Text(pDX, IDC_CHG2_ASS_VER, m_sProductVer);
	DDX_CBIndex(pDX, IDC_CHG2_CONTEXT_COMBO, m_iCont);
	DDX_Check(pDX, IDC_CHG2_DATE_CHECK, m_bDateSelected);
	DDX_DateTimeCtrl(pDX, IDC_CHG2_DATE_CTRL, m_oleDate);
	DDX_Check(pDX, IDC_CHG2_SN_CHECK, m_bSNSelected);
	DDX_Text(pDX, IDC_CHG2_SN_CTRL, m_sSN);
	DDX_Check(pDX, IDC_CHNGA_NOTSHOW, m_bNotShow);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChangeWhereUsed, CResizableDialog)
	//{{AFX_MSG_MAP(CChangeWhereUsed)
	ON_BN_CLICKED(IDC_CHG2_ASS_SELECT, OnChg2AssSelect)
	ON_BN_CLICKED(IDC_CHG2_ASS_REFRESH, OnChg2AssRefresh)
	ON_BN_CLICKED(IDC_CHG2_ITEM_CHANGE, OnChg2ItemChange)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHG_WHERE_USED_LIST, OnItemchangedChgWhereUsedList)
	ON_BN_CLICKED(IDC_CHG2_ITEM_DELETE, OnChg2ItemDelete)
	ON_BN_CLICKED(IDC_CHG2_CLEAR, OnChg2Clear)
	ON_BN_CLICKED(IDC_CHG2_PROP, OnChg2Prop)
	ON_BN_CLICKED(IDC_CHG2_SET_EFF, OnChg2SetEff)
	ON_BN_CLICKED(IDC_CHG2_SN_CHECK, OnChg2SnCheck)
	ON_BN_CLICKED(IDC_CHG2_DATE_CHECK, OnChg2DateCheck)
	ON_NOTIFY(DTN_DATETIMECHANGE, IDC_CHG2_DATE_CTRL, OnDatetimechangeChg2DateCtrl)
	ON_CBN_CLOSEUP(IDC_CHG2_CONTEXT_COMBO, OnCloseupChg2ContextCombo)
	ON_NOTIFY(NM_DBLCLK, IDC_CHG_WHERE_USED_LIST, OnDblclkChgWhereUsedList)
	//}}AFX_MSG_MAP

	ON_NOTIFY ( NM_CUSTOMDRAW, IDC_CHG_WHERE_USED_LIST, OnCustomdrawWhereUsedList )
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChangeWhereUsed message handlers

BOOL CChangeWhereUsed::OnInitDialog() 
{
	CResizableDialog::OnInitDialog();
	ModifyStyleEx(0, WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT);   
	ModifyStyle(0, WS_MAXIMIZEBOX);   

	CreateImageLists();
	SetList();
	SetButtons();

	if (m_api && apidata.IsConnected())
	{
		LoadContexts();

		//заполняем таблицу
		if (!m_assPdf)
		{
			CaplInstance* inst = NULL;
			if (m_psc)
				apidata.GetAttr(m_psc, m_api->m_change_mgr.a_psc_changed_product, inst);		

			if (!inst)
				inst = m_pscInfo.m_pdr;
			
			if (inst)
			{
				if (apidata.IsKindOf(inst, m_api->m_prd_mgr.e_apl_pdf))
					m_assPdf = inst;
				else if (apidata.IsKindOf(inst, m_api->m_prd_mgr.e_pdr)) 
					//apidata.GetAttr(inst, m_api->m_prd_mgr.a_pdr_r_ting, m_assPdf);
					apidata.GetAttr(inst, m_api->m_prd_mgr.a_pdr_r_ted, m_assPdf);
			}
			
			if (m_assPdf)
			{
				apidata.GetAttr(m_assPdf, m_api->m_prd_mgr.a_pdf_prd, inst);
				if (inst)
				{
					apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_id, m_sProductId);
					apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_name, m_sProductName);
				}
				apidata.GetAttr(m_assPdf, m_api->m_prd_mgr.a_pdf_id, m_sProductVer);
				
				UpdateData(FALSE);
			}
		}

		m_dateCtrl.EnableWindow(m_bDateSelected);
		OnChg2AssRefresh();

//		m_api->m_prd_mgr.WhereUsedProduct(m_assPdf, m_extRels, m_extPdfs);
//		
//		bool bLoadData;
//		CaplLoadData ld(&m_api->m_data, DEF_SOURCE);
//		for (int i = 0; i < m_extRels.GetSize(); i++)
//		{
//			if (m_extRels[i]->GetId() == 0)
//				continue;
//			
//			ld.AddQuery(0, m_extRels[i]);
//			bLoadData = true;
//		}
//		
//		if (bLoadData)
//		{
//			ld.AddQuery(_T('r'), 0, m_api->m_prd_mgr.e_pd_eff, m_api->m_prd_mgr.a_pde_usage, true, true);
//			ld.LoadEx();
//		}
//		
//		FillWhereUsedList();
	}

	if (m_bReadOnly)
	{
		m_selectBtn.EnableWindow(FALSE);
		m_okBtn.EnableWindow(FALSE);
	}

	SetAnchors();

	UpdateData(FALSE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CChangeWhereUsed::CreateImageLists()
{
	m_ImageList.Create(IDR_NAVIGATOR_ICON, 20, 11, RGB(255, 0, 255));

	m_btnImageList.Create(24, 24, ILC_COLOR24 | ILC_MASK, 1, 0);
	m_btnImageList.SetImageCount(0);
	
	CBitmap bm;
	bm.LoadBitmap(IDB_CLEAR_ICO);
	m_btnImageList.Add(&bm, RGB(255, 0, 255));
	bm.DeleteObject();

	bm.LoadBitmap(IDB_REPLACE_ICO);
	m_btnImageList.Add(&bm, RGB(0, 0, 0));
	bm.DeleteObject();
}

void CChangeWhereUsed::SetList()
{
	m_WhereUsedList.SetImageList(aplGetInstImageList(), LVSIL_SMALL);	
	m_WhereUsedList.SetExtendedStyle(m_WhereUsedList.GetExtendedStyle() | LVS_EX_FULLROWSELECT |
		LVS_EX_SUBITEMIMAGES);

	int i= 0;

	m_WhereUsedList.InsertColumn(i++,  APL_T("Позиция"), LVCFMT_LEFT, 50);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Изменяемое изделие"), LVCFMT_LEFT, 100);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Количество"), LVCFMT_LEFT, 50);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Контекст"), LVCFMT_LEFT, 50);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Действие"), LVCFMT_LEFT, 70);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Заменить"), LVCFMT_LEFT, 100);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Позиция"), LVCFMT_LEFT, 50);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Количество"), LVCFMT_RIGHT, 50);
	m_WhereUsedList.InsertColumn(i++,  APL_T("Применяемость"), LVCFMT_LEFT, 50);

	m_WhereUsedList.AutoSizeAllColumns();
}

void CChangeWhereUsed::SetAnchors()
{
	AddAnchor(IDC_WHERE_USED_STATIC, TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_CHG_WHERE_USED_LIST, TOP_LEFT, BOTTOM_RIGHT);
	
	AddAnchor(IDC_PRODUCT_STATIC, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_CHG2_ASS_ID, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_CHG2_ASS_NAME, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_CHG2_ASS_VER, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_CHG2_ASS_SELECT, TOP_CENTER);
	
	AddAnchor(IDC_FILTER_STATIC, TOP_CENTER, TOP_RIGHT);
	AddAnchor(IDC_CHG2_SN_CTRL, TOP_CENTER, TOP_RIGHT);
	AddAnchor(IDC_CHG2_DATE_CTRL, TOP_CENTER, TOP_RIGHT);
	AddAnchor(IDC_CHG2_CONTEXT_COMBO, TOP_CENTER, TOP_RIGHT);
	AddAnchor(IDC_TEXT_CON_STATIC, TOP_CENTER);
	AddAnchor(IDC_CHG2_SN_CHECK, TOP_CENTER);
	AddAnchor(IDC_CHG2_DATE_CHECK, TOP_CENTER);
	AddAnchor(IDC_CHNGA_NOTSHOW, TOP_CENTER, TOP_RIGHT);
	AddAnchor(IDC_CHG2_ASS_REFRESH, TOP_RIGHT);
	
	AddAnchor(IDOK, BOTTOM_RIGHT);	
	AddAnchor(IDCANCEL, BOTTOM_RIGHT);	
}

void CChangeWhereUsed::SetButtons()
{
	m_CancelBtn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_CancelBtn.SetFlat(FALSE);
	
	m_okBtn.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_okBtn.SetFlat(FALSE);
	
	m_refreshBtn.SetIcon(GetAplStdIco16(APLSTDICO_PLAY));
	m_refreshBtn.SetFlat(FALSE);
	
	m_selectBtn.SetIcon(GetAplTableIco(APL_TABLE_FIND));
	m_selectBtn.SetFlat(FALSE);
	
	m_itemChngBtn.SetFlat(FALSE);
	m_itemChngBtn.EnableWindow(FALSE);
	m_itemChngBtn.SetWindowText(_T(""));
	m_itemChngBtn.SetTooltipText( APL_T("Заменить"));
	m_itemChngBtn.SetIcon(m_btnImageList.ExtractIcon(1)/*GetAplCheckIco(APL_ICON_CHECKOUT, true)*/);
	
	m_itemDeleteBtn.SetIcon(GetAplStdIco16(APLSTDICO_MINUS));
	m_itemDeleteBtn.SetFlat(FALSE);
	m_itemDeleteBtn.EnableWindow(FALSE);
	m_itemDeleteBtn.SetWindowText(_T(""));
	m_itemDeleteBtn.SetTooltipText( APL_T("Удалить"));
	
	m_itemClearBtn.EnableWindow(FALSE);
	m_itemClearBtn.SetWindowText(_T(""));
	m_itemClearBtn.SetTooltipText( APL_T("Очистить"));
	m_itemClearBtn.SetFlat(FALSE);
	m_itemClearBtn.SetIcon(m_btnImageList.ExtractIcon(0));
	
	m_itemPropBtn.EnableWindow(FALSE);
	m_itemPropBtn.SetWindowText(_T(""));
	m_itemPropBtn.SetTooltipText( APL_T("Показать свойства"));
	m_itemPropBtn.SetFlat(FALSE);
	m_itemPropBtn.SetIcon(GetAplTableIco(APL_TABLE_PROP));
	
	m_setEffBtn.SetWindowText(_T(""));
	m_setEffBtn.SetTooltipText( APL_T("Условие"));
	m_setEffBtn.SetFlat(FALSE);
	m_setEffBtn.SetIcon(GetAplStdIco16(APLSTDICO_QUERY));
}

void CChangeWhereUsed::LoadContexts()
{
	CString buf;
	int j;
	
	// заполняем контексты
	apidata.GetEntityExtent(m_api->m_prd_mgr.e_pd_context, m_contexts);
	for (int i = 0; i < m_contexts.GetSize(); i++)
	{
		apidata.GetAttr(m_contexts[i], m_api->m_prd_mgr.a_pd_context_name, buf);
		j = m_contCtrl.AddString(buf);
		m_contCtrl.SetItemData(j, (long)m_contexts[i]);
	}
	m_iCont = m_contCtrl.AddString( APL_T("Все контексты"));
	m_contCtrl.SetItemData(m_iCont, 0);
	UpdateData(FALSE);
}

CString CChangeWhereUsed::PrintEffectivityInString(CString type, CString start, CString end)
{
	CString buf = _T("");
	
	if (type == _T("none"))
	{
		buf =  APL_T("По дате проведения изменения");
	}
	else if (type == _T("dated"))
	{
		COleDateTime odt;
		if (!start.IsEmpty())
		{
			aplString2Date(start, odt);
			buf=  APL_T("с: ") + odt.Format(_T("%d:%m:%Y %H:%M:%S"));
		}
		if (!end.IsEmpty())
		{
			aplString2Date(end, odt);
			buf+= APL_T(" по: ") + odt.Format(_T("%d:%m:%Y %H:%M:%S"));				
		}		
	}
	else if (type == _T("numbered"))
	{
		if (!start.IsEmpty())
		{
			buf=  APL_T("с: ") + start;
		}
		if (!end.IsEmpty())
		{
			buf += APL_T(" по: ") + end;				
		}		
	}
	
	return buf;
}

void CChangeWhereUsed::InsertText(int num, CaplInstance* newPdf, double dCount, CaplInstance* unit, 
									CString sPos, CString sPosNum, CString sEffType, CString sStart, CString sEnd,
									CString sPrior)
{
	CaplInstance* inst;
	CString buf, name;

	while(sPos.GetLength()<4)
		sPos=_T(" ")+sPos;
	
	if (newPdf)
	{
		if (!newPdf->attrs != 0)
			m_api->m_prd_mgr.LoadPrdInfo(newPdf);

		int prdIcon = m_api->GetInstIco(newPdf);

		apidata.GetAttr(newPdf, m_api->m_prd_mgr.a_pdf_prd, inst);
		if (inst)
		{
			apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_id, name);
			apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_name, buf);
			if (!name.IsEmpty())
				name+=_T(":");

			name += buf;
		}
		apidata.GetAttr(newPdf, m_api->m_prd_mgr.a_pdf_id, buf);
		if(!name.IsEmpty())
			name += _T(":");
		
		name += buf;
		
		m_WhereUsedList.SetItemText(num, 5, name);		
		m_WhereUsedList.SetItem(num, 5, LVIF_IMAGE, name, prdIcon, 0, 0, 0);
		
		int index = 6;
			
		if (unit)
			m_api->m_charact_mgr.GetUnitName(unit, name);
		buf.Format(_T("%g [%s]"), dCount, name);
		
		m_WhereUsedList.SetItemText(num, 6, sPos);
		m_WhereUsedList.SetItemText(num, 7, buf);
		m_WhereUsedList.SetItemText(num, 8, PrintEffectivityInString(sEffType, sStart, sEnd));
	}
}

void CChangeWhereUsed::OnChg2AssSelect() 
{
	UpdateData();
	
	CaplInstance* inst = m_api->m_change_mgr.SelectInstance(APL_MODE_SELECT_PDF, 
		 APL_T("Выберите изделие для изменения"));
	
	if (inst)
	{
		m_assPdf = inst;
		apidata.GetAttr(m_assPdf, m_api->m_prd_mgr.a_pdf_prd, inst);
		if (inst)
		{
			apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_id, m_sProductId);
			apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_name, m_sProductName);
		}
		apidata.GetAttr(m_assPdf, m_api->m_prd_mgr.a_pdf_id, m_sProductVer);
		UpdateData(FALSE);	
	
		OnChg2AssRefresh();
	}
}

void CChangeWhereUsed::OnChg2AssRefresh() 
{
	UpdateData();
		
	m_api->m_prd_mgr.WhereUsedProduct(m_assPdf, m_extRels, m_extPdfs);
	
	if(m_bNotShow)
	{
		aplExtent ext;
		if(m_bDateSelected)
		{
			m_api->m_prd_mgr.FilterlByDate(m_extRels, m_oleDate, ext);
			m_extRels.Clear();
			m_extRels.Append(ext);
			ext.Clear();
		}
		if(m_bSNSelected)
		{
			m_api->m_prd_mgr.FilterlBySN(m_extRels, m_sSN, ext);
			m_extRels.Clear(); 
			m_extRels.Append(ext);
			ext.Clear();
		}
		
		CaplInstance* cont= (CaplInstance*)m_contCtrl.GetItemData(m_contCtrl.GetCurSel());

		if(cont)
		{
			for(int i= 0; i<m_extRels.GetSize(); i++)
			{
				if(!m_api->m_prd_mgr.IsItemInContext(m_extRels[i], cont, m_api->m_prd_mgr.a_pdr_frames_of_reference))
				{
					m_extRels.Remove(i);
					i--;
					continue;
				}
			}
		}		
	}

	int i;
	CaplLoadData ld(&m_api->m_data, DEF_SOURCE);
	for (i = 0; i < m_extRels.GetSize(); i++)
	{
		if (m_extRels[i]->GetId() == 0)
			continue;
		
		ld.AddQuery(0, m_extRels[i]);
	}
	if (ld.IsQueryNotEmpty())
	{
		ld.AddQuery(_T('r'), 0, m_api->m_prd_mgr.e_pd_eff, m_api->m_prd_mgr.a_pde_usage, true, true);
		ld.LoadEx();
	}

	// если выбран фильтр по дате
	if (m_bDateSelected)
		m_bFilteredByDate = true;
	else
		m_bFilteredByDate = false;
	
	// если выбран фильтр по серийному номеру
	if (m_bSNSelected)
		m_bFilteredBySN = true;
	else
		m_bFilteredBySN = false;
	
	// фильтр по контексту
	CaplInstance* cont= (CaplInstance*)m_contCtrl.GetItemData(m_contCtrl.GetCurSel());
	
	if (cont)
		m_bFilteredByContext = true;
	else
		m_bFilteredByContext = false;

	FillWhereUsedList();
}

void CChangeWhereUsed::FillWhereUsedList()
{
	m_WhereUsedList.SetRedraw(FALSE);
	m_WhereUsedList.DeleteAllItems();
	m_WhereUsedList.SetRedraw(TRUE);
	m_WhereUsedItems.Clear();

	if (m_assPdf)
	{
		CaplInstance* inst;
		CString name, buf;
		int index = -1;
		int i;

		for (i = 0; i < m_extRels.GetSize(); i++)
		{
			CaplInstance* inst2= NULL;
			apidata.GetAttr(m_extRels[i], m_api->m_prd_mgr.a_pdr_r_ting, inst2);
			
			if (!inst2 || !inst2->GetId() || !inst2->GetType())
				continue;
			
			if (inst2->GetAccessmode() > aplRO)
				continue;
			
			int prdIcon = m_api->GetInstIco(inst2);
			
			apidata.GetAttr(inst2, m_api->m_prd_mgr.a_pdf_prd, inst);
			if (inst)
			{
				apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_id, name);
				apidata.GetAttr(inst, m_api->m_prd_mgr.a_prd_name, buf);
				if (!name.IsEmpty())
					name += _T(":");
				name += buf;
			}
			
			apidata.GetAttr(inst2, m_api->m_prd_mgr.a_pdf_id, buf);
			if (!name.IsEmpty())
				name += _T(":");
			name += buf;
			
			if (m_api->m_data.IsKindOf(m_extRels[i], m_api->m_prd_mgr.e_qacu_nauo))
			{
				apidata.GetAttr(m_extRels[i], m_api->m_prd_mgr.a_pdr_id, buf);
			}
			else if(m_api->m_data.IsKindOf(m_extRels[i], m_api->m_prd_mgr.e_make_from))
			{
				int iRank;
				apidata.GetAttr(m_extRels[i], m_api->m_prd_mgr.a_make_from_ranking, iRank);
				buf.Format(_T("%i"), iRank);
			}
			
			while(buf.GetLength()<4)
				buf= _T(" ")+buf;
			
			++index;
			m_WhereUsedList.InsertItem(index, buf, prdIcon);
			m_WhereUsedList.SetItemText(index, 1, name);

			//m_WhereUsedList.SetItemData(index, (DWORD)m_extRels[i]);
			sWhereUsedListItem* sItem = new sWhereUsedListItem;
			sItem->m_iRel = m_extRels[i];

			if (m_bFilteredByDate)
			{
				COleDateTime cur_time;
				if (m_bDateSelected)
				{
					m_dateCtrl.GetTime(cur_time);
					cur_time.SetDateTime(cur_time.GetYear(), cur_time.GetMonth(), cur_time.GetDay(), 0, 0, 0);
				}
				else
				{
					cur_time = COleDateTime::GetCurrentTime();
					cur_time.SetDateTime(cur_time.GetYear(), cur_time.GetMonth(), cur_time.GetDay(), 0, 0, 0);
				}
				
				if (!IsPrdEffByDate(m_extRels[i], cur_time))
				{
					sItem->m_Color = RGB(160, 160, 160);
					sItem->m_bActive = false;
				}
			}
			
			if (m_bFilteredBySN)
			{
				CString sn;
				m_sn.GetWindowText(sn);
				if (!IsPrdEffBySN(m_extRels[i], sn))
				{
					sItem->m_Color = RGB(160, 160, 160); //::GetSysColor(COLOR_GRAYTEXT);
					sItem->m_bActive = false;
				}
			}
			
			if (m_bFilteredByContext)
			{
				int cont_index = m_contCtrl.GetCurSel();
				CaplInstance* cont= (CaplInstance*)m_contCtrl.GetItemData(cont_index);
				
				if (!m_api->m_prd_mgr.IsItemInContext(m_extRels[i], cont, m_api->m_prd_mgr.a_pdr_frames_of_reference))
				{
					sItem->m_Color = RGB(160, 160, 160);
					sItem->m_bActive = false;
				}
			}

			m_WhereUsedList.SetItemData(index, (DWORD)sItem);			
			m_WhereUsedItems.Add(sItem);

			double dbl;
			apidata.GetAttrBN(m_extRels[i], _T("value_component"), dbl);
			apidata.GetAttrBN(m_extRels[i], _T("unit_component"), inst);
			buf = _T("");
			
			if (inst)
				m_api->m_charact_mgr.GetUnitName(inst, buf);
			
			name.Format(_T("%7.2f [%s]"), dbl, buf);

			m_WhereUsedList.SetItemText(index, 2, name);
			
			aplExtent aggr;
			apidata.GetAttr(m_extRels[i], m_api->m_prd_mgr.a_pdr_frames_of_reference, aggr);
			m_api->m_change_mgr.PrintItemContextInString(aggr, name);
			
			if (name.IsEmpty())
				name =  APL_T("Все контексты");

			m_WhereUsedList.SetItemText(index, 3, name);

			bool bFind = false;
			bool bContinue = true;
			
			CaplInstance* newPdf, *unit;
			CString sEffType, sStart, sEnd, sType, sPos, sPosNum, sPrior;
			double dCount;

			for (int j = 0; j < m_items->GetSize(); j++)
			{
				bContinue= true;
				CaplInstance* item= m_items->GetAt(j);
				
				if (-1 != m_delItems->Find(item))
					continue;
				
				CaplInstance* pdr_pdf = NULL, *new_pdr = NULL, *inst1 = NULL;
				
				buf = _T("");
				
				apidata.GetAttr(item, m_api->m_change_mgr.a_psc_changed_product, pdr_pdf);
				if (apidata.IsKindOf(pdr_pdf, m_api->m_prd_mgr.e_apl_pdf))
				{
					sType =  APL_T("Добавление");
					//sItem->m_Color = RGB(0, 110, 0);
				}
				else if (apidata.IsKindOf(pdr_pdf, m_api->m_prd_mgr.e_pdr))
				{
					sType =  APL_T("Замена");
					//sItem->m_Color = RGB(0, 0, 255);
				}				
				apidata.GetAttr(item, m_api->m_change_mgr.a_psc_changing_product, newPdf);
				if (!newPdf)
				{
					sType =  APL_T("Удаление");
					//sItem->m_Color = RGB(255, 0, 0);
				}
				
				apidata.GetAttr(item, m_api->m_change_mgr.a_psc_created_pdr, new_pdr);
				if (m_extRels[i] == new_pdr)//эта связь была создана в этом изменении
				{
					//удаляем ее, если это не Добавление
					bFind= true;
					bContinue= false;
					m_WhereUsedList.DeleteItem(index);index--;
					break;
				}
				else if(m_extRels[i]==pdr_pdf)
				{
					bFind = true;
					
					if (newPdf)
					{
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_position, sPos);					
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_position_num, sPosNum);					
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_value, dCount);
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_unit, unit);
					}
					apidata.GetAttr(item, m_api->m_change_mgr.a_psc_eff_type, sEffType);
					if (sEffType == _T("dated"))
					{
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_start_date, sStart);
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_end_date, sEnd);
					}
					else if (sEffType == _T("numbered"))
					{
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_start_num, sStart);
						apidata.GetAttr(item, m_api->m_change_mgr.a_psc_end_num, sEnd);
					}
					
					break;
				}
			}//for(int i= 0; i<m_items->GetSize(); i++)
			
			if (!bFind)
			{
				for (int j = 0; j < m_newItems->GetSize(); j++)
				{
					if (apidata.IsKindOf(m_newItems->GetAt(j).m_pdr, m_api->m_prd_mgr.e_apl_pdf)) 
					{
						sType =  APL_T("Добавление");
					}
					else if (apidata.IsKindOf(m_newItems->GetAt(j).m_pdr, m_api->m_prd_mgr.e_pdr))
					{
						sType =  APL_T("Замена");
					}
					
					if (!m_newItems->GetAt(j).m_pdf)
					{
						newPdf = NULL;
						sType =  APL_T("Удаление");
					}
					else newPdf = m_newItems->GetAt(j).m_pdf;
					
					if (m_extRels[i] == m_newItems->GetAt(j).m_pdr)
					{
						bFind = true;
						if (newPdf)
						{
							sPos = m_newItems->GetAt(j).m_sPosition;
							sPosNum = m_newItems->GetAt(j).m_sPositionNum;
							dCount = m_newItems->GetAt(j).m_value;
							unit = m_newItems->GetAt(j).m_unit;
						}
						
						sEffType = m_newItems->GetAt(j).m_sEffType;
						sStart = m_newItems->GetAt(j).m_sStartCond;
						sEnd = m_newItems->GetAt(j).m_sEndCond;
						
						break;
					}
				}
			}
			
			if (!bFind) //ищем в новых элементах
			{
				for (int j = 0; j < m_newestItems.GetSize(); j++)
				{
					if(apidata.IsKindOf(m_newestItems.GetAt(j).m_pdr, m_api->m_prd_mgr.e_apl_pdf)) 
					{
						sType=  APL_T("Добавление");
						//sItem->m_Color = RGB(0, 110, 0);
					}
					else if(apidata.IsKindOf(m_newestItems.GetAt(j).m_pdr, m_api->m_prd_mgr.e_pdr))
					{
						sType=  APL_T("Замена");
						//sItem->m_Color = RGB(0, 0, 255);
					}
					
					if (!m_newestItems.GetAt(j).m_pdf)
					{
						newPdf = NULL;
						sType =  APL_T("Удаление");
						//sItem->m_Color = RGB(255, 0, 0);
					}
					else
						newPdf = m_newestItems.GetAt(j).m_pdf;
					
					if (m_extRels[i] == m_newestItems.GetAt(j).m_pdr)
					{
						bFind = true;
						if (newPdf)
						{
							sPos = m_newestItems.GetAt(j).m_sPosition;
							sPosNum = m_newestItems.GetAt(j).m_sPositionNum;
							dCount = m_newestItems.GetAt(j).m_value;
							unit = m_newestItems.GetAt(j).m_unit;
						}
						
						sEffType = m_newestItems.GetAt(j).m_sEffType;
						sStart = m_newestItems.GetAt(j).m_sStartCond;
						sEnd = m_newestItems.GetAt(j).m_sEndCond;
						
						break;
					}
				}
			}
			
			if (bFind && bContinue)
			{
				m_WhereUsedList.SetItemText(index, 4, sType);
				InsertText(index, newPdf, dCount, unit, sPos, sPosNum, sEffType, sStart, sEnd, sPrior);
				
				
				if (sType ==  APL_T("Замена") && sItem->m_bActive)
					sItem->m_Color = RGB(0, 0, 255);
				
				if (sType ==  APL_T("Удаление") && sItem->m_bActive)
					sItem->m_Color = RGB(255, 0, 0);
				
				if (sType ==  APL_T("Добавление") && sItem->m_bActive)
					sItem->m_Color = RGB(0, 110, 0);
			}
		}

		m_WhereUsedList.AutoSizeAllColumns();
	}
}

void CChangeWhereUsed::OnChg2ItemChange() 
{
	// TODO: Add your control notification handler code here
	CChangeParamDlg dlg;
	dlg.m_api = m_api;
	dlg.m_mode = 0;
	
	dlg.m_sType = _T("change");
	
	dlg.m_sEffType = m_sEffType;
	dlg.m_sStart = m_sStartCond;
	dlg.m_sEnd = m_sEndCond;
	
	bool bNew = false;
	if (!FindItem(&dlg)) // для случая, когда элемент удален
	{
		bNew = true;
		// в диалог записываем параметры по умолчанию из pdr
		apidata.GetAttr(m_curItem, m_api->m_prd_mgr.a_pdr_id, dlg.m_sPosition);
		apidata.GetAttr(m_curItem, m_api->m_prd_mgr.a_apl_qacu_value, dlg.m_iValue);
		apidata.GetAttr(m_curItem, m_api->m_prd_mgr.a_apl_qacu_unit, dlg.m_unitInst);

		if (m_iDefaultPdf)
			dlg.m_newPdf = m_iDefaultPdf;
			
	}
	if (IDOK == dlg.DoModal())
	{
		if (bNew)
		{
			CPSCItemInfo info;
			info.m_pdr = m_curItem;
			info.m_pdf = dlg.m_newPdf;
			
			m_iDefaultPdf = dlg.m_newPdf;

			info.m_sId = dlg.m_sRegNum;
			info.m_sName= dlg.m_sPdrName;
			info.m_sDscr= dlg.m_sPdrDscr;
			info.m_sPosition= dlg.m_sPosition;
			info.m_sPositionNum= dlg.m_sPositionNum;
			info.m_value = dlg.m_iValue;
			info.m_unit = dlg.m_unitInst;
			
			info.m_sEffType = dlg.m_sEffType;
			info.m_sStartCond = dlg.m_sStart;
			info.m_sEndCond = dlg.m_sEnd;
			
			info.m_der_unit = dlg.m_derUnitInst;
			info.m_der_value = dlg.m_iDerValue;
			
			info.m_sort = dlg.m_assortment;
			info.m_prior = dlg.m_iPrior;
			info.m_razmer = dlg.m_sZagotov;
			info.m_tehTreb = dlg.m_sCondition;			
			
			info.SetContexts(dlg.m_contexts);

			aplExtent ext;
			apidata.GetAttr(m_curItem, m_api->m_prd_mgr.a_pdr_frames_of_reference, ext);
			info.SetAttachment(ext);
			
			m_newestItems.Add(info);
		}

		FillWhereUsedList();
	}
}

bool CChangeWhereUsed::FindItem(CChangeParamDlg *dlg, bool bDelete)
{
	int i;
	bool bFind= false;
	m_curPSC = NULL;
	m_curPSCInfo = NULL;
	
	for (i = 0; i < m_items->GetSize(); i++)
	{
		CaplInstance* inst = m_items->GetAt(i);
		
		CaplInstance* pdr= NULL, *pdf= NULL;
		CString sPos;
		CString buf= m_WhereUsedList.GetItemText(m_index, 6);
		buf.TrimRight();
		buf.TrimLeft();
		
		apidata.GetAttr(inst, m_api->m_change_mgr.a_psc_changed_product, pdr);
		apidata.GetAttr(inst, m_api->m_change_mgr.a_psc_changing_product, pdf);
		apidata.GetAttr(inst, m_api->m_change_mgr.a_psc_position, sPos);
		
		if(m_curItem==pdr || (pdr==m_assPdf && m_curItem==pdf && !buf.CompareNoCase(sPos)))
		{//могут добавлять один и тот же pdf, но под разной позицией
			bFind= true;
			m_curPSC= inst;
			if(dlg)dlg->m_psc= inst;
			if(bDelete) m_delItems->Add(inst);
			break;
		}
	}
	
	if(!bFind)
	{
		for(i= 0; i<m_newItems->GetSize(); i++)
		{
			CString buf= m_WhereUsedList.GetItemText(m_index, 6);
			buf.TrimRight();
			buf.TrimLeft();
			CString buf1;
			
			buf1= m_newItems->GetAt(i).m_sPosition;
			
			if(m_curItem==m_newItems->GetAt(i).m_pdr || 
				(m_curItem==m_newItems->GetAt(i).m_pdf &&
				!buf.CompareNoCase(buf1)))
			{//могут добавлять один и тот же pdf, но под разной позицией
				bFind= true;
				m_curPSCInfo= &m_newItems->ElementAt(i);
				if(dlg)	dlg->m_pscInfo= &m_newItems->ElementAt(i);
				if(bDelete) m_newItems->RemoveAt(i);
				break;
			}
		}
	}
	if(!bFind)
	{
		for(i= 0; i<m_newestItems.GetSize(); i++)
		{
			CString buf= m_WhereUsedList.GetItemText(m_index, 6);
			buf.TrimRight();
			buf.TrimLeft();
			CString buf1;
			
			buf1= m_newestItems.GetAt(i).m_sPosition;
			
			if(m_curItem==m_newestItems.GetAt(i).m_pdr || 
				(m_curItem==m_newestItems.GetAt(i).m_pdf &&
				!buf.CompareNoCase(buf1)))
			{//могут добавлять один и тот же pdf, но под разной позицией
				bFind= true;
				m_curPSCInfo= &m_newestItems.ElementAt(i);
				if(dlg)	dlg->m_pscInfo= &m_newestItems.ElementAt(i);
				if(bDelete) m_newestItems.RemoveAt(i);
				break;
			}
		}
	}
	
	return bFind;
}

void CChangeWhereUsed::OnItemchangedChgWhereUsedList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	CString buf;

	if (pNMListView->uNewState == 3)
	{	
		// индекс выбранного итема
		m_index = pNMListView->iItem;
		//m_curItem = (CaplInstance*)m_WhereUsedList.GetItemData(m_index);
		sWhereUsedListItem* sItem = (sWhereUsedListItem*)m_WhereUsedList.GetItemData(m_index);
		m_curItem = sItem->m_iRel;
		buf = m_WhereUsedList.GetItemText(m_index, 4);
	}
	else
	{
		m_index = -1;
		m_curItem = NULL;
	}

	m_itemChngBtn.EnableWindow(FALSE);
	m_itemDeleteBtn.EnableWindow(FALSE);
	
	m_itemClearBtn.EnableWindow(FALSE);
	m_itemPropBtn.EnableWindow(FALSE);

	if (buf ==  APL_T("Замена"))
	{
		if (!m_bReadOnly)
		{
			m_itemClearBtn.EnableWindow();
			m_itemDeleteBtn.EnableWindow();
		}
		
		m_itemPropBtn.EnableWindow();		
	}
	else if (buf ==  APL_T("Удаление"))
	{
		if (!m_bReadOnly)
		{
			m_itemClearBtn.EnableWindow();		
			m_itemChngBtn.EnableWindow();
		}
		
		m_itemPropBtn.EnableWindow();
	}

	if (m_index != -1 && !m_bReadOnly)
	{
		m_itemChngBtn.EnableWindow();
		m_itemDeleteBtn.EnableWindow();
	}

	*pResult = 0;
}

void CChangeWhereUsed::OnOK() 
{
	// TODO: Add extra validation here
	for (int i = 0; i < m_newestItems.GetSize(); i++)
		m_newItems->Add(m_newestItems[i]);
	
	CResizableDialog::OnOK();
}

void CChangeWhereUsed::OnChg2ItemDelete() 
{
	// TODO: Add your control notification handler code here
	CChangeParamDlg dlg;
	if (!FindItem(&dlg))
	{
		// новая запись об изменении
		dlg.m_api = m_api;
		dlg.m_mode = 0;
		
		dlg.m_sType = _T("delete");
		
		dlg.m_sEffType = m_sEffType;
		dlg.m_sStart = m_sStartCond;
		dlg.m_sEnd = m_sEndCond;
		
		if (IDOK == dlg.DoModal())
		{
			CPSCItemInfo info;
			info.m_pdr = m_curItem;
			info.m_pdf = NULL;
			info.m_sId = dlg.m_sRegNum;
			info.m_sPosition = _T("");
			info.m_sPositionNum = _T("");
			info.m_value = 0;
			info.m_unit = NULL;
			
			info.m_der_unit = 0;
			info.m_der_value = NULL;
			
			info.m_sort = NULL;
			info.m_prior = 0;
			info.m_razmer = _T("");
			info.m_tehTreb = _T("");			
			
			info.m_sEffType = dlg.m_sEffType;
			info.m_sStartCond = dlg.m_sStart;
			info.m_sEndCond = dlg.m_sEnd;

			info.SetContexts(dlg.m_contexts);

			m_newestItems.Add(info);
		}
	} 
	else //для случая, когда элемент заменен
	{
		CaplInstance* inst= NULL;
		if (m_curPSC) 
		{
			apidata.PutAttr(m_curPSC, m_api->m_change_mgr.a_psc_changing_product, (CaplInstance*)NULL);
			apidata.PutAttr(m_curPSC, m_api->m_change_mgr.a_psc_position, _T(""));
			apidata.PutAttr(m_curPSC, m_api->m_change_mgr.a_psc_value, 0.0);
			apidata.PutAttr(m_curPSC, m_api->m_change_mgr.a_psc_unit, inst);
		}
		else if (m_curPSCInfo) 
		{
			m_curPSCInfo->m_pdf = inst;
			m_curPSCInfo->m_sPosition = _T("");
			m_curPSCInfo->m_sPositionNum = _T("");
			m_curPSCInfo->m_value = 0;
			m_curPSCInfo->m_unit = NULL;
			
			m_curPSCInfo->m_der_unit = 0;
			m_curPSCInfo->m_der_value = NULL;
			
			m_curPSCInfo->m_sort = NULL;
			m_curPSCInfo->m_prior = 0;
			m_curPSCInfo->m_razmer = _T("");
			m_curPSCInfo->m_tehTreb = _T("");			
		}
	}
	FillWhereUsedList();
}

void CChangeWhereUsed::OnChg2Clear() 
{
	// TODO: Add your control notification handler code here
	if (IDYES == MessageBox( APL_T("Вы действительно хотите удалить запись об изменении?"),
		 APL_T("Удаление"), MB_YESNO | MB_ICONWARNING))
	{
		FindItem(NULL, true);
		FillWhereUsedList();
	}
}

void CChangeWhereUsed::OnChg2Prop() 
{
	// TODO: Add your control notification handler code here
	CChangeParamDlg dlg;
	dlg.m_api = m_api;
	dlg.m_mode = 0;
	dlg.m_bReadOnly = m_bReadOnly;
	dlg.m_change = m_change;
	
	CString buf = m_WhereUsedList.GetItemText(m_index, 4);
	if (buf ==  APL_T("Удаление"))
		dlg.m_sType = _T("delete");
	
	else if (buf ==  APL_T("Замена"))
		dlg.m_sType = _T("change");
	
	FindItem(&dlg);
	
	if (IDOK == dlg.DoModal())
	{
		FillWhereUsedList();
	}
}

void CChangeWhereUsed::OnChg2SetEff() 
{
	// TODO: Add your control notification handler code here
	CChangeParamDlg dlg;
	dlg.m_sType = _T("eff_type");	
	
	dlg.m_sEffType = m_sEffType;
	dlg.m_sStart = m_sStartCond;
	dlg.m_sEnd = m_sEndCond;
	
	if (IDOK == dlg.DoModal())
	{
		m_sEffType = dlg.m_sEffType;
		m_sStartCond = dlg.m_sStart;
		m_sEndCond = dlg.m_sEnd;
	}
}

void CChangeWhereUsed::OnChg2SnCheck() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	if (m_bSNSelected)
		m_sn.SetReadOnly(FALSE);
	else
		m_sn.SetReadOnly();	
}

void CChangeWhereUsed::OnChg2DateCheck() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	m_dateCtrl.EnableWindow(m_bDateSelected);
}

void CChangeWhereUsed::OnDatetimechangeChg2DateCtrl(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	m_refreshBtn.EnableWindow();
	*pResult = 0;
}

void CChangeWhereUsed::OnCloseupChg2ContextCombo() 
{
	// TODO: Add your control notification handler code here
	m_refreshBtn.EnableWindow();
}

void CChangeWhereUsed::OnDblclkChgWhereUsedList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	CString buf;
	if (-1 != m_index)
		buf = m_WhereUsedList.GetItemText(m_index, 4);
	
	if (!buf.IsEmpty())
		OnChg2Prop();
	
	*pResult = 0;
}

bool CChangeWhereUsed::IsPrdEffByDate(CaplInstance* rel, COleDateTime date)
{
	aplExtent eff_ext;

	CString date_start, date_end;
	CString dt;
	aplDate2String(date, dt);
	
	int size = 0;
	int i;
	CaplInstance *inst;

	m_api->m_data.GetEntityExtent(m_api->m_prd_mgr.e_pd_eff, eff_ext);

	for (i = 0; i < eff_ext.GetSize(); i++)
	{
		apidata.GetAttr(eff_ext[i], m_api->m_prd_mgr.a_pde_usage, inst);
		if (inst != rel)
			continue;

		if (apidata.IsKindOf(eff_ext[i],m_api->m_prd_mgr.e_dat_eff))
		{
			apidata.GetAttr(eff_ext[i], m_api->m_prd_mgr.a_dat_eff_start_s, date_start);
			apidata.GetAttr(eff_ext[i], m_api->m_prd_mgr.a_dat_eff_end_s, date_end);
			
			if (date_start.IsEmpty())
				return false;

			if (date_start > dt)
				return false;

			if (date_end.IsEmpty())
				return true;

			if (date_end >= dt)
				return true;

			size++;
		}
	}

	if (size == 0)
		return true;

	return false;
}

bool CChangeWhereUsed::IsPrdEffBySN(CaplInstance* rel, const TCHAR* sn)
{
	aplExtent eff_ext;
	
	CString sn_start, sn_end;
	
	int size = 0;
	int i;
	CaplInstance *inst;

	m_api->m_data.GetEntityExtent(m_api->m_prd_mgr.e_pd_eff, eff_ext);

	for (i = 0; i < eff_ext.GetSize(); i++)
	{
		apidata.GetAttr(eff_ext[i], m_api->m_prd_mgr.a_pde_usage, inst);
		if (inst != rel)
			continue;

		if (apidata.IsKindOf(eff_ext[i],m_api->m_prd_mgr.e_sn_eff))
		{
			apidata.GetAttr(eff_ext[i], m_api->m_prd_mgr.a_sn_eff_start, sn_start);
			apidata.GetAttr(eff_ext[i], m_api->m_prd_mgr.a_sn_eff_end, sn_end);

			if (sn_start.IsEmpty())
				return false;

			if (sn_start > sn)
				return false;

			if (sn_end.IsEmpty())
				return true;

			if (sn_end >= sn)
				return true;

			size++;
		}
	}

	if (size == 0)
		return true;

	return false;
}

void CChangeWhereUsed::OnCustomdrawWhereUsedList ( NMHDR* pNMHDR, LRESULT* pResult )
{
	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 )
	{
		sWhereUsedListItem* sItem = (sWhereUsedListItem*)m_WhereUsedList.GetItemData(pLVCD->nmcd.dwItemSpec);
		if (sItem)
			pLVCD->clrText = sItem->m_Color;
		
		*pResult |= CDRF_NEWFONT; //CDRF_DODEFAULT;
	}
}
