// BPInstDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BPInstDlg.h"
#include "dictionary.h"

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

/////////////////////////////////////////////////////////////////////////////
// CBPInstDlg dialog


CBPInstDlg::CBPInstDlg(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CBPInstDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBPInstDlg)
	m_id = _T("");
	m_descr = _T("");
	m_name = _T("");
	m_bp_id = _T("");
	//}}AFX_DATA_INIT
	m_bp_inst_ref=0;
	m_api=0;
	m_inst=0;
	m_bp=0;
	m_item=0;
	m_context=0;
	m_base_bp_inst=0;
	m_context_changed=false;
	m_ReadOnly=false;
	m_changed_aggr=false;
	m_add_mode=false;
}


void CBPInstDlg::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBPInstDlg)
	DDX_Control(pDX, IDC_TIME, m_time_ctrl);
	DDX_Control(pDX, IDC_DATE, m_date_ctrl);
	DDX_Control(pDX, IDC_SELECT_BP_BTN, m_bp_sel_btn);
	DDX_Control(pDX, IDC_BP, m_bp_ctrl);
	DDX_Control(pDX, IDC_CONTEXTS_NAMES, m_context_names_ctrl);
	DDX_Control(pDX, IDC_ELEMENTS, m_elements);
	DDX_Control(pDX, IDC_ST_ACTION_NAME, m_st_bp_name);
	DDX_Control(pDX, IDC_ST_ACTION_ICO, m_st_action_ico);
	DDX_Control(pDX, IDC_ADD_BP_INST, m_add_btn);
	DDX_Control(pDX, IDC_EL_BOTTOM, m_bottom_btn);
	DDX_Control(pDX, IDC_CONTEXT_SEL, m_context_sel_btn);
	DDX_Control(pDX, IDC_EL_TOP, m_top_btn);
	DDX_Control(pDX, IDCANCEL, m_cancel_btn);
	DDX_Control(pDX, IDOK, m_ok_btn);
	DDX_Control(pDX, IDC_CONTEXT_TEXT, m_context_text_ctrl);
	DDX_Control(pDX, IDC_BP_INST_NAME, m_name_ctrl);
	DDX_Control(pDX, IDC_BP_INST_ID, m_id_ctrl);
	DDX_Control(pDX, IDC_BP_INST_DESCR, m_descr_ctrl);
	DDX_Control(pDX, IDC_TAB1, m_Tab);
	DDX_Control(pDX, IDC_B_PROPS_ADD_BPI, m_bPropsAdd);
	DDX_Control(pDX, IDC_B_PROPS_DEL_BPI, m_bPropsDel);
	DDX_Control(pDX, IDC_B_PROPS_PROPS_BPI, m_bPropsProps);
	DDX_Text(pDX, IDC_BP_INST_ID, m_id);
	DDX_Text(pDX, IDC_BP_INST_DESCR, m_descr);
	DDX_Text(pDX, IDC_BP_INST_NAME, m_name);
	DDX_Text(pDX, IDC_BP, m_bp_id);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CBPInstDlg, CResizableDialog)
	//{{AFX_MSG_MAP(CBPInstDlg)
	ON_BN_CLICKED(IDC_CONTEXT_SEL, OnContextSel)
	ON_BN_CLICKED(IDC_SELECT_BP_BTN, OnSelectBpBtn)
	ON_BN_CLICKED(IDC_EL_BOTTOM, OnElBottom)
	ON_BN_CLICKED(IDC_EL_TOP, OnElTop)
	ON_BN_CLICKED(IDC_ADD_BP_INST, OnAddBpInst)
	ON_NOTIFY(NM_DBLCLK, IDC_ELEMENTS, OnDblclkElements)
	ON_WM_CONTEXTMENU()
	ON_BN_CLICKED(IDC_ST_ACTION_NAME, OnStActionName)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnSelchangeTab1)
	ON_BN_CLICKED(IDC_B_PROPS_ADD_BPI, OnBPropsAddBpi)
	ON_BN_CLICKED(IDC_B_PROPS_DEL_BPI, OnBPropsDelBpi)
	ON_BN_CLICKED(IDC_B_PROPS_PROPS_BPI, OnBPropsPropsBpi)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CBPInstDlg::SetAnchors(void)
{
	AddAnchor(IDC_T_ID,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_BP_INST_ID,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_T_NAME,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_BP_INST_NAME,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_T_DESCR,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_BP_INST_DESCR,TOP_LEFT,TOP_RIGHT);

	AddAnchor(IDC_ELEMENTS,TOP_LEFT,BOTTOM_RIGHT);
		AddAnchor(IDC_EL_TOP,MIDDLE_LEFT);
		AddAnchor(IDC_EL_BOTTOM,MIDDLE_LEFT);

	AddAnchor(IDC_DATE_TEXT,BOTTOM_LEFT);
	AddAnchor(IDC_DATE,BOTTOM_LEFT);
	AddAnchor(IDC_TIME,BOTTOM_LEFT);

	AddAnchor(IDC_BP_TEXT,BOTTOM_LEFT);
	AddAnchor(IDC_BP,BOTTOM_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_SELECT_BP_BTN,BOTTOM_RIGHT);
	
	AddAnchor(IDC_CONTEXT_TEXT,BOTTOM_LEFT);
	AddAnchor(IDC_CONTEXTS_NAMES,BOTTOM_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_CONTEXT_SEL,BOTTOM_RIGHT);

	AddAnchor(IDC_ADD_BP_INST,BOTTOM_LEFT);
	AddAnchor(IDOK,BOTTOM_RIGHT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);

	return TRUE;
}

BOOL CBPInstDlg::InitViews(void)
{
	CaplCharactView*	pCharView	=NULL;
	CaplApprovalView*	pApprView	=NULL;
	CaplDocsView*		pDocsView	=NULL;
	CaplAccessView*		pAccView	=NULL;

	CWnd*				pWnd		=NULL;

	CArray<int,int>		caExcludes;

	CRect				rt;

	DWORD				dwStyles=WS_CHILD|WS_BORDER;

	CaplInstance*		cit			=m_inst;

	m_Tab.SetImageList(aplGetTabCtrlImageList());

	m_Tab.InsertItem(0, APL_T("Свойства"),0);
	m_Tab.AddTab(0,NULL);
	m_Tab.SetCurSel(0);

	caExcludes.Add(IDC_B_PROPS_ADD_BPI);
	caExcludes.Add(IDC_B_PROPS_DEL_BPI);
	caExcludes.Add(IDC_B_PROPS_PROPS_BPI);
	caExcludes.Add(IDC_ST_ACTION_ICO);
	caExcludes.Add(IDC_ST_ACTION_NAME);

	m_Tab.AddExcludeIDs(caExcludes);

	//pWnd=GetDlgItem(IDC_T_VIEW_FRAME);
	//pWnd->GetClientRect(rt);
	//pWnd->ClientToScreen(rt);
	m_Tab.GetWindowRect(rt);
	rt.DeflateRect(8,75,8,8);
	ScreenToClient(rt);

	if(NULL!=m_inst)
	{
		m_Tab.InsertItem(1, APL_T("Характеристики"),1);
		pCharView=(CaplCharactView*)(RUNTIME_CLASS(CaplCharactView)->CreateObject());
		pCharView->Create(NULL,NULL,dwStyles,rt,this,0);
		pCharView->m_inst=cit;
		pCharView->m_api=m_api;

		pCharView->SetBtnsHandles(&m_bPropsAdd,&m_bPropsDel,&m_bPropsProps);
		pCharView->OnInitialUpdate();
		m_Tab.AddTab(1,pCharView);
		AddAnchor(pCharView->m_hWnd,TOP_LEFT,BOTTOM_RIGHT);

		m_Tab.InsertItem(2, APL_T("Документы"),2);
		pDocsView=(CaplDocsView*)(RUNTIME_CLASS(CaplDocsView)->CreateObject());
		pDocsView->Create(NULL,NULL,dwStyles,rt,this,0);
		pDocsView->m_inst=cit;
		pDocsView->m_api=m_api;

		pDocsView->SetBtnsHandles(&m_bPropsAdd,&m_bPropsDel,&m_bPropsProps);
		pDocsView->OnInitialUpdate();
		m_Tab.AddTab(2,pDocsView);
		AddAnchor(pDocsView->m_hWnd,TOP_LEFT,BOTTOM_RIGHT);

		m_Tab.InsertItem(3, APL_T("Электронные подписи"),3);
		pApprView=(CaplApprovalView*)(RUNTIME_CLASS(CaplApprovalView)->CreateObject());
		pApprView->Create(NULL,NULL,dwStyles,rt,this,0);
		pApprView->m_inst=cit;
		pApprView->m_api=m_api;

		pApprView->SetBtnsHandles(&m_bPropsAdd,&m_bPropsDel,&m_bPropsProps);
		pApprView->OnInitialUpdate();
		m_Tab.AddTab(3,pApprView);
		AddAnchor(pApprView->m_hWnd,TOP_LEFT,BOTTOM_RIGHT);
	}

	if(NULL==m_inst)
		m_Tab.InsertItem(1, APL_T("Доступ"),17);
	else
		m_Tab.InsertItem(4, APL_T("Доступ"),17);

	pAccView=(CaplAccessView*)(RUNTIME_CLASS(CaplAccessView)->CreateObject());
	pAccView->Create(NULL,NULL,dwStyles|LVS_NOSORTHEADER,rt,this,0);
	pAccView->m_inst=cit;
	pAccView->m_api=m_api;

	pAccView->SetBtnsHandles(&m_bPropsAdd,&m_bPropsDel,&m_bPropsProps);
	pAccView->OnInitialUpdate();
	if(NULL==m_inst)
	{
		m_Tab.AddTab(1,pAccView);

		CString	csAccPatName;
		
		CaplEntity* et=NULL;

		et=m_api->m_bp_mgr.e_apl_bp_inst;
		if(true==m_api->m_bp_mgr.m_AutoUsurpire)
			if(TRUE==m_api->m_options_mgr.GetDefTmplName(et,csAccPatName))
				pAccView->SetDefaultTemplate(csAccPatName);
	}
	else
		m_Tab.AddTab(4,pAccView);

	AddAnchor(pAccView->m_hWnd,TOP_LEFT,BOTTOM_RIGHT);

	return TRUE;
}

void CBPInstDlg::ChangeViewBtnsState(BOOL bDis,BOOL bHide)
{
	CWnd*	pwnd	=NULL;

	int		iIDs[]={IDC_B_PROPS_ADD_BPI,IDC_B_PROPS_DEL_BPI,IDC_B_PROPS_PROPS_BPI};
	int		iShow=SW_SHOW;
	int		i;

	if(TRUE==bHide)
		iShow=SW_HIDE;	

	for(i=0;i<sizeof(iIDs)/sizeof(int);i++)
	{
		pwnd=GetDlgItem(iIDs[i]);
		pwnd->EnableWindow(bDis);
		pwnd->ShowWindow(iShow);
	}
}

void CBPInstDlg::GetAccessString(void)
{
	CaplAccessView*	pAccView	=NULL;

	CWnd*			pwnd		=NULL;

	int				i;
	
	for(i=0;i<m_Tab.GetItemCount();i++)
	{
		m_Tab.GetTabView(i,pwnd);
		if(pwnd!=NULL)
			if(pwnd->IsKindOf(RUNTIME_CLASS(CaplAccessView)))
			{
				pAccView=(CaplAccessView*)pwnd;
				pAccView->GetAccessString(m_csAccessString);
			}
	}
}


/////////////////////////////////////////////////////////////////////////////
// CBPInstDlg message handlers

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

	m_bPropsAdd.SetIcon(GetAplStdIco16(APLSTDICO_PLUS));
	m_bPropsAdd.SetFlat(FALSE);
	m_bPropsDel.SetIcon(GetAplStdIco16(APLSTDICO_MINUS));
	m_bPropsDel.SetFlat(FALSE);
	m_bPropsProps.SetIcon(GetAplTableIco(APL_TABLE_PROP));
	m_bPropsProps.SetFlat(FALSE);

	{	// Изменение Tab-а под текущее окно
		CRect rectTab,rectCancel;
		m_Tab.GetWindowRect(rectTab);
		m_cancel_btn.GetWindowRect(rectCancel);
		rectTab.bottom=rectCancel.top-5;
		rectTab.right=rectCancel.right;
		ScreenToClient(rectTab);
		m_Tab.MoveWindow(rectTab);
	}

	InitViews();
	
	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_top_btn.SetIcon(GetAplTableIco(APL_TABLE_TOP));
	m_bottom_btn.SetIcon(GetAplTableIco(APL_TABLE_BOTTOM));

	m_context_sel_btn.SetFlat(FALSE);	

	m_top_btn.ShowWindow(SW_HIDE);
	m_bottom_btn.ShowWindow(SW_HIDE);

	int color_mode=0;
	if(aplGetBitPerPixel(this)>8) 
		color_mode=1;
	
	m_add_btn.SetIcon(GetAplStdIco16(APLSTDICO_PLUS));
	m_add_btn.SetTooltipText( APL_T("Добавить входящий экземпляр бизнес-процесса"));
	m_add_btn.SetFlat(FALSE);

	if(!m_base_bp_inst) 
		m_add_btn.ShowWindow(SW_HIDE);

	COLORMAP  cm;
	cm.from=RGB(192,192,192);
	cm.to=GetSysColor(COLOR_BTNFACE);

	m_ico_bmp.LoadMappedBitmap(IDB_ACTION_ICO,0,&cm,1);
	HBITMAP hBmpOld0=m_st_action_ico.SetBitmap(HBITMAP(m_ico_bmp));
	::DeleteObject(hBmpOld0);	
	
	if(aplGetBitPerPixel(this)>8)
	{
		m_name_bmp.LoadMappedBitmap(IDB_BP_INST_NAME,0,&cm,1);
		m_name_qm_bmp.LoadMappedBitmap(IDB_ACTION_QM,0,&cm,1);
	}
	else
	{
		m_name_bmp.LoadMappedBitmap(IDB_ACTION_NAME_16,0,&cm,1);
		m_name_qm_bmp.LoadMappedBitmap(IDB_ACTION_QM_16,0,&cm,1);
	}

	HBITMAP hBmpOld=m_st_bp_name.SetBitmap(HBITMAP(m_name_bmp));
	::DeleteObject(hBmpOld);

	m_elements.InsertColumn(0, APL_T("№"),LVCFMT_LEFT,25);
	m_elements.InsertColumn(1, APL_T("Обозначение"),LVCFMT_LEFT,100);
	m_elements.InsertColumn(2, APL_T("Наименование"),LVCFMT_LEFT,150);
	m_elements.InsertColumn(3, APL_T("Описание"),LVCFMT_LEFT,200);

    ListView_SetExtendedListViewStyle(m_elements.m_hWnd,
		ListView_GetExtendedListViewStyle(m_elements.m_hWnd)
                | LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_INFOTIP);

	CString buf=_T("");
	if(m_bp_inst_ref)
	{
		m_context_sel_btn.EnableWindow(TRUE);
		m_api->m_data.GetAttr(m_bp_inst_ref,m_api->m_bp_mgr.a_bp_inst_ref_frames_of_reference,m_bp_inst_ref_contexts);
		if(m_bp_inst_ref_contexts.GetSize()>0)
			m_api->m_bp_mgr.PrintItemContextInString(m_bp_inst_ref_contexts,buf);
		else 
			buf=S::all_context();
		
		m_context_names_ctrl.SetWindowText(buf);
	}

	if(!m_bp_inst_ref && m_item)	
	{
		m_context_sel_btn.EnableWindow(TRUE);
		if(m_context)
		{
			m_bp_inst_ref_contexts.Add(m_context);
			m_api->m_bp_mgr.PrintItemContextInString(m_bp_inst_ref_contexts,buf);
		}
		else
			buf=S::all_context();
		m_context_names_ctrl.SetWindowText(buf);

	}
	if(m_inst)
	{
		m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_id,m_id);
		m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_name,m_name);
		m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_descr,m_descr);
		m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_process,m_bp);
		m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_date_time,buf);
	}
	COleDateTime dt;
	dt = COleDateTime::GetCurrentTime();

	if(m_bp) 
		m_api->GetItemName(m_bp,m_bp_id);
	if(buf!=_T("")) 
		aplString2Date(buf, dt);
	if(dt.GetStatus()==COleDateTime::valid)
	{
		m_time_ctrl.SetTime(dt);
		m_date_ctrl.SetTime(dt);
	}
	UpdateElements();
	SetReadOnlyItems();

	m_Tab.InitStates();
	SetAnchors();

	UpdateData(FALSE);
	
	return TRUE;
}

void CBPInstDlg::UpdateElements()
{
	if(!m_inst) return;
	int k=m_elements.GetNextItem(-1,LVNI_SELECTED);
	m_elements.DeleteAllItems();
	CaplInstance *inst;
	CaplAggr aggr0;
	CString buf;
	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_elements,aggr0);	
	for(int i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,inst);
		if(inst==0) continue;
		buf.Format(_T("%3i"),i+1);
		int k=m_elements.InsertItem(i,buf);
		m_elements.SetItemData(k,(long)inst);
		CString id=_T(""),name=_T(""),descr=_T("");
		m_api->m_data.GetAttr(inst,m_api->m_bp_mgr.a_bp_inst_id,id);
		m_api->m_data.GetAttr(inst,m_api->m_bp_mgr.a_bp_inst_name,name);
		m_api->m_data.GetAttr(inst,m_api->m_bp_mgr.a_bp_inst_descr,descr);
		m_elements.SetItemText(k,1,id);
		m_elements.SetItemText(k,2,name);
		m_elements.SetItemText(k,3,descr);
	}

	if(k>0&&k<m_elements.GetItemCount())
		m_elements.SetItemState(k,LVIS_SELECTED| LVIS_FOCUSED|LVIS_DROPHILITED,-1);
	if(m_ReadOnly || !m_elements.GetItemCount())
	{
		m_top_btn.ShowWindow(SW_HIDE);
		m_bottom_btn.ShowWindow(SW_HIDE);
	}
	else 
	{
		m_top_btn.ShowWindow(SW_SHOW);
		m_bottom_btn.ShowWindow(SW_SHOW);
	}
}

bool CBPInstDlg::SaveChanges()
{
	// TODO: Add extra validation here
	UpdateData(TRUE);

	//Проверка заполнения полей
	m_id.TrimLeft();
	m_id.TrimRight();
	m_name.TrimLeft();
	m_name.TrimRight();
	m_descr.TrimLeft();
	m_descr.TrimRight();
	
	if(m_id==_T("")) {AfxMessageBox( APL_T("Поле \"Обозначение\" не заполнено !")); return false;}
	
	CString buf=_T(""),buf0=_T("");
	
	if(m_inst) m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_id,buf);
	
	if(buf!=m_id)
	{
		//проверка уникальности id
		CaplAttrValue tst_values[1];               

		tst_values[0].value.Set((LPCTSTR)m_id); 
		tst_values[0].attr=m_api->m_bp_mgr.a_bp_inst_id;      
	
		if(!m_api->m_data.TestUniqueAttrValues(m_api->m_bp_mgr.e_apl_bp_inst,m_inst,1,&tst_values[0]))
		{
			AfxMessageBox( APL_T("Экземпляр бизнес-процесса с таким обозначением уже есть в базе !!!"));
			return false;
		}
	}

	if(m_inst==0) 
	{
		m_inst=m_api->m_data.CreateInstance(m_api->m_bp_mgr.e_apl_bp_inst);
		if(!m_inst) 
		{
			AfxMessageBox( APL_T("Не удалось создать экземпляр бизнес-процесса!"));
			return false;
		}
	}

	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_id,buf);
	if(buf!=m_id) m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_id,m_id);	
	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_name,buf);
	if(buf!=m_name) m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_name,m_name);
	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_descr,buf);
	if(buf!=m_descr) m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_descr,m_descr);
	CaplInstance *inst=0;
	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_process,inst);
	if(inst!=m_bp) m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_process,m_bp);

	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_date_time,buf0);
	COleDateTime d_time,t_time,dt;
	m_date_ctrl.GetTime(d_time);	
	m_time_ctrl.GetTime(t_time);
	dt.SetDateTime(d_time.GetYear(),d_time.GetMonth(),d_time.GetDay(),
		t_time.GetHour(),t_time.GetMinute(),t_time.GetSecond());
	aplDate2String(dt,buf);
	if(buf!=buf0) m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_date_time,buf);

	if(m_item && !m_bp_inst_ref) 
	{
		m_bp_inst_ref=m_api->m_bp_mgr.CreateInstanceAssociation(m_item,m_inst,m_context);
		m_context_changed=true;
	}
	
	if(m_bp_inst_ref)
	{
		if(m_context_changed)
		{
			if(m_bp_inst_ref_contexts.GetSize()>0)
				m_api->m_data.PutAttr(m_bp_inst_ref,m_api->m_bp_mgr.a_bp_inst_ref_frames_of_reference,m_bp_inst_ref_contexts);
			else
			{
				CaplValue empty_val;
				m_api->m_data.PutAttr(m_bp_inst_ref,m_api->m_bp_mgr.a_bp_inst_ref_frames_of_reference,empty_val);
			}
		}
	}
	return true;
}

void CBPInstDlg::OnContextSel() 
{
	if(m_api->m_bp_mgr.ChangeItemContext(m_bp_inst_ref_contexts))
	{
		CString buf;
		if(m_bp_inst_ref_contexts.GetSize()>0)
			m_api->m_bp_mgr.PrintItemContextInString(m_bp_inst_ref_contexts,buf);
		else buf=S::all_context();
		m_context_names_ctrl.SetWindowText(buf);
		m_context_changed=true;
	}	
}

void CBPInstDlg::OnOK() 
{
	if(!SaveChanges()) 
		return;
	CResizableDialog::OnOK();
}

void CBPInstDlg::OnSelectBpBtn() 
{
	UpdateData(TRUE);
	m_bp=m_api->m_bp_mgr.SelectInstance(APL_MODE_SELECT_BP);
	if(m_bp)
	{
		m_api->GetItemName(m_bp,m_bp_id);
		UpdateData(FALSE);
	}
}

void CBPInstDlg::SetReadOnlyItems()
{
	m_id_ctrl.SetReadOnly(m_ReadOnly);
	m_name_ctrl.SetReadOnly(m_ReadOnly);
	m_descr_ctrl.SetReadOnly(m_ReadOnly);
	m_ok_btn.EnableWindow(!m_ReadOnly);
	m_add_btn.EnableWindow(!m_ReadOnly);
	if(m_bp_inst_ref) m_context_sel_btn.EnableWindow(!m_ReadOnly);
	m_bp_sel_btn.EnableWindow(!m_ReadOnly);
	m_time_ctrl.EnableWindow(!m_ReadOnly);
	m_date_ctrl.EnableWindow(!m_ReadOnly);
}

void CBPInstDlg::OnElBottom() 
{
	if(m_ReadOnly) return;
	if(!m_inst) return;
	CaplAggr aggr0;
	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_elements,aggr0);	
	int k=m_elements.GetNextItem(-1,LVNI_SELECTED);
	int k1=k+1;
	
	if(k<0)  return;
	if(k>aggr0.GetSize()-2) return;
	
	m_changed_aggr=true;
	CaplValue *v=aggr0.aggr.Data[k1];
	aggr0.aggr.Data[k1]=aggr0.aggr.Data[k];
	aggr0.aggr.Data[k]=v;
	m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_elements,aggr0);	
	
	m_elements.SetItemState(k,LVIS_SELECTED| LVIS_FOCUSED,-1);
	UpdateElements();	
}

void CBPInstDlg::OnElTop() 
{
	if(m_ReadOnly) return;
	if(!m_inst) return;
	CaplAggr aggr0;
	m_api->m_data.GetAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_elements,aggr0);	
	int k=m_elements.GetNextItem(-1,LVNI_SELECTED)-1;
	int k1=k+1;
	
	if(k<0)  return;
	if(k>aggr0.GetSize()-2) return;
	
	m_changed_aggr=true;
	CaplValue *v=aggr0.aggr.Data[k1];
	aggr0.aggr.Data[k1]=aggr0.aggr.Data[k];
	aggr0.aggr.Data[k]=v;
	m_api->m_data.PutAttr(m_inst,m_api->m_bp_mgr.a_bp_inst_elements,aggr0);	
	
	m_elements.SetItemState(k+1,LVIS_SELECTED| LVIS_FOCUSED,-1);
	UpdateElements();	
}

bool CBPInstDlg::CreateSubBPInst()
{
	if(!m_inst)
	{
		if(IDYES!=AfxMessageBox( APL_T("Для выполнения данного действия необходимо \nсохранить данные экземпляра бизнес-процесса\nПродолжить ?"),
			MB_YESNO|MB_ICONQUESTION)) return false;
		if(!SaveChanges()) return false;
	}
	if(m_api->m_bp_mgr.CreateBPInst(m_inst))
	{
		UpdateElements();
		return true;
	}
	return false;
}

void CBPInstDlg::OnAddBpInst() 
{
	if(!SaveChanges()) return;
	m_add_mode=true;
	CResizableDialog::EndDialog(IDOK);
}

void CBPInstDlg::OnDblclkElements(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) pNMHDR;
	*pResult = 0;
	int k=lpnmitem->iItem;
	if(k<0||k>m_elements.GetItemCount()-1) return;
	CaplInstance *act=(CaplInstance*)m_elements.GetItemData(k);
	if(act==0) return;
	if(m_api->m_bp_mgr.ShowBPInstProperties(act))
		UpdateElements();
}

void LoadContextMenuIcon();

void CBPInstDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	if(m_ReadOnly) return;

	int i=0,j=0;
	CaplInstance *sel_bp_inst=0;
	if(false==PointToVal(&point,i,&sel_bp_inst)) return;

    CMenu menu;CMenu* pPopup;
    VERIFY(menu.LoadMenu(IDR_CONTEXT_MENU));
	pPopup = menu.GetSubMenu(5);
	LoadContextMenuIcon();
	CaplMenu::Install(this);
    if(!sel_bp_inst)
	{
		pPopup->RemoveMenu(ID_DELETE_BP_REL, MF_BYCOMMAND );
		pPopup->RemoveMenu(ID_DELETE_BP, MF_BYCOMMAND );
	}
	
	BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON |TPM_RETURNCMD,	point.x, point.y,this); // use main window for cmds

	switch(res)
	{
		case ID_CREATE_BP_INST:
			{
				if(CreateSubBPInst()){
					UpdateElements();
				}
			}
			break;
		case ID_DELETE_BP_REL:
			{
				if(AfxMessageBox( APL_T("Вы действительно хотите удалить связь ?"),MB_YESNO)==IDYES)
				{
					if(m_api->m_bp_mgr.DeleteBPInstRelation(sel_bp_inst,m_inst)) 
						UpdateElements();
				}
			}
			break;
		case ID_DELETE_BP:
			{
				if(AfxMessageBox( APL_T("Вы действительно хотите удалить экземпляр бизнес-процесса ?"),MB_YESNO)==IDYES)
				{
					if(m_api->m_bp_mgr.DeleteBPInst(sel_bp_inst)) 
						UpdateElements();
				}
			}
			break;
	}
}

bool CBPInstDlg::PointToVal(CPoint *point, int &i,CaplInstance **inst)
{
	*inst=0;

	if(point!=0)
	{
		i=-1; 
				
		CRect rect;
		m_elements.GetWindowRect(&rect);
		if(!rect.PtInRect(*point)) return false;

		CPoint m_point_context_menu=*point;
		m_elements.ScreenToClient(&m_point_context_menu);
	
		// Отсекание нажатия на header
		CHeaderCtrl*head= m_elements.GetHeaderCtrl();
		head->GetWindowRect(&rect);
		if(rect.PtInRect(*point)) return false;
		
		LVHITTESTINFO lvhti;
		lvhti.pt = m_point_context_menu;
		m_elements.SubItemHitTest(&lvhti);
		
		i=lvhti.iItem;
		if(i<0) return true;
	}
	
	*inst=(CaplInstance*)m_elements.GetItemData(i);
	
	return true;
}

void CBPInstDlg::OnStActionName() 
{
	// TODO: Add your control notification handler code here
	CString text,buf;
	//	if(((GetKeyState(VK_LMENU) & 0xff00)!=0)&&((GetKeyState(VK_RMENU) & 0xff00)!=0)){
	if(((GetKeyState(VK_LMENU) )!=0)&&((GetKeyState(VK_RMENU) )!=0)){
		text.Format(_T("\n"));
		if(m_bp!=0){buf.Format(_T("m_bp->id %i;\n"),m_bp->GetId());text+=buf;}else{buf.Format(_T("m_bp==0;\n"));}
		if(m_bp_inst_ref!=0){buf.Format(_T("m_bp_inst_ref->id %i;\n"),m_bp_inst_ref->GetId());text+=buf;}else{buf.Format(_T("m_bp_inst_ref==0;\n"));}
		if(m_inst!=0){buf.Format(_T("m_inst->GetId() %i;\n"),m_inst->GetId());text+=buf;}else{buf.Format(_T("m_inst==0;\n"));}
		if(m_item!=0){buf.Format(_T("m_item->id %i;\n"),m_item->GetId());text+=buf;}else{buf.Format(_T("m_item==0;\n"));}
		if(m_context!=0){buf.Format(_T("m_context->id %i;\n"),m_context->GetId());text+=buf;}else{buf.Format(_T("m_context==0;\n"));}
		if(m_base_bp_inst!=0){buf.Format(_T("m_base_bp_inst->GetId() %i;\n"),m_base_bp_inst->GetId());text+=buf;}else{buf.Format(_T("m_base_bp_inst==0;\n"));}
		AfxMessageBox(text);
	}
	
}

void CBPInstDlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CaplPropsView* pView	=NULL;
	
	BOOL	bDis	=TRUE;
	BOOL	bHide	=FALSE;

	if(0==m_Tab.GetCurSel())
		bDis=FALSE;

	ChangeViewBtnsState(bDis,!bDis);

	m_Tab.GetTabView(m_Tab.GetCurSel(),(CWnd*&)pView);
	if(NULL!=pView)
	{
		pView->InitView();
		pView->ChangeCtrlsState();
	}
	
	*pResult = 0;
}

void CBPInstDlg::OnBPropsAddBpi() 
{
	CaplPropsView* pView	=NULL;

	if(0==m_Tab.GetCurSel())
		return;

	m_Tab.GetTabView(m_Tab.GetCurSel(),(CWnd*&)pView);
	pView->OnBAdd();
}

void CBPInstDlg::OnBPropsDelBpi() 
{
	CaplPropsView* pView	=NULL;

	if(0==m_Tab.GetCurSel())
		return;

	m_Tab.GetTabView(m_Tab.GetCurSel(),(CWnd*&)pView);
	pView->OnBDel();
}

void CBPInstDlg::OnBPropsPropsBpi() 
{
	CaplPropsView* pView	=NULL;

	if(0==m_Tab.GetCurSel())
		return;

	m_Tab.GetTabView(m_Tab.GetCurSel(),(CWnd*&)pView);
	pView->OnBProps();
}
