// CharacteristicDlg.cpp : implementation file
//

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

#include "apl_api.h"
#include "CharacteristicDlg.h"
#include "StrValueDlg.h"
#include "RealValueDlg.h"
#include "MoneraryValDlg.h"
#include "EnumValDlg.h"
#include "DataTimeDlg.h"
#include "TableValDlg.h"
#include "aplguiex.h"

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

/////////////////////////////////////////////////////////////////////////////
// CCharacteristicDlg dialog


CCharacteristicDlg::CCharacteristicDlg(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CCharacteristicDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCharacteristicDlg)
	m_str_val = _T("");
	m_auto_checkin = TRUE;
	//}}AFX_DATA_INIT
	m_aggr_val.SetUniqueName(_T("apl_psm_aggr_val"));
	m_item=0;
	m_value=0;
	m_old_value=0;
	m_unit=0;
	m_new_type=0;
	m_data=0;
	m_base_val=0;
	m_changed_aggr=false;
	m_api=0;
	m_ReadOnly=false;
	m_cur_ref_val=0;
	m_no_del_val_if_selchange=false;
	m_charactteristic=0;
	m_creation_mode=false;
	m_locked_type=false;

//	#ifdef _DEBUG
//		m_auto_checkin = FALSE;
//	#endif

}


void CCharacteristicDlg::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCharacteristicDlg)
	DDX_Check(pDX, IDC_AUTO_CHECK_IN, m_auto_checkin);
	DDX_Control(pDX, IDC_AUTO_CHECK_IN, m_autoCheckinCtrl);
	DDX_Control(pDX, IDC_BOTTOM, m_bottom_btn);
	DDX_Control(pDX, IDC_CHARACT_ICO, m_charact_ico);
	DDX_Control(pDX, IDC_CHARACTERYSTIC, m_charact);
	DDX_Control(pDX, IDC_CHECK_IN, m_check_in_ctrl);
	DDX_Control(pDX, IDC_CHECK_OUT, m_check_out_ctrl);
	DDX_Control(pDX, IDC_DATE, m_date_ctrl);
	DDX_Control(pDX, IDC_ENUM_VALUE, m_enum_val_ctrl);
	DDX_Control(pDX, IDC_MAX_DEV_1, m_max_dev);
	DDX_Control(pDX, IDC_MEASURE_COUNT, m_measure_count);
	DDX_Control(pDX, IDC_MEASURE_UNIT, m_measure_unit_ctrl);
	DDX_Control(pDX, IDC_MIN_DEV_1, m_min_dev);
	DDX_Control(pDX, IDC_SAVE_TO_FILE, m_save_to_file);
	DDX_Control(pDX, IDC_SCOPE, m_scope);
	DDX_Control(pDX, IDC_SEL_CHARACT, m_sec_charact_btn);
	DDX_Control(pDX, IDC_SELECT_INSTANCE, m_SelInstBtn);
	DDX_Control(pDX, IDC_ST_CHARACT_NAME, m_st_charact_name);
	DDX_Control(pDX, IDC_STATIC_MAX, m_stat_max);
	DDX_Control(pDX, IDC_STATIC_MIN, m_stat_min);
	DDX_Control(pDX, IDC_STATIC_VALUE_1, m_stat_value);
	DDX_Control(pDX, IDC_STR_VAL_1, m_str_val_ctrl);
	DDX_Control(pDX, IDC_TIME, m_time_ctrl);
	DDX_Control(pDX, IDC_TOP, m_top_btn);
	DDX_Control(pDX, IDC_TYPE, m_type);
	DDX_Control(pDX, IDC_UNDO_CHECK_OUT, m_undo_check_out_ctrl);
	DDX_Control(pDX, IDC_VALUE, m_value_ctrl);
	DDX_Control(pDX, IDCANCEL, m_cancel_btn);
	DDX_Control(pDX, IDOK, m_ok_btn);
	DDX_Control(pDX, IDC_TAB1, m_Tab);
	DDX_Control(pDX, IDC_B_PROPS_PROPS_CV, m_bPropsProps);
	DDX_Control(pDX, IDC_B_PROPS_DEL_CV, m_bPropsDel);
	DDX_Control(pDX, IDC_B_PROPS_ADD_CV, m_bPropsAdd);
	DDX_Text(pDX, IDC_STR_VAL_1, m_str_val);
	//}}AFX_DATA_MAP
	//DDX_Control(pDX, IDC_AGGR_VAL, m_aggr_val);
}


BEGIN_MESSAGE_MAP(CCharacteristicDlg, CResizableDialog)
	//{{AFX_MSG_MAP(CCharacteristicDlg)
	ON_BN_CLICKED(IDC_ST_CHARACT_NAME, OnStCharactName)
	ON_WM_CONTEXTMENU()
	ON_NOTIFY(NM_DBLCLK, IDC_AGGR_VAL, OnDblclkAggrVal)
	ON_BN_CLICKED(IDC_TOP, OnTop)
	ON_BN_CLICKED(IDC_BOTTOM, OnBottom)
	ON_BN_CLICKED(IDC_SAVE_TO_FILE, OnSaveToFile)
	ON_BN_CLICKED(IDC_SELECT_INSTANCE, OnSelectInstance)
	ON_BN_CLICKED(IDC_SEL_CHARACT, OnSelCharact)
	ON_BN_CLICKED(IDC_CHECK_OUT, OnCheckOut)
	ON_BN_CLICKED(IDC_CHECK_IN, OnCheckIn)
	ON_BN_CLICKED(IDC_UNDO_CHECK_OUT, OnUndoCheckOut)
	ON_BN_CLICKED(IDC_B_PROPS_ADD_CV, OnBPropsAdd)
	ON_BN_CLICKED(IDC_B_PROPS_DEL_CV, OnBPropsDel)
	ON_BN_CLICKED(IDC_B_PROPS_PROPS_CV, OnBPropsProps)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnSelchangeTab1)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CCharacteristicDlg::SetAnchors(void)
{
	AddAnchor(IDC_TAB1,TOP_LEFT,BOTTOM_RIGHT);

	AddAnchor(IDC_B_PROPS_ADD_CV,TOP_RIGHT);
	AddAnchor(IDC_B_PROPS_DEL_CV,TOP_RIGHT);
	AddAnchor(IDC_B_PROPS_PROPS_CV,TOP_RIGHT);

	AddAnchor(IDC_CHARACT_ICO,TOP_LEFT);
	AddAnchor(IDC_ST_CHARACT_NAME,TOP_CENTER);

	AddAnchor(IDC_CHECK_OUT,TOP_RIGHT);
	AddAnchor(IDC_CHECK_IN,TOP_RIGHT);
	AddAnchor(IDC_UNDO_CHECK_OUT,TOP_RIGHT);


	AddAnchor(IDC_T_CHAR_NAME,TOP_LEFT);
	AddAnchor(IDC_CHARACTERYSTIC,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_SEL_CHARACT,TOP_RIGHT);

	AddAnchor(IDC_T_UNIT,TOP_LEFT);
	AddAnchor(IDC_MEASURE_UNIT,TOP_LEFT, TOP_RIGHT);

	AddAnchor(IDC_T_TYPE,TOP_LEFT);
	AddAnchor(IDC_TYPE,TOP_LEFT, TOP_RIGHT);

	AddAnchor(IDC_T_AREA,TOP_LEFT);
	AddAnchor(IDC_SCOPE,TOP_LEFT, TOP_RIGHT);
	
	AddAnchor(IDC_T_MNUM,TOP_LEFT);
	AddAnchor(IDC_MEASURE_COUNT,TOP_LEFT, TOP_RIGHT);


	AddAnchor(IDC_STATIC_VALUE_1,TOP_LEFT);
	AddAnchor(IDC_TOP, MIDDLE_LEFT);
	AddAnchor(IDC_BOTTOM, MIDDLE_LEFT);
	AddAnchor(IDC_VALUE, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_STATIC_MAX,TOP_RIGHT);
	AddAnchor(IDC_STATIC_MIN,TOP_RIGHT);
	AddAnchor(IDC_MAX_DEV_1,TOP_RIGHT);
	AddAnchor(IDC_MIN_DEV_1,TOP_RIGHT);

	AddAnchor(IDC_STR_VAL_1, TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_ENUM_VALUE, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_AGGR_VAL, TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_SELECT_INSTANCE,TOP_RIGHT);

	AddAnchor(IDC_AUTO_CHECK_IN, BOTTOM_LEFT, BOTTOM_RIGHT);

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

	return TRUE;
}

BOOL CCharacteristicDlg::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_value;
	CaplInstance*		actver		=NULL;

	if(m_value) m_api->m_data.GetAttr(m_value, m_api->m_charact_mgr.a_apl_charact_val_act_ver, actver);
	if(!actver)actver=cit;

	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_CV);
	caExcludes.Add(IDC_B_PROPS_DEL_CV);
	caExcludes.Add(IDC_B_PROPS_PROPS_CV);

	caExcludes.Add(IDC_CHARACT_ICO);
	caExcludes.Add(IDC_ST_CHARACT_NAME);
	m_Tab.AddExcludeIDs(caExcludes);

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

	if(NULL!=cit)
	{
		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=actver;
		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==cit)
		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==cit)
	{
		m_Tab.AddTab(1,pAccView);

		CString	csAccPatName;
		
		CaplEntity* et=NULL;

		et=m_api->m_charact_mgr.e_apl_charact_value;
		if(true==m_api->m_charact_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 CCharacteristicDlg::ChangeViewBtnsState(BOOL bDis,BOOL bHide)
{
	CWnd*	pwnd	=NULL;

	int		iIDs[]={IDC_B_PROPS_ADD_CV,IDC_B_PROPS_DEL_CV,IDC_B_PROPS_PROPS_CV};
	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 CCharacteristicDlg::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);
			}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CCharacteristicDlg message handlers
void CCharacteristicDlg::DisableChangeCharact()
{
	RECT rect,rect1;
	m_sec_charact_btn.GetWindowRect(&rect1);
	m_charact.GetWindowRect(&rect);
	rect.right=rect1.right;
	ScreenToClient(&rect);
	m_charact.MoveWindow(&rect);

	m_measure_unit_ctrl.GetWindowRect(&rect);
	rect.right=rect1.right;
	ScreenToClient(&rect);
	m_measure_unit_ctrl.MoveWindow(&rect);

	m_sec_charact_btn.EnableWindow(FALSE);
	m_sec_charact_btn.ShowWindow(SW_HIDE);
	m_charact.SetReadOnly(TRUE);
}

//*******************************************************************
BOOL CCharacteristicDlg::OnInitDialog() 
{
	CResizableDialog::OnInitDialog();
	if(m_api==NULL)
	{
		EndDialog(0);
		return FALSE;
	}

	// предотвращаем потерю модальности после диалога с бочками из aplSocketTransport
	CORRECT_LOOSE_MODAL(&(m_api->m_data));

	ModifyStyleEx(0, WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT);   
	ModifyStyle(0, WS_MAXIMIZEBOX);   

	RECT rect={5,5,10,10},rect1;
	m_aggr_val.Create(WS_VISIBLE|WS_CHILD|WS_BORDER|LVS_SHOWSELALWAYS,rect,this,IDC_AGGR_VAL);
	m_aggr_val.SetWindowPos(&CWnd::wndTop,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);

	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_value_ctrl.GetWindowRect(&rect);
	ScreenToClient(&rect);
	m_date_ctrl.MoveWindow(&rect);

	m_max_dev.GetWindowRect(&rect1);
	ScreenToClient(&rect1);
	rect1.top=rect.top;
	rect1.bottom=rect.bottom;
	m_time_ctrl.MoveWindow(&rect1);

	m_measure_count.GetWindowRect(&rect1);
	ScreenToClient(&rect1);
	rect.right=rect1.right;
	m_enum_val_ctrl.MoveWindow(&rect);
	rect.top-=10;
	rect.bottom+=15;
	m_str_val_ctrl.MoveWindow(&rect);
	m_aggr_val.MoveWindow(&rect);

	m_value_ctrl.GetWindowRect(&rect);
	ScreenToClient(&rect);
	rect.left=rect.right+10;
	rect.right=rect.left+20;
	m_SelInstBtn.MoveWindow(&rect);

	CTime time(2000,1,1,0,0,0);
	m_time_ctrl.SetTime(&time);

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

	if(aplGetBitPerPixel(this)>8)
		m_name_bmp.LoadMappedBitmap(IDB_CHARACT_NAME,0,&cm,1);
	else
		m_name_bmp.LoadMappedBitmap(IDB_CHARACT_NAME_16,0,&cm,1);

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

	m_ico_bmp.LoadMappedBitmap(IDB_CHARACTERYSTIC_ICO,0,&cm,1);
	hBmpOld=m_charact_ico.SetBitmap(HBITMAP(m_ico_bmp));	
	::DeleteObject(hBmpOld);

	

	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_save_to_file.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	//m_save_to_file.SetFlat(FALSE);

	m_top_btn.SetIcon(GetAplTableIco(APL_TABLE_TOP));
	m_bottom_btn.SetIcon(GetAplTableIco(APL_TABLE_BOTTOM));

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

	m_check_out_ctrl.SetFlat(false);
	m_check_in_ctrl.SetFlat(false);
	m_undo_check_out_ctrl.SetFlat(false);

	int color_mode=0;
	if(aplGetBitPerPixel(this)>8) color_mode=1;
	
	m_check_out_ctrl.SetIcon(GetAplCheckIco(APL_ICON_CHECKOUT,color_mode)); 
	m_check_in_ctrl.SetIcon(GetAplCheckIco(APL_ICON_CHECKIN,color_mode)); 
	m_undo_check_out_ctrl.SetIcon(GetAplCheckIco(APL_ICON_UNDOCHECKOUT,color_mode)); 

	RECT r1;
	m_undo_check_out_ctrl.GetWindowRect(&r1);
	ScreenToClient(&r1);
	m_check_out_ctrl.MoveWindow(&r1);

	m_check_out_ctrl.SetTooltipText(APL_T("Взять на редактирование"));
	m_check_in_ctrl.SetTooltipText(APL_T("Завершить редактирование"));
	m_undo_check_out_ctrl.SetTooltipText(APL_T("Отменить редактирование")); 

	m_data=&(m_api->m_data);
	m_charact_mgr=&(m_api->m_charact_mgr);

	HideValue();
	if(m_data!=0)
	{
		aplExtent ext0;
		CString buf;
		int i;
		if(!m_value) 
			m_creation_mode=true;
		if(m_charactteristic!=0)
		{
			SetCharacterystic(m_charactteristic);
			DisableChangeCharact();
		}

		int k=m_type.AddString(_T(""));
		m_type.SetItemData(k,0);
		m_data->GetEntityExtent(m_charact_mgr->e_apl_charact_type,ext0);
		for(i=0;i<ext0.Size;i++)
		{
			m_data->GetAttr(ext0[i],m_charact_mgr->a_apl_charact_type_name,buf);
			int k=m_type.AddString(buf);
			m_type.SetItemData(k,(UINT)ext0[i]);
		}
		if(m_new_type && m_base_val==0){
			m_data->GetAttrBN(m_new_type,S::name,buf);
			m_type.SelectString(0,buf);	
			m_locked_type=true;
			
		}
		if(m_locked_type)m_type.EnableWindow(FALSE);	

		if(!m_charact_mgr->m_bUseVersions || !m_value) 
		{
			m_check_out_ctrl.ShowWindow(SW_HIDE);
			m_check_in_ctrl.ShowWindow(SW_HIDE);
			m_undo_check_out_ctrl.ShowWindow(SW_HIDE);
			
			if(m_data->IsKindOf(m_item,m_charact_mgr->m_api->m_bp_mgr.e_bp) || 
				m_data->IsKindOf(m_item,m_charact_mgr->m_api->m_bp_mgr.e_apl_bp_ver))			
				m_autoCheckinCtrl.ShowWindow(SW_HIDE);
			else 
			{
				m_autoCheckinCtrl.ShowWindow(SW_SHOW);
			}

		}
		if(m_base_val!=0)
		{
			SetFromInst(m_base_val);
			DisableChangeCharact();
		}
		else if(m_mode==_T("Edit"))
		{
			DisableChangeCharact();
            m_no_del_val_if_selchange=true;

			SetFromInst(m_value);
			
			m_no_del_val_if_selchange=false;
		}
		
		if(m_item)
		{
			if(m_data->IsKindOf(m_item,m_charact_mgr->m_api->m_bp_mgr.e_bp) || 
				m_data->IsKindOf(m_item,m_charact_mgr->m_api->m_bp_mgr.e_apl_bp_ver))	
				m_auto_checkin= FALSE;
		}
		else
		{
			// Вроде как свойства БП (обр-ка дырявой БД ?)
			m_auto_checkin= FALSE;
			m_check_out_ctrl.ShowWindow(SW_HIDE);
			m_check_in_ctrl.ShowWindow(SW_HIDE);
			m_undo_check_out_ctrl.ShowWindow(SW_HIDE);
			m_autoCheckinCtrl.ShowWindow(SW_HIDE);
		}
	}
	
	if(m_value)
	{
		CaplInstance *inst = NULL;
		CString sSystem;
		if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value_ver))
			m_api->m_data.GetAttr(m_value, m_api->m_charact_mgr.a_apl_charact_val_ver_char_value, inst);
		else if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value))
			inst = m_value;
		if(inst)
		{
			m_api->m_data.GetAttr(inst, m_api->m_charact_mgr.a_apl_charact_val_system, sSystem);
			if(!sSystem.IsEmpty())
			{
				m_auto_checkin = FALSE;
				m_autoCheckinCtrl.SetCheck(0);
				m_autoCheckinCtrl.ShowWindow(SW_HIDE);
			}
		}
	}

	//BringWindowToTop();
	SetForegroundWindow();

	m_Tab.InitStates();
	SetAnchors();

	UpdateData(FALSE);

	return TRUE;
}
//*******************************************************************
void CCharacteristicDlg::HideValue()
{
	m_stat_value.ShowWindow(SW_HIDE);
	m_value_ctrl.ShowWindow(SW_HIDE);
	m_min_dev.ShowWindow(SW_HIDE);
	m_max_dev.ShowWindow(SW_HIDE);
	m_stat_max.ShowWindow(SW_HIDE);
	m_stat_min.ShowWindow(SW_HIDE);
	m_enum_val_ctrl.ShowWindow(SW_HIDE);
	m_str_val_ctrl.ShowWindow(SW_HIDE);
	m_date_ctrl.ShowWindow(SW_HIDE);
	m_time_ctrl.ShowWindow(SW_HIDE);
	m_aggr_val.ShowWindow(SW_HIDE);
	m_top_btn.ShowWindow(SW_HIDE);
	m_save_to_file.ShowWindow(SW_HIDE);
	m_bottom_btn.ShowWindow(SW_HIDE);
	m_SelInstBtn.ShowWindow(SW_HIDE);
	m_value_ctrl.ShowWindow(FALSE);
}
//**********************************************************
void CCharacteristicDlg::OnTop() 
{
	if(m_ReadOnly) return;
	CaplAggr aggr0;
	m_data->GetAttrBN(m_value,_T("values"),aggr0);

	if(FALSE==m_aggr_val.IsWindowVisible()) return ;
	int k=m_aggr_val.GetNextItem(0,LVNI_SELECTED);
	
	int k1=k-1;
	if(k<1) return;
	if(k>aggr0.GetSize()-1) return;
	k=m_aggr_val.GetItemData(k);
	if(k<0) return;
	
	k1=m_aggr_val.GetItemData(k1);
	if(k1<0) 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_data->PutAttrBN(m_value,_T("values"),aggr0);
	if(m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val) || m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val_ver)) PrintAggrInList(m_value);
	else if(m_data->IsKindOf(m_value,m_charact_mgr->e_table_val) || m_data->IsKindOf(m_value,m_charact_mgr->e_table_val_ver)) PrintTableInList(m_value);
	m_aggr_val.SetItemState(k-1,LVIS_SELECTED,-1);
}
//*******************************************************************
void CCharacteristicDlg::OnBottom() 
{
	if(m_ReadOnly) return;
	CaplAggr aggr0;
	m_data->GetAttrBN(m_value,_T("values"),aggr0);

	if(FALSE==m_aggr_val.IsWindowVisible()) return ;
	
	int k=m_aggr_val.GetNextItem(-1,LVNI_SELECTED);
	int k1=k+1;
	
	if(k<0)  return;
	if(k>aggr0.GetSize()-2) return;
	
	k=m_aggr_val.GetItemData(k);
	if(k<0)  return;

	k1=m_aggr_val.GetItemData(k1);
	if(k1<0)  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_data->PutAttrBN(m_value,_T("values"),aggr0);
	if(m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val) || m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val_ver)) PrintAggrInList(m_value);
	else if(m_data->IsKindOf(m_value,m_charact_mgr->e_table_val) || m_data->IsKindOf(m_value,m_charact_mgr->e_table_val_ver)) PrintTableInList(m_value);
	m_aggr_val.SetItemState(k+1,LVIS_SELECTED,-1);
}
//**********************************************************
void CCharacteristicDlg::OnOK() 
{
	if(!UpdateData()) return;

	if(!m_value || m_value->GetId()==0 || !m_auto_checkin)//иначе не сохранит вообще
	{
		if(!SaveChanges(true))
			return;		
	}
	
	CaplInstance* locker= NULL;
	if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value))
		m_api->m_data.GetAttr(m_value, m_api->m_charact_mgr.a_apl_charact_val_lock_ver, locker);
	else if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value_ver))
		locker= m_value;

	if(locker && m_auto_checkin)
	{
		bool ModeInteractive= m_api->m_ModeInteractive;
		m_api->m_ModeInteractive= false;
		if(!CheckIn())
		{
			m_api->m_ModeInteractive= ModeInteractive;
			return;
		}
		m_api->m_ModeInteractive= ModeInteractive;
	}

	GetAccessString();

	CResizableDialog::OnOK();
}
//*******************************************************************
void CCharacteristicDlg::SetFromInst(CaplInstance *val)
{
	if(val==0) return;
	CString buf, buf1;
	CaplInstance *characteristic,*inst,*lock=0;
	int i;
	
	if(val)
	{
		if(m_item==0)
		{
			if(m_data->IsKindOf(val,m_charact_mgr->e_apl_charact_value))
			{
				m_api->m_data.GetAttrBN(val, _T("item"), m_item);
			}
			else
			{
				CaplInstance *char_value;
				m_api->m_data.GetAttrBN(val, _T("characteristic_value"), char_value);
				if(char_value)m_api->m_data.GetAttrBN(char_value, _T("item"), m_item);
			}
		}
		if(m_item)
		{
			if(m_data->IsKindOf(m_item,m_charact_mgr->m_api->m_bp_mgr.e_bp) || 
				m_data->IsKindOf(m_item,m_charact_mgr->m_api->m_bp_mgr.e_apl_bp_ver))
					m_autoCheckinCtrl.ShowWindow(SW_HIDE);
		}
	}

	if(m_data->IsKindOf(val,m_charact_mgr->e_apl_charact_value)) 
	{
		SetWindowText( APL_T("Характеристика"));
		if(m_charact_mgr->m_bUseVersions) 
		{
			m_check_in_ctrl.ShowWindow(SW_HIDE);
			m_undo_check_out_ctrl.ShowWindow(SW_HIDE);
			m_autoCheckinCtrl.ShowWindow(SW_HIDE);

			if(val!=m_base_val)
			{
				m_ReadOnly=true;
				if(val->GetAccessmode()<aplRO)
				{
					m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_lock_ver,lock);
					if(lock) m_check_out_ctrl.ShowWindow(SW_HIDE);
				}
				else
					m_check_out_ctrl.ShowWindow(SW_HIDE);
			}
		}
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_scope,buf);
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_type,inst);
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_charact,characteristic);
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_num,i);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_apl_charact_value_ver)) 
	{
		SetWindowText( APL_T("Версия характеристики"));
		m_check_out_ctrl.ShowWindow(SW_HIDE);

		CaplInstance *char_ver_char_val=0;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_char_value,char_ver_char_val);
		lock=m_charact_mgr->CheckMyLock(char_ver_char_val,false);
		if(!lock || lock!=val) 
		{
			m_check_in_ctrl.ShowWindow(SW_HIDE);
			m_undo_check_out_ctrl.ShowWindow(SW_HIDE);
			m_autoCheckinCtrl.ShowWindow(SW_HIDE);

			m_ReadOnly=true;
		}
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_scope,buf);
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_type,inst);
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_charact,characteristic);
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_num,i);
	}
	m_scope.SetWindowText(buf);

	SetReadOnlyItems();
	if(!m_ReadOnly) CreateTempVal();	
	
	if(inst){
		m_data->GetAttrBN(inst,S::name,buf);
		m_type.SelectString(0,buf);	
	}

	if(characteristic!=0)
	{
		m_charactteristic=characteristic;
		m_data->GetAttrBN(m_charactteristic,S::name,buf);
		m_data->GetAttrBN(m_charactteristic,S::id,buf1);
		m_charact.SetWindowText(buf1+ _T(" : ")+buf);

		SetCharacterystic(m_charactteristic);
	}	

	buf.Format(_T("%i"),i);
	m_measure_count.SetWindowText(buf);

	// установка значений
	if(m_data->IsKindOf(val,m_charact_mgr->e_meas_value))
	{
		double rval;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_meas_val,rval);		
		buf.Format(_T("%f"), rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_value_ctrl.SetWindowText(buf);

		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_meas_min,rval);
		buf.Format(_T("%f"), rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_min_dev.SetWindowText(buf);

		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_meas_max,rval);
		buf.Format(_T("%f"), rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_max_dev.SetWindowText(buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_descr_value))
	{
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_descr_val,m_str_val);
		m_str_val_ctrl.SetWindowText(m_str_val);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_monet_value))
	{
		double rval;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_monet_val,rval);
		buf.Format(_T("%f"), rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_value_ctrl.SetWindowText(buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_time_val))
	{
		COleDateTime odt;
		odt=COleDateTime::GetCurrentTime();

		CString s_date;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_time_val_s,s_date);
		aplString2Date(s_date,odt);
		m_date_ctrl.SetTime(odt);
		m_time_ctrl.SetTime(odt);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_enum_value))
	{
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_enum_val,buf);
		m_enum_val_ctrl.SelectString(0,buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_aggr_val))
	{
		if(!m_ReadOnly)
		{
			if(m_value==0)m_value=m_charact_mgr->CreateCopyCharacteristicVal(val);
			else
			{
				if(m_value!=val)
				{
					m_charact_mgr->DeleteCharacteristic(m_value);
					m_value=m_charact_mgr->CreateCopyCharacteristicVal(val);
				}
			}
		}
		PrintAggrInList(val);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_table_val))
	{
		if(!m_ReadOnly)
		{
			if(m_value==0)m_value=m_charact_mgr->CreateCopyCharacteristicVal(val);
			else
			{
				if(m_value!=val)
				{
					m_charact_mgr->DeleteCharacteristic(m_value);
					m_value=m_charact_mgr->CreateCopyCharacteristicVal(val);
				}
			}
		}
		PrintTableInList(m_value);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_apl_reference_value))
	{
		buf=_T("");
		m_data->GetAttr(val,m_charact_mgr->a_apl_reference_val,m_cur_ref_val);
		m_charact_mgr->PrintCharacteristicValue(val,m_unit,buf,true);
		//m_data->GetAttr(val,m_charact_mgr->a_apl_reference_val,m_cur_ref_val);
		//if(m_cur_ref_val!=0) m_charact_mgr->GetItemName(m_cur_ref_val,buf);
		m_value_ctrl.SetWindowText(buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_meas_value_ver))
	{
		double rval;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_val,rval);
		buf.Format(_T("%f"),rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_value_ctrl.SetWindowText(buf);

		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_min,rval);
		buf.Format(_T("%f"),rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_min_dev.SetWindowText(buf);

		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_max,rval);
		buf.Format(_T("%f"),rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_max_dev.SetWindowText(buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_descr_value_ver))
	{
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_descr_val,m_str_val);
		m_str_val_ctrl.SetWindowText(m_str_val);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_monet_value_ver))
	{
		double rval;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_monet_val,rval);
		buf.Format(_T("%f"),rval);
		buf.TrimRight(_T('0'));
		buf.TrimRight(_T('.'));	
		m_value_ctrl.SetWindowText(buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_time_val_ver))
	{
		COleDateTime odt;
		odt=COleDateTime::GetCurrentTime();

		CString s_date;
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_time_val_s,s_date);
		aplString2Date(s_date,odt);
		m_date_ctrl.SetTime(odt);
		m_time_ctrl.SetTime(odt);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_enum_value_ver))
	{
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_enum_val,buf);
		m_enum_val_ctrl.SelectString(-1,buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_apl_reference_value_ver))
	{
		buf=_T("");
		m_data->GetAttr(val,m_charact_mgr->a_apl_reference_val_ver_val,m_cur_ref_val);
		m_charact_mgr->PrintCharacteristicValue(val,m_unit,buf,true);
		m_value_ctrl.SetWindowText(buf);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_aggr_val_ver))
	{
		if(!m_ReadOnly)
		{
			if(m_value==0)m_value=m_charact_mgr->CreateCharValVersion(val,_T("-1"),false);
			else
			{
				if(m_value!=val)
				{
					m_charact_mgr->DeleteCharacteristic(m_value);
					m_value=m_charact_mgr->CreateCharValVersion(val,_T("-1"),false);
				}
			}
		}
		PrintAggrInList(val);
	}
	else if(m_data->IsKindOf(val,m_charact_mgr->e_table_val_ver))
	{
		if(m_value==0)m_value=m_charact_mgr->CreateCharValVersion(val,_T("-1"),false);
		else
		{
			if(m_value!=val)
			{
				m_charact_mgr->DeleteCharacteristic(m_value);
				m_value=m_charact_mgr->CreateCharValVersion(val,_T("-1"),false);
			}
		}
		PrintTableInList(m_value);
	}
}
//*******************************************************************
void CCharacteristicDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
//	long wait_dlg=aplStartWaitDlg(APL_T("Идет выполнение ..."));

	UpdateData();

	if(m_old_value!=0)
	{
		CaplInstance *temp=m_value;
		m_value=m_old_value;
		m_old_value=temp;
	}
	else
	{
		// отмена создания
		if(m_value!=0 && !m_ReadOnly)
		{
			if(m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val))
			{
				m_charact_mgr->DeleteCharacteristic(m_value);
				m_value=0;
			}
			else if(m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val_ver))
			{
				m_charact_mgr->DeleteCharacteristic(m_value);
				m_value=0;
			}
			else if(m_data->IsKindOf(m_value,m_charact_mgr->e_table_val))
			{
				m_charact_mgr->DeleteCharacteristic(m_value);
				m_value=0;
			}
		}
	}
	if(m_old_value) m_charact_mgr->DeleteCharacteristic(m_old_value);

	CaplInstance* locker= NULL, *val= NULL;
	if(m_value)
	{
		if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value))
			m_api->m_data.GetAttr(m_value, m_api->m_charact_mgr.a_apl_charact_val_lock_ver, locker);
		else if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value_ver))
		{
			m_api->m_data.GetAttr(m_value, m_api->m_charact_mgr.a_apl_charact_val_ver_char_value, val);
			if(val)m_api->m_data.GetAttr(val, m_api->m_charact_mgr.a_apl_charact_val_lock_ver, locker);
		}
	}

	if(locker && m_auto_checkin)
	{
		bool ModeInteractive= m_api->m_ModeInteractive;
		m_api->m_ModeInteractive= false;
		OnUndoCheckOut();
		m_api->m_ModeInteractive= ModeInteractive;
	}

//	aplEndWaitDlg(wait_dlg);
	CResizableDialog::OnCancel();
}
//*******************************************************************
void CCharacteristicDlg::OnStCharactName() 
{
	// 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( APL_T("Режим %s;\n"),m_mode);
		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_value!=0){buf.Format(_T("m_value->id %i;\n"),m_value->GetId());text+=buf;}else{buf.Format(_T("m_value==0;\n"));}
		if(m_unit!=0){buf.Format(_T("m_unit->id %i;\n"),m_unit->GetId());text+=buf;}else{buf.Format(_T("m_unit==0;\n"));}
		if(m_base_val!=0){buf.Format(_T("m_base_val->id %i;\n"),m_base_val->GetId());text+=buf;}else{buf.Format(_T("m_base_val==0;\n"));}
		if(m_old_value!=0){buf.Format(_T("m_old_value->id %i;\n"),m_old_value->GetId());text+=buf;}else{buf.Format(_T("m_old_value==0;\n"));}
		AfxMessageBox(text);
	}	
}
//*******************************************************************
void CCharacteristicDlg::PrintAggrInList(CaplInstance *val)
{
	m_aggr_val.DeleteAllItems();
	CArray <int,int> widths;
	int i,j,w;
	while(1)
	{
		i=m_aggr_val.GetColumnWidth(0);
		if(!m_aggr_val.DeleteColumn(0)) break;
		if(i>0) widths.Add(i);
	}

	m_aggr_val.InsertColumn(0, APL_T("№"),LVCFMT_LEFT,25);
	m_aggr_val.CListCtrl::SetColumnWidth(0,25);
	w=100;
	if(widths.GetSize()>1) w=widths[1];
	m_aggr_val.InsertColumn(1,_T("0"),LVCFMT_LEFT,w);
	//m_aggr_val.CListCtrl::SetColumnWidth(1,w);
	int colums=1;

	if(val==0) return;
	if(!m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val)) 
		if(!m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val_ver)) 
			return;
	CString buf;
	int row=0;
	CaplInstance *val0,*val1;
	CaplAggr aggr0;
	m_data->GetAttrBN(m_value,_T("values"),aggr0);
	for(i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,val0);
		if(val0==0) continue;
		row++;
		row=m_aggr_val.InsertItem(row,_T(""));
		buf.Format(_T("%i"),row);
		m_aggr_val.SetItemText(row,0,buf);
		m_aggr_val.SetItemData(row,row);

		if(m_data->IsKindOf(val0,m_charact_mgr->e_aggr_val) || m_data->IsKindOf(val0,m_charact_mgr->e_aggr_val_ver))
		{
			CaplAggr aggr1;
			if(m_data->IsKindOf(val0,m_charact_mgr->e_aggr_val))
				m_data->GetAttr(val0,m_charact_mgr->a_apl_charact_val_aggr_val,aggr1);
			else
				m_data->GetAttr(val0,m_charact_mgr->a_apl_charact_val_ver_aggr_val,aggr1);
			for(j=0;j<aggr1.GetSize();j++)
			{
				aggr1.GetByIndex(j,val1);
				while (colums<j+1)
				{
					buf.Format(_T("%i"),colums);
					colums++;
					w=100;
					if(widths.GetSize()>colums) w=widths[colums];
					m_aggr_val.InsertColumn(colums,buf,LVCFMT_LEFT,w);
				}
				if(val1==0) continue;
				m_charact_mgr->PrintCharacteristicValue(val1,0,buf);
				m_aggr_val.SetItemText(row,j+1,buf);
			}
		}
		else
		{
			m_charact_mgr->PrintCharacteristicValue(val0,0,buf,true);
			m_aggr_val.SetItemText(row,1,buf);
		}
	}
}
//*****************************************************************
bool CCharacteristicDlg::PointToVal(CPoint *point, int &i,int &j, CaplInstance **val, CaplInstance **unit,int &type)
{
	*val=0; *unit=0;
	type=-1;

	CaplInstance *unit1=0,*unit2=0;
	if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_aggr_unit))
	{
		m_data->GetAttrBN(m_unit,_T("element_type"),unit1);
		if(m_data->IsKindOf(unit1,m_charact_mgr->e_apl_aggr_unit))
		{
			m_data->GetAttrBN(unit1,_T("element_type"),unit2);
			*unit=unit2;
			type=2;
		} else {*unit=unit1; type=1;}
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_table_unit)) type=3;
	else type=-1;

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

		CPoint m_point_context_menu=*point;
		m_aggr_val.ScreenToClient(&m_point_context_menu);
	
		// Отсекание нажатия на header
		CHeaderCtrl*head= m_aggr_val.GetHeaderCtrl();
		head->GetWindowRect(&rect);
		if(rect.PtInRect(*point)) return false;

		LVHITTESTINFO lvhti;
		lvhti.pt = m_point_context_menu;
		m_aggr_val.SubItemHitTest(&lvhti);
		
		i=lvhti.iItem;
		if(i<0) return true;
		j=lvhti.iSubItem-1;
		if(j<0) return true;;
	}
	if(type<0) return false;
	i=m_aggr_val.GetItemData(i);
	if(i<0) return true;

	CaplAggr aggr,aggr1; CaplInstance* val_el;

	m_data->GetAttrBN(m_value,_T("values"),aggr);
	aggr.GetByIndex(i,val_el);
	if(type==2) // массив
	{
		m_data->GetAttrBN(val_el,_T("values"),aggr1);
		aggr1.GetByIndex(j,val_el);					
	}
	else if(type==3) // таблица
	{
		m_data->GetAttrBN(val_el,_T("items"),aggr1);
		val_el=0;
		CaplInstance *cell,*column,*i_column=(CaplInstance*)m_ColumnListMap.GetByOut(j);
		if((long)i_column==-1)i_column=0;
		if(i_column)
		{
			m_data->GetAttrBN(i_column,_T("unit"),*unit);
			int k=0;
			while(k<aggr1.GetSize())
			{
				aggr1.GetByIndex(k,cell);
				k++;
				if(!cell) continue;
				if(m_data->IsKindOf(cell,m_charact_mgr->e_table_cell))
					m_data->GetAttr(cell,m_charact_mgr->a_table_cell_column,column);
				else
					m_data->GetAttr(cell,m_charact_mgr->a_table_cell_ver_column,column);
							
				if(column!=i_column) continue;
				if(m_data->IsKindOf(cell,m_charact_mgr->e_table_cell))
					m_data->GetAttr(cell,m_charact_mgr->a_table_cell_val,val_el);
				else
					m_data->GetAttr(cell,m_charact_mgr->a_table_cell_ver_val,val_el);
								
				break;
			}
		}
	}
	*val=val_el;
	return true;
}
//*****************************************************************

void LoadContextMenuIcon();

void CCharacteristicDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	if(m_ReadOnly) return;
	int i=0,j=0,type=0;
	CaplInstance *val=0, *unit=0;
	if(false==PointToVal(&point,i,j,&val,&unit,type)) return;

	if(type<1) return;

	CaplAggr aggr,aggr1;
	CaplInstance *n_val=0,*val_el=0;
	if(m_value) m_data->GetAttrBN(m_value,_T("values"),aggr);
	if(i>=0)
	{
		if(type==2)
		{
			aggr.GetByIndex(i,val_el);
			m_data->GetAttrBN(val_el,_T("values"),aggr1);
		}
		if(type==3)
		{
			aggr.GetByIndex(i,val_el);
			m_data->GetAttrBN(val_el,_T("items"),aggr1);
		}
	}

    CaplMenu menu;CMenu* pPopup;
    VERIFY(menu.LoadMenu(IDR_CONTEXT_MENU));
	LoadContextMenuIcon();
	CaplMenu::Install(this);

	pPopup = menu.GetSubMenu(type);
	switch(type)
	{
	case 1:
		if(val==0)
		{
			 pPopup->RemoveMenu(ID_AGGR_VALUE, MF_BYCOMMAND );
			 pPopup->RemoveMenu(ID_AGGR_DUP_VAL, MF_BYCOMMAND );
			 pPopup->RemoveMenu(ID_AGGR_DEL_VAL, MF_BYCOMMAND);
		}
		//else pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND);
		break;
	case 2:
		if(val==0)
		{
			pPopup->RemoveMenu(ID_AGGR_VALUE, MF_BYCOMMAND );
			pPopup->RemoveMenu(ID_AGGR_DEL_VAL, MF_BYCOMMAND);
		}
		//else pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND); 
		if(i<0)
		{
			pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGROFAGGR_LEFT, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGROFAGGR_RIGHT, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGR_VALUE, MF_BYCOMMAND );
			pPopup->RemoveMenu(ID_AGGR_DEL_VAL, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGR_DEL_ROW, MF_BYCOMMAND);
		}
		else
		{
			if(j<0) 
			{
				//pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND);
				pPopup->RemoveMenu(ID_AGGROFAGGR_LEFT, MF_BYCOMMAND);
				pPopup->RemoveMenu(ID_AGGROFAGGR_RIGHT, MF_BYCOMMAND);
			}
			else
			{
				if(j>=aggr1.GetSize()-1)
					pPopup->RemoveMenu(ID_AGGROFAGGR_RIGHT, MF_BYCOMMAND);
				if(j==0) pPopup->RemoveMenu(ID_AGGROFAGGR_LEFT, MF_BYCOMMAND);
			}
		}
		break;
	case 3:
		if(val==0)
		{
			pPopup->RemoveMenu(ID_AGGR_VALUE, MF_BYCOMMAND );
			pPopup->RemoveMenu(ID_AGGR_DEL_VAL, MF_BYCOMMAND);
		}
		else pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND); 
		if(i<0)
		{
			pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGR_VALUE, MF_BYCOMMAND );
			pPopup->RemoveMenu(ID_AGGR_DEL_VAL, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGR_DUP_ROW, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_AGGR_DEL_ROW, MF_BYCOMMAND);
		}
		else
		{
			if(j<0) 
			{
				pPopup->RemoveMenu(ID_AGGR_CREATE_VAL, MF_BYCOMMAND);
				pPopup->RemoveMenu(ID_AGGR_VALUE, MF_BYCOMMAND );
				pPopup->RemoveMenu(ID_AGGR_DEL_VAL, MF_BYCOMMAND);
			}
		}
		break;
	}

	BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON |TPM_RETURNCMD,	point.x, point.y,this); // use main window for cmds

	switch (type)
	{
	case 1: // Линейный список
		{
			switch(res)
			{
			case ID_AGGR_VALUE:EditVal(i,j,&val,unit); break;
			case ID_AGGR_CREATE_VAL:
				if(EditVal(i,j,&n_val,unit))
				{
					if((i>=0)&&(i<aggr.GetSize()))
					{
						CaplValue v; v.Set(n_val);
						aggr.Insert(i,v);
					}
					else aggr.Add(n_val);
					m_data->PutAttrBN(m_value,_T("values"),aggr);
				}
				break;
			case ID_AGGR_DUP_VAL:
				{
					if((i>=0)&&(i<aggr.GetSize()))
					{
						CaplInstance *new_item=0;
						if(m_data->IsKindOf(val,m_charact_mgr->e_apl_charact_value))
						{
							new_item=m_charact_mgr->CreateCopyCharacteristicVal(val,0);
						}
						else
						{
							new_item=m_charact_mgr->CreateCharValVersion(val,_T("-1"),false,true);
						}
						
						CaplValue v; v.Set(new_item);
						aggr.Insert(i,v);
					}
					else aggr.Add(n_val);
					m_data->PutAttrBN(m_value,_T("values"),aggr);
				}
				break;
			case ID_AGGR_DEL_VAL:
				m_changed_aggr=true;
				m_charact_mgr->DeleteCharacteristic(val);
				aggr.Remove(i);
				m_data->PutAttrBN(m_value,_T("values"),aggr);
				break;
			}
			PrintAggrInList(m_value);
		}
		break;
	case 2:  // AGGR OF AGGR
		{
			switch(res)
			{
			case ID_AGGR_INS_ROW:
				{
					CaplInstance *new_item=m_data->CreateInstance(m_charact_mgr->e_aggr_val);
					if((i>=0)&&(i<aggr.GetSize()))
					{
						CaplValue v; v.Set(new_item);
						aggr.Insert(i,v);
					}
					else aggr.Add(new_item);
					m_changed_aggr=true;
					m_data->PutAttrBN(m_value,_T("values"),aggr);
				}
				break;
			case ID_AGGR_DEL_ROW:
				{
					if((i>=0)&&(i<aggr.GetSize()))
					{
						m_changed_aggr=true;
						CaplInstance *val_el;
						aggr.GetByIndex(i,val_el);
						m_charact_mgr->DeleteCharacteristic(val_el);
						aggr.Remove(i);
						m_data->PutAttrBN(m_value,_T("values"),aggr);
					}
				}
				break;
			case ID_AGGR_VALUE: EditVal(i,j,&val,unit); break;
			case ID_AGGR_CREATE_VAL:
				{
					if((i>=0)&&(i<aggr.GetSize()))
					{
						if(EditVal(i,j,&n_val,unit))
						{
							if((j>=0)&&(j<aggr1.GetSize()))
							{
								CaplValue v; v.Set(n_val);
								aggr1.Insert(j,v);
							}
							else aggr1.Add(n_val);
							m_data->PutAttrBN(val_el,_T("values"),aggr1);
						}
					}
				}
				break;
			case ID_AGGR_DEL_VAL:
				if((j>=0)&&(j<aggr1.GetSize()))
				{
					m_changed_aggr=true;
					m_charact_mgr->DeleteCharacteristic(val);
					aggr1.Remove(j);
					m_data->PutAttrBN(val_el,_T("values"),aggr1);
				}
				break;
			case ID_AGGROFAGGR_LEFT:
				if((i>=0)&&(i<aggr.GetSize()))
				{
					if((j>0)&&(j<aggr1.GetSize()))
					{
						m_changed_aggr=true;
						CaplValue *v=aggr1.aggr.Data[j-1];
						aggr1.aggr.Data[j-1]=aggr1.aggr.Data[j];
						aggr1.aggr.Data[j]=v;
						m_data->PutAttrBN(val_el,_T("values"),aggr1);
					}
				}
				break;
			case ID_AGGROFAGGR_RIGHT:
				if((i>=0)&&(i<aggr.GetSize()))
				{
					if((j>=0)&&(j<aggr1.GetSize()-1))
					{
						m_changed_aggr=true;
						CaplValue *v=aggr1.aggr.Data[j+1];
						aggr1.aggr.Data[j+1]=aggr1.aggr.Data[j];
						aggr1.aggr.Data[j]=v;
						m_data->PutAttrBN(val_el,_T("values"),aggr1);
					}
				}
				break;		
			}
			PrintAggrInList(m_value);
		}
		break;
	case 3: // таблица
		{
			switch(res)
			{
			case ID_AGGR_INS_ROW:
				{
					CaplInstance *new_item=0;
					if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value))
						new_item=m_data->CreateInstance(m_charact_mgr->e_table_row);
					else
						new_item=m_data->CreateInstance(m_charact_mgr->e_table_row_ver);
					CaplValue v; v.Set(new_item);
					if((i>=0)&&(i<aggr.GetSize()))aggr.Insert(i,v);
					else aggr.Add(v);
					m_changed_aggr=true;
					m_data->PutAttrBN(m_value,_T("values"),aggr);
				}
				break;
			case ID_AGGR_DEL_ROW:
				{
					if((i>=0)&&(i<aggr.GetSize()))
					{
						m_changed_aggr=true;
						CaplInstance *val_el;
						aggr.GetByIndex(i,val_el);
						m_charact_mgr->DeleteCharacteristic(val_el);
						aggr.Remove(i);
						m_data->PutAttrBN(m_value,_T("values"),aggr);
					}
				}
				break;
			case ID_AGGR_VALUE: EditVal(i,j,&val,unit); break;
			case ID_AGGR_CREATE_VAL:
				{
					if((i>=0)&&(i<aggr.GetSize()))
					{
						if(EditVal(i,j,&n_val,unit))
						{
							CaplInstance *i_column=(CaplInstance*)m_ColumnListMap.GetByOut(j);
							if((long)i_column==-1)i_column=0;
							
							CaplInstance *ceel=0;
							if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value))
							{
								ceel=m_data->CreateInstance(m_charact_mgr->e_table_cell);
								m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_val,n_val);
								m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_column,i_column);
							}
							else
							{
								ceel=m_data->CreateInstance(m_charact_mgr->e_table_cell_ver);
								m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_ver_val,n_val);
								m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_ver_column,i_column);
							}
							

							if((j>=0)&&(j<aggr1.GetSize()))
							{
								CaplValue v; v.Set(ceel);
								aggr1.Insert(j,v);
							}
							else aggr1.Add(ceel);
							m_data->PutAttrBN(val_el,_T("items"),aggr1);
						}
					}
				}
				break;
			case ID_AGGR_DEL_VAL:
				if((j>=0)&&(val!=0))
				{
					CaplInstance *i_column=(CaplInstance*)m_ColumnListMap.GetByOut(j);
					m_changed_aggr=true;
					m_charact_mgr->DeleteCharacteristic(val);
					if((long)i_column==-1)i_column=0;
					int k=0;
					while(k<aggr1.GetSize())
					{
						CaplInstance *cell,*column;
						aggr1.GetByIndex(k,cell);
						k++;
						if(!cell) continue;
						if(m_data->IsKindOf(cell,m_charact_mgr->e_table_cell))
							m_data->GetAttr(cell,m_charact_mgr->a_table_cell_column,column);
						else
							m_data->GetAttr(cell,m_charact_mgr->a_table_cell_ver_column,column);
						if(column!=i_column) continue;
						aggr1.Remove(k-1);	
						m_data->DeleteInstance(cell);
						m_data->PutAttrBN(val_el,_T("items"),aggr1);
						break;
					}
				}
				break;
			case ID_AGGR_DUP_ROW:
				{
					CaplInstance *new_item=0;
					if(m_data->IsKindOf(val_el,m_charact_mgr->e_apl_charact_value))
						new_item=m_charact_mgr->CreateCopyCharacteristicVal(val_el,0);	
					else
						new_item=m_charact_mgr->CreateCharValVersion(val_el,_T("-1"),false,true);
						
					if((i>=0)&&(i<aggr.GetSize()))
					{
						CaplValue v; v.Set(new_item);
						aggr.Insert(i,v);
					}
					else aggr.Add(new_item);
					m_changed_aggr=true;
					m_data->PutAttrBN(m_value,_T("values"),aggr);
				}
				break;
			}
			PrintTableInList(m_value);
		}
		break;
	}
}
//*****************************************************************
void CCharacteristicDlg::OnDblclkAggrVal(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) pNMHDR;
	*pResult = 0;

	if(lpnmitem==0) return;
	
	int i=lpnmitem->iItem,j=lpnmitem->iSubItem-1,type=0;

	if(i<0) return;
	if(j<0) return;
	CaplInstance *val=0, *unit=0;

	if(false==PointToVal(0,i,j,&val,&unit,type)) return;

	if(unit==0) return;

	if(type==1) {EditVal(i,j,&val,unit); return;}

	CaplAggr aggr,aggr1;
	CaplInstance *n_val=0,*val_el=0;
	m_data->GetAttrBN(m_value,_T("values"),aggr);
	if(type==2)
	{
		if((i>=0)&&(i<aggr.GetSize()))
		{
			aggr.GetByIndex(i,val_el);
			m_data->GetAttrBN(val_el,_T("values"),aggr1);
			bool ins=false;
			if(val==0)
			{
//				if(IDYES!=AfxMessageBox(APL_T("Создать значение ?"),MB_YESNO|MB_ICONQUESTION))
//					return;
				ins = true;
			}
			if(EditVal(i,j,&val,unit))
			{
				if(ins)
				{
					if((j>=0)&&(j<aggr1.GetSize()))
					{
						CaplValue v; v.Set(val);
						aggr1.Insert(j,v);
					}
					else aggr1.Add(val);
					m_data->PutAttrBN(val_el,_T("values"),aggr1);
					PrintAggrInList(m_value);
				}
			}
		}
		return;
	}
	if(type==3)
	{
		if((i>=0)&&(i<aggr.GetSize()))
		{
			aggr.GetByIndex(i,val_el);
			m_data->GetAttrBN(val_el,_T("items"),aggr1);
			bool ins=false;
			if(val==0)
			{
//				if(IDYES!=AfxMessageBox(APL_T("Создать значение ?"),MB_YESNO|MB_ICONQUESTION))
//					return;
				ins = true;
			}
			if(EditVal(i,j,&val,unit))
			{
				if(ins)
				{
					CaplInstance *i_column=(CaplInstance*)m_ColumnListMap.GetByOut(j);
					if((long)i_column==-1)i_column=0;

					CaplInstance *ceel=0;
					if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value))
					{
						ceel=m_data->CreateInstance(m_charact_mgr->e_table_cell);
						m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_val,val);
						m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_column,i_column);
					}
					else
					{
						ceel=m_data->CreateInstance(m_charact_mgr->e_table_cell_ver);
						CaplInstance *cell_ver_val=m_charact_mgr->CreateCharValVersion(val,_T("-1"),false,true);
						if(cell_ver_val) m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_ver_val,cell_ver_val);
						m_data->PutAttr(ceel,m_charact_mgr->a_table_cell_ver_column,i_column);
					}


					if((j>=0)&&(j<aggr1.GetSize()))
					{
						CaplValue v; v.Set(ceel);
						aggr1.Insert(j,v);
					}
					else aggr1.Add(ceel);
					m_data->PutAttrBN(val_el,_T("items"),aggr1);
					PrintTableInList(m_value);
				}
			}
		}
		return;
	}
}
//*****************************************************************
bool CCharacteristicDlg::EditVal(int i,int j,CaplInstance **value, CaplInstance *unit)
{
	if(m_data==0) return false;
	if(value==0) return false;
	if(unit==0) return false;
	CaplInstance *val= *value;
	CString buf;
	bool is_value_ver=false;
	if(val!=0) 
	{
		if(m_data->IsKindOf(val,m_charact_mgr->e_apl_charact_value_ver))
			is_value_ver=true;
	}
	else
	{
		if(m_value)
			if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value_ver))
				is_value_ver=true;
	}

	if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_descript_unit))
	{
		if(m_ReadOnly) return false;
		CStrValueDlg dlg;
		if(val!=0) 
		{
			if(is_value_ver)
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_descr_val,dlg.m_val);
			else
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_descr_val,dlg.m_val);
		}
		if(dlg.DoModal()!=IDOK) return false;
		if(val==0) 
		{
			if(is_value_ver)
				val=m_data->CreateInstance(m_charact_mgr->e_descr_value_ver);
			else
				val=m_data->CreateInstance(m_charact_mgr->e_descr_value);
		}
		if(is_value_ver)
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_descr_val,dlg.m_val);
		else
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_descr_val,dlg.m_val);
	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_monetary_unit))
	{
		if(m_ReadOnly) return false;
		CMoneraryValDlg dlg;
		m_charact_mgr->GetUnitName(unit,dlg.m_unit_name);
		if(val!=0)
		{
			if(is_value_ver)
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_monet_val,dlg.m_val);
			else
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_monet_val,dlg.m_val);
		}
		if(dlg.DoModal()!=IDOK) return false;
		if(val==0)
		{
			if(is_value_ver)
				val=m_data->CreateInstance(m_charact_mgr->e_monet_value_ver);
			else
				val=m_data->CreateInstance(m_charact_mgr->e_monet_value);
		}
		if(is_value_ver)
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_monet_val,dlg.m_val);
		else	
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_monet_val,dlg.m_val);

	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_reference_unit))
	{
		if(m_ReadOnly) return false;
		CaplInstance *old_inst=0;
		if(val!=0)
		{
			if(is_value_ver)
				m_data->GetAttr(val,m_charact_mgr->a_apl_reference_val_ver_val,old_inst);
			else
				m_data->GetAttr(val,m_charact_mgr->a_apl_reference_val,old_inst);
		}
		CaplInstance *new_inst=m_charact_mgr->BrowseReferenceVal(unit);
		if(new_inst!=0)
		{
			if(val==0)
			{
				if(is_value_ver)
					val=m_data->CreateInstance(m_charact_mgr->e_apl_reference_value_ver);
				else
					val=m_data->CreateInstance(m_charact_mgr->e_apl_reference_value);
			}
			if(old_inst!=new_inst)
			{
				if(is_value_ver)
				{
					m_data->PutAttr(val,m_charact_mgr->a_apl_reference_val_ver_val,new_inst);
					//m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_unit,unit);
				}
				else
				{
					m_data->PutAttr(val,m_charact_mgr->a_apl_reference_val,new_inst);
					m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_unit,unit);
				}
			}
		}
	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_enum_unit))
	{
		if(m_ReadOnly) return false;
		CEnumValDlg dlg;
		if(val!=0)
		{
			if(is_value_ver)
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_enum_val,dlg.m_val);
			else
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_enum_val,dlg.m_val);
		}
		CaplAggr aggr;
		m_data->GetAttrBN(unit,_T("values"),aggr);
		for(int i=0;i<aggr.GetSize();i++)
		{
			if(aggr.GetByIndex(i,buf)) dlg.m_values.Add(buf);
		}
		if(dlg.DoModal()!=IDOK) return false;
		if(val==0)
		{
			if(is_value_ver)
				val=m_data->CreateInstance(m_charact_mgr->e_enum_value_ver);
			else
				val=m_data->CreateInstance(m_charact_mgr->e_enum_value);
		}
		if(is_value_ver)
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_enum_val,dlg.m_val);
		else
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_enum_val,dlg.m_val);
	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_time_unit))
	{
		if(m_ReadOnly) return false;
		CDataTimeDlg dlg;
		CString dt_s,dt_s1;
		if(val!=0) 
		{
			if(is_value_ver)
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_time_val_s,dt_s);
			else
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_time_val_s,dt_s);
		}
		aplString2Date(dt_s,dlg.m_dt);
		if(dlg.DoModal()!=IDOK) return false;
		aplDate2String(dlg.m_dt,dt_s1);
		if(dt_s!=dt_s1)
		{
			if(val==0) 
			{
				if(is_value_ver)
					val=m_data->CreateInstance(m_charact_mgr->e_time_val_ver);
				else
					val=m_data->CreateInstance(m_charact_mgr->e_time_val);
			}
			if(is_value_ver)
				m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_time_val_s,dt_s1);
			else
				m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_time_val_s,dt_s1);
		}
	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_step_unit))
	{
		if(m_ReadOnly) return false;
		CRealValueDlg dlg;
		if(val!=0)
		{
			if(is_value_ver)
			{
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_val,dlg.m_val);
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_max,dlg.m_max_dev);
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_min,dlg.m_min_dev);
			}
			else
			{
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_meas_val,dlg.m_val);
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_meas_max,dlg.m_max_dev);
				m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_meas_min,dlg.m_min_dev);
			}
		}
		m_charact_mgr->GetUnitName(unit,dlg.m_unit_name);
		if(dlg.DoModal()!=IDOK) return false;
		if(val==0) 
		{
			if(is_value_ver)
				val=m_data->CreateInstance(m_charact_mgr->e_meas_value_ver);
			else
				val=m_data->CreateInstance(m_charact_mgr->e_meas_value);
		}
		if(is_value_ver)
		{
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_val,dlg.m_val);
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_max,dlg.m_max_dev);
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_ver_meas_min,dlg.m_min_dev);
		}
		else
		{
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_meas_val,dlg.m_val);
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_meas_max,dlg.m_max_dev);
			m_data->PutAttr(val,m_charact_mgr->a_apl_charact_val_meas_min,dlg.m_min_dev);
		}
	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_table_unit))
	{
		CTableValDlg dlg;

		dlg.m_data=m_data;
		dlg.m_charact_mgr=m_charact_mgr;
		dlg.m_value=val;
		dlg.m_unit=unit;
		dlg.m_ReadOnly=m_ReadOnly;
		dlg.m_parent_value=m_value;

		//m_charact_mgr->GetUnitName(unit,dlg.m_unit_name);

		if(dlg.DoModal()!=IDOK) return false;

		if(val!=dlg.m_value)
		{
			val=dlg.m_value;
		}
	}
	else if(m_data->IsKindOf(unit,m_charact_mgr->e_apl_aggr_unit))
	{
		CTableValDlg dlg;

		dlg.m_data=m_data;
		dlg.m_charact_mgr=m_charact_mgr;
		dlg.m_value=val;
		dlg.m_unit=unit;
		dlg.m_ReadOnly=m_ReadOnly;
		dlg.m_parent_value=m_value;

		//m_charact_mgr->GetUnitName(unit,dlg.m_unit_name);

		if(dlg.DoModal()!=IDOK) return false;

		if(val!=dlg.m_value)
		{
			val=dlg.m_value;
		}
	}
	else return false;

	if(*value!=0)
	{
		CString buf;
		if(val==0) buf=_T("");
		else m_charact_mgr->PrintCharacteristicValue(val,0,buf,true);
		m_aggr_val.SetItemText(i,j+1,buf);
	}
	else m_aggr_val.SetItemText(i,j+1,_T(""));
	m_changed_aggr=true;
	*value=val;
	return true;
}
//*****************************************************************
bool CCharacteristicDlg::CreateTableHeader(CaplInstance *unit)
{
	m_ColumnListMap.Clear();
	m_aggr_val.DeleteAllItems();
	CArray <int,int> widths;
	int i,w;
	while(1)
	{
		i=m_aggr_val.GetColumnWidth(0);
		if(!m_aggr_val.DeleteColumn(0)) break;
		if(i>0) widths.Add(i);
	}
	if(unit==0) return false;
	if(!m_data->IsKindOf(unit,m_charact_mgr->e_table_unit)) return false;

	m_aggr_val.InsertColumn(0, APL_T("№"),LVCFMT_LEFT,25);
	m_aggr_val.CListCtrl::SetColumnWidth(0,25);
	w=100;

	CString buf;
	int colums=0;
	CaplInstance *val0;
	CaplAggr aggr0;
	m_data->GetAttrBN(unit,_T("columns"),aggr0);
	for(i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,val0);
		if(val0==0) continue;
		m_data->GetAttrBN(val0,_T("name"),buf);
		colums++;
		w=100;
		if(widths.GetSize()>colums) w=widths[colums];
		m_aggr_val.InsertColumn(colums,buf,LVCFMT_LEFT,w);
		CaplInstance *tab_unit=0;
		m_data->GetAttr(val0,m_charact_mgr->a_table_column_unit,tab_unit);
		if(tab_unit)
		{
			if(m_data->IsKindOf(tab_unit,m_charact_mgr->e_apl_time_unit))
				m_aggr_val.SetColumnDate(colums);
			else if(m_data->IsKindOf(tab_unit,m_charact_mgr->e_apl_step_unit))
				m_aggr_val.SetColumnNumeric(colums);
		}
		
		m_ColumnListMap.Add((long)val0,colums-1);
	}
	return true;
}
//*****************************************************************
void CCharacteristicDlg::PrintTableInList(CaplInstance *val)
{
	m_aggr_val.DeleteAllItems();
	if(val==0) return;
	if(!m_data->IsKindOf(val,m_charact_mgr->e_table_val)) 
		if(!m_data->IsKindOf(val,m_charact_mgr->e_table_val_ver)) 
			return;
	CString buf;
	int i,j,row=0,column=0;
	CaplInstance *val0,*val1,*val2;
	CaplAggr aggr0;
	if(m_data->IsKindOf(val,m_charact_mgr->e_table_val))
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_table_val,aggr0);
	else
		m_data->GetAttr(val,m_charact_mgr->a_apl_charact_val_ver_table_val,aggr0);
	for(i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,val0);
		if(val0==0) continue;
		row++;
		row=m_aggr_val.InsertItem(row,_T(""));
		buf.Format(_T("%3i"),row);
		m_aggr_val.SetItemText(row,0,buf);
		m_aggr_val.SetItemData(row,row);

		CaplAggr aggr1;
		if(m_data->IsKindOf(val0,m_charact_mgr->e_table_row)) 
			m_data->GetAttr(val0,m_charact_mgr->a_table_row_items,aggr1);
		else if(m_data->IsKindOf(val0,m_charact_mgr->e_table_row_ver))
			m_data->GetAttr(val0,m_charact_mgr->a_table_row_ver_items,aggr1);
		else
			continue;
		for(j=0;j<aggr1.GetSize();j++)
		{
			aggr1.GetByIndex(j,val1);
			if(val1==0) continue;
			CaplInstance *i_column;
			if(m_data->IsKindOf(val1,m_charact_mgr->e_table_cell))
				m_data->GetAttr(val1,m_charact_mgr->a_table_cell_column,i_column);
			else
				m_data->GetAttr(val1,m_charact_mgr->a_table_cell_ver_column,i_column);
			column=m_ColumnListMap.GetByIn((long)i_column);
			if(column==-1){continue;}//столбцы у которых нет apl_table_column игнорируем! Раньше почему-то их значения писали в первый	 столбец...// column=0;
			if(column>=0)
			{
				if(m_data->IsKindOf(val1,m_charact_mgr->e_table_cell))
					m_data->GetAttr(val1,m_charact_mgr->a_table_cell_val,val2);
				else
					m_data->GetAttr(val1,m_charact_mgr->a_table_cell_ver_val,val2);
				m_charact_mgr->PrintCharacteristicValue(val2,0,buf,true);
				m_aggr_val.SetItemText(row,column+1,buf);
			}
		}
	}
}
//*****************************************************************
void CCharacteristicDlg::OnSaveToFile() 
{
	if(m_aggr_val.IsWindowVisible()) apl_SaveListCtrlToFile(&m_aggr_val,0);
}

void CCharacteristicDlg::OnSelectInstance() 
{
	if(!m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_reference_unit)) return;
	
	CaplInstance *inst=m_charact_mgr->BrowseReferenceVal(m_unit);
	if(inst==0) return;

	m_cur_ref_val=inst;
	CString buf;
	m_charact_mgr->GetItemName(m_cur_ref_val, buf);
	m_value_ctrl.SetWindowText(buf);
}
//******************************************************************************
void CCharacteristicDlg::OnSelCharact() 
{
	CaplInstance *newCharact=m_charact_mgr->SelectCharacteristic(m_charactteristic);
	SetCharacterystic(newCharact);
	m_Tab.InitStates();
}
void CCharacteristicDlg::SetCharacterystic(CaplInstance *new_charact)
{
	if(new_charact==0) return;
	m_measure_unit_ctrl.SetWindowText(_T("???"));

	CString buf,buf1;
	CaplInstance *inst1;
	HideValue();
	m_data->GetAttrBN(new_charact,S::name,buf);
	m_data->GetAttrBN(new_charact,S::id,buf1);
	m_charact.SetWindowText(buf1+ _T(" : ")+buf);
	m_charactteristic=new_charact;
	//CString buf1;
	//m_data->GetAttrBN(m_charactteristic,_T("unit"),inst1);
	//m_charact_mgr->GetUnitName(inst1,buf1);
	//buf+=_T("  [");buf+=buf1;buf+=_T("]");

	m_data->GetAttrBN(new_charact,_T("unit"),inst1);
	CaplInstance *old_unit=m_unit;
	m_unit=inst1;
	m_charact_mgr->GetUnitName(inst1,buf);
	m_measure_unit_ctrl.SetWindowText(buf);
	if(m_value!=0)
	{
		if(old_unit!=m_unit)
		{
			if(!m_no_del_val_if_selchange)
			{
				m_charact_mgr->DeleteCharacteristic(m_value);
				m_value=0;
			}
		}
	}
	if(inst1!=0)
	{
		if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_step_unit))
		{
			if (old_unit!=m_unit) m_value_ctrl.SetWindowText(_T("0"));
			m_min_dev.SetWindowText(_T("0"));
			m_max_dev.SetWindowText(_T("0"));

			m_value_ctrl.SetReadOnly(m_ReadOnly);
			m_stat_value.ShowWindow(SW_SHOW);
			m_value_ctrl.ShowWindow(SW_SHOW);
			m_min_dev.ShowWindow(SW_SHOW);
			m_max_dev.ShowWindow(SW_SHOW);
			m_stat_max.ShowWindow(SW_SHOW);
			m_stat_min.ShowWindow(SW_SHOW);
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_descript_unit))
		{
			m_str_val_ctrl.ShowWindow(SW_SHOW);
			m_stat_value.ShowWindow(SW_SHOW);
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_enum_unit))
		{
			m_enum_val_ctrl.ResetContent();
			CaplAggr aggr;
			CString buf;
			m_data->GetAttrBN(inst1,_T("values"),aggr);
			for(int i=0;i<aggr.GetSize();i++)
			{
				if(aggr.GetByIndex(i,buf))
					m_enum_val_ctrl.AddString(buf);
			}
			m_stat_value.ShowWindow(SW_SHOW);
			m_enum_val_ctrl.ShowWindow(SW_SHOW);
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_monetary_unit))
		{
			if (old_unit!=m_unit) m_value_ctrl.SetWindowText(_T(""));
			m_value_ctrl.SetReadOnly(m_ReadOnly);
			m_value_ctrl.ShowWindow(SW_SHOW);
			m_stat_value.ShowWindow(SW_SHOW);
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_time_unit))
		{
			m_date_ctrl.ShowWindow(SW_SHOW);
			m_time_ctrl.ShowWindow(SW_SHOW);
			m_stat_value.ShowWindow(SW_SHOW);
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_aggr_unit))
		{
			m_aggr_val.ShowWindow(SW_SHOW);
			m_save_to_file.ShowWindow(SW_SHOW);
			if(!m_ReadOnly)
			{
				m_top_btn.ShowWindow(SW_SHOW);
				m_bottom_btn.ShowWindow(SW_SHOW);
			}
			if(m_value==0) m_value=m_data->CreateInstance(m_charact_mgr->e_aggr_val);
			if(m_value) PrintAggrInList(m_value);
			m_stat_value.ShowWindow(SW_SHOW);
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_table_unit))
		{
			m_aggr_val.ShowWindow(SW_SHOW);
			m_save_to_file.ShowWindow(SW_SHOW);
			if(!m_ReadOnly)
			{
				m_top_btn.ShowWindow(SW_SHOW);
				m_bottom_btn.ShowWindow(SW_SHOW);
			}
			if(m_value==0) m_value=m_data->CreateInstance(m_charact_mgr->e_table_val);
			CreateTableHeader(inst1);
			if(m_value) PrintTableInList(m_value);
			m_stat_value.ShowWindow(SW_SHOW);
			
		}
		else if(m_data->IsKindOf(inst1,m_charact_mgr->e_apl_reference_unit))
		{
			buf=_T("");
			if (old_unit==m_unit)
			{
				if(m_cur_ref_val!=0) m_charact_mgr->GetItemName(m_cur_ref_val,buf);
			}
			else m_cur_ref_val=0;
			m_value_ctrl.SetWindowText(buf);
			m_value_ctrl.ShowWindow(SW_SHOW);
			m_stat_value.ShowWindow(SW_SHOW);
			m_SelInstBtn.ShowWindow(SW_SHOW);
			m_value_ctrl.SetReadOnly(TRUE);
		}
		else		
		{
			AfxMessageBox(APL_T("В этой версии данный тип не поддерживается"));
		}
	}
}

void CCharacteristicDlg::SetReadOnlyItems()
{
	if(m_ReadOnly) m_mode=_T("View");
	else m_mode=_T("Edit");
	m_min_dev.SetReadOnly(m_ReadOnly);
	m_max_dev.SetReadOnly(m_ReadOnly);
	m_value_ctrl.SetReadOnly(m_ReadOnly);
	m_str_val_ctrl.SetReadOnly(m_ReadOnly);
	
	if(m_value != NULL && m_value->GetType() != NULL)
	{
		if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_reference_value_ver))
			m_value_ctrl.SetReadOnly(true);
	}

	m_measure_count.SetReadOnly(m_ReadOnly);
	m_enum_val_ctrl.EnableWindow(!m_ReadOnly);
	m_scope.SetReadOnly(m_ReadOnly);
	m_type.EnableWindow(!m_ReadOnly && !m_locked_type);	
	m_ok_btn.EnableWindow(!m_ReadOnly);	
	m_date_ctrl.EnableWindow(!m_ReadOnly);	
	m_time_ctrl.EnableWindow(!m_ReadOnly);
	m_SelInstBtn.EnableWindow(!m_ReadOnly);
}



void CCharacteristicDlg::OnCheckOut() 
{
	CaplInstance *item=0;
	m_data->GetAttrBN(m_value,_T("item"),item);
	if(!item)
	{
		m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_base_item,item);
		return;
	}
	bool check_out_result=false;
	if(m_data->IsKindOf(item,m_charact_mgr->m_api->m_bp_mgr.e_bp))
	{
		check_out_result=m_api->m_bp_mgr.CheckOutWithRequest(item);
	}
	else 
		check_out_result=m_charact_mgr->CheckOut(m_value);
	
	if(check_out_result)
	{
		m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_lock_ver,m_value);
		if(m_value)
		{
			m_check_out_ctrl.ShowWindow(SW_HIDE);
			m_check_in_ctrl.ShowWindow(SW_SHOW);
			m_undo_check_out_ctrl.ShowWindow(SW_SHOW);
			if(!m_api->m_data.IsKindOf(m_item, m_api->m_bp_mgr.e_bp))
				m_autoCheckinCtrl.ShowWindow(SW_SHOW);

			m_ReadOnly=false;
			SetWindowText( APL_T("Версия характеристики"));
			SetReadOnlyItems();
			CreateTempVal();
		}
	}
	
}

void CCharacteristicDlg::OnCheckIn() 
{
	CheckIn();
}

void CCharacteristicDlg::OnUndoCheckOut() 
{
	CaplInstance *char_ver_char_value=0;
	m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_char_value,char_ver_char_value);
	if(char_ver_char_value)
	{
		CaplInstance *item=0;
		m_data->GetAttrBN(char_ver_char_value,_T("item"),item);
		if(!item)
		{	
			m_data->GetAttr(char_ver_char_value,m_charact_mgr->a_apl_charact_val_base_item,item);
			return;
		}

		bool undo_check_out_result=false;
		
		if(m_data->IsKindOf(item,m_charact_mgr->m_api->m_bp_mgr.e_bp))
		{
			undo_check_out_result=m_api->m_bp_mgr.UndoCheckOutWithRequest(item);
		}
		else
			undo_check_out_result=m_charact_mgr->UndoCheckOut(char_ver_char_value);

		if(undo_check_out_result)
		{
			m_check_out_ctrl.ShowWindow(SW_SHOW);
			m_check_in_ctrl.ShowWindow(SW_HIDE);
			m_undo_check_out_ctrl.ShowWindow(SW_HIDE);
			m_autoCheckinCtrl.ShowWindow(SW_HIDE);

			m_ReadOnly=true;
			SetWindowText( APL_T("Характеристика"));
			SetReadOnlyItems();
			m_charact_mgr->DeleteCharacteristic(m_value);//удаление временной версии
			m_old_value=0;//ее уже удалили при UndoCheckOut
			m_value=char_ver_char_value;
			SetFromInst(m_value);
		}
	}
}

void CCharacteristicDlg::CreateTempVal()
{
	if(m_value)
	{
		if(m_value->GetAccessmode()<aplNO)
		{
			if(m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val))
			{
				m_old_value=m_value;
				m_value=m_charact_mgr->CreateCopyCharacteristicVal(m_value);
			}
			else if(m_data->IsKindOf(m_value,m_charact_mgr->e_aggr_val_ver))
			{
				m_old_value=m_value;
				m_value=m_charact_mgr->CreateCharValVersion(m_value,_T("-1"),false);
			}	
			else if(m_data->IsKindOf(m_value,m_charact_mgr->e_table_val))
			{
				m_old_value=m_value;
				m_value=m_charact_mgr->CreateCopyCharacteristicVal(m_value,0,&m_val_map);
			}
			else if(m_data->IsKindOf(m_value,m_charact_mgr->e_table_val_ver))
			{
				m_old_value=m_value;
				m_value=m_charact_mgr->CreateCharValVersion(m_value,_T("-1"),false);
			}
		}
	}
}

bool CCharacteristicDlg::SaveChanges(bool bSaveChanges)
{
	// TODO: Add extra validation here
	if(!UpdateData(TRUE)) return false;

	if(m_charactteristic==0){AfxMessageBox( APL_T("Характеристика не выбрана !!!")); return false;}

	m_data->GetAttrBN(m_charactteristic,_T("unit"),m_unit);

	double rval=0,min_dev=0,max_dev=0;
	double rval1=0,min_dev1=0,max_dev1=0;
	CString sval,buf;
	CaplInstance *inst;
	
	// проверка типов
	CaplInstance *type=(CaplInstance*)m_type.GetItemData(m_type.GetCurSel());
	if(type==(CaplInstance*)-1)type=0;
//	if(type==0) { AfxMessageBox(APL_T("Тип не выбран !!!"));return;}

	if(m_creation_mode)
	{
		CaplInstance *tst_inst=0;
		
		m_measure_count.GetWindowText(sval);
		int num=_atoi(sval);
	
		// Проверка существования
		CaplAttrValue tst_values[4];
		tst_values[0].value.Set(m_item);
		tst_values[0].attr=m_charact_mgr->a_apl_charact_val_item;
		tst_values[1].value.Set(type);
		tst_values[1].attr=m_charact_mgr->a_apl_charact_val_type;
		tst_values[2].value.Set(m_charactteristic);
		tst_values[2].attr=m_charact_mgr->a_apl_charact_val_charact;
		tst_values[3].value.Set(num);
		tst_values[3].attr=m_charact_mgr->a_apl_charact_val_num;

		/*aplExtent ext1;
		bool b1=m_data->NET_FindInstancesWithAttrValues(m_charact_mgr->e_apl_charact_value,4,&tst_values[0], ext1, false);
		CaplInstance *intstmp=0;
		if(ext1.GetSize()>0) intstmp=ext1[0];*/

		if(!m_data->NET_TestUniqueAttrValues(m_charact_mgr->e_apl_charact_value,tst_inst,4,&tst_values[0], false))
		{
			AfxMessageBox( APL_T("Такая характеристика уже существует !!!"));return false ;
		}
	}

	if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_step_unit))
	{
		m_value_ctrl.GetWindowText(sval);
		sval.TrimLeft(); sval.TrimRight();
		if(!IsReal(sval))
		{
			AfxMessageBox( APL_T("Значение должно быть числом !!!"));
			return false;
		}
		if(sval.GetLength()>15){
			AfxMessageBox( APL_T("Значение не должно быть длиннее 15 разрядов!!!"));
			return false;
		}
		rval=__atof(sval);

		m_max_dev.GetWindowText(sval);
		sval.TrimLeft(); sval.TrimRight();
		if(!IsRealOrEmpty(sval))
		{
			AfxMessageBox( APL_T("Максимальное отклонение должно быть числом !!!"));
			return false;
		}
		if(sval.GetLength()>15){
			AfxMessageBox( APL_T("Максимальное отклонение не должно быть длиннее 15 разрядов!!!"));
			return false;
		}
		max_dev=__atof(sval);

		m_min_dev.GetWindowText(sval);
		sval.TrimLeft(); sval.TrimRight();
		if(!IsRealOrEmpty(sval))
		{
			AfxMessageBox( APL_T("Минимальное отклонение должно быть числом !!!"));
			return false;
		}
		if(sval.GetLength()>15){
			AfxMessageBox( APL_T("Минимальное отклонение не должно быть длиннее 15 разрядов!!!"));
			return false;
		}
		min_dev=__atof(sval);
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_monetary_unit))
	{
		m_value_ctrl.GetWindowText(sval);
		sval.TrimLeft(); sval.TrimRight();
		if(!IsReal(sval))
		{
			AfxMessageBox( APL_T("Значение должно быть числом !!!"));
			return false;
		}
		if(sval.GetLength()>15){
			AfxMessageBox( APL_T("Значение не должно быть длиннее 15 разрядов!!!"));
			return false;
		}
		rval=__atof(sval);
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_enum_unit))
	{
		m_enum_val_ctrl.GetWindowText(sval);
		if(sval==_T(""))
		{
			AfxMessageBox( APL_T("Значение не выбрано !!!"));
			return false;
		}
	}
	// создание объектов
	//if(m_mode==_T("Create"))

	CaplEntity *ent_val=0,*ent_val_ver=0;
	
	if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_step_unit))
	{
		ent_val=m_charact_mgr->e_meas_value;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_descript_unit))
	{
		ent_val=m_charact_mgr->e_descr_value;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_monetary_unit))
	{
		ent_val=m_charact_mgr->e_monet_value;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_time_unit))
	{
		ent_val=m_charact_mgr->e_time_val;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_enum_unit))
	{
		ent_val=m_charact_mgr->e_enum_value;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_aggr_unit))
	{
		ent_val=m_charact_mgr->e_aggr_val;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_table_unit))
	{
		ent_val=m_charact_mgr->e_table_val;
	}
	else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_reference_unit))
	{
		ent_val=m_charact_mgr->e_apl_reference_value;
	}

/*	if(m_value!=0)
	{
		if(m_value->GetType()!=ent_val)
		{
			m_charact_mgr->DeleteCharacteristic(m_value);
			m_value=0;
		}
	}*/

	CaplInstance *m_value_ver=0;
	if(m_value==0)
	{
		if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_reference_unit))
		{
			if(m_cur_ref_val==0){ AfxMessageBox( APL_T("Объект не выбран !!!"));return false; }			
		}

		m_value=m_data->CreateInstance(ent_val);

		// 25.03.26 ЯАИ Добавлено, т.к. иначе можно не работает проверка уникальности и можно создать несколько одинаковых хар-к
		m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_item, m_item);

	}
	// Запись значений
	long wait_dlg=aplStartWaitDlg( APL_T("Идет запись ..."));

	bool smth_changed=false;
	if(m_value!=0)
	{
		if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value_ver))
		{
			if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_step_unit))
			{
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_meas_val,rval1);
				if(rval1!=rval)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_meas_val,rval);
					smth_changed=true;
				}

				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_meas_min,min_dev1);
				if(min_dev1!=min_dev)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_meas_min,min_dev);
					smth_changed=true;
				}
				
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_meas_max,max_dev1);
				if(max_dev1!=max_dev)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_meas_max,max_dev);
					smth_changed=true;
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_descript_unit))
			{
				m_str_val_ctrl.GetWindowText(sval);
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_descr_val,buf);
				if(buf!=sval)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_descr_val,sval);
					smth_changed=true;
				}

			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_monetary_unit))
			{
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_monet_val,rval1);
				if(rval1!=rval)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_monet_val,rval);
					smth_changed=true;
				}

			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_reference_unit))
			{
				CaplInstance *tmp_inst;
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_reference_val_ver_val,tmp_inst);
				if(m_cur_ref_val!=tmp_inst)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_reference_val_ver_val,m_cur_ref_val);
					smth_changed=true;
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_time_unit))
			{
				COleDateTime odt,odt0,odt1,odt_old; 
				odt=COleDateTime::GetCurrentTime();
				CString s_date;
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_time_val_s,s_date);
				//bool f=true;
				//if(s_date==_T("")) f=false;
				aplString2Date(s_date,odt_old);
				m_date_ctrl.GetTime(odt0);
				m_time_ctrl.GetTime(odt1);
				odt.SetDateTime(odt0.GetYear(),odt0.GetMonth(),odt0.GetDay(),
					odt1.GetHour(),odt1.GetMinute(),odt1.GetSecond());
				if(odt!=odt_old)
				{
					aplDate2String(odt,s_date);
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_time_val_s,s_date);	
					smth_changed=true;
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_enum_unit))
			{
				m_enum_val_ctrl.GetWindowText(sval);
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_enum_val,buf);
				if(buf!=sval)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_enum_val,sval);
					smth_changed=true;
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_aggr_unit))
			{
				if(m_old_value)
				{
					CaplAggr aggr0,aggr1;
					
					if(m_charact_mgr->IsValueChanged(m_old_value,m_value)) 
					{
						smth_changed=true;
						m_data->GetAttr(m_old_value,m_charact_mgr->a_apl_charact_val_ver_aggr_val, aggr0);
						m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_aggr_val, aggr1);
						m_data->PutAttr(m_old_value,m_charact_mgr->a_apl_charact_val_ver_aggr_val, aggr1);
					
					}
					else
						m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_aggr_val, aggr0);
					for(int i=0;i<aggr0.GetSize();i++)
					{
						CaplInstance *t_inst;
						aggr0.GetByIndex(i,t_inst);
						if(!t_inst) continue;
						if(t_inst!=m_value) m_charact_mgr->DeleteCharacteristic(t_inst);
					}
					m_data->DeleteInstance(m_value);
					m_value=m_old_value;
					m_old_value=0;
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_table_unit))
			{
				if(m_old_value)
				{
					CaplAggr aggr0,aggr1;
					if(m_charact_mgr->IsValueChanged(m_old_value,m_value)) 
					{
						smth_changed=true;
						/*int i;
						for(i=0;i<m_val_map.Size;i++)
						{
							if((CaplInstance*)(m_val_map[i].out)==m_value) continue;
							if(((CaplInstance*)(m_val_map[i].out))->GetType()==0) continue;
							((CaplInstance*)(m_val_map[i].out))->id=((CaplInstance*)(m_val_map[i].in))->id;
							((CaplInstance*)(m_val_map[i].in))->id=0;
						}*/

						m_data->GetAttr(m_old_value,m_charact_mgr->a_apl_charact_val_ver_table_val, aggr0);
						m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_table_val, aggr1);
						m_data->PutAttr(m_old_value,m_charact_mgr->a_apl_charact_val_ver_table_val, aggr1);

						/*CaplAttrValue *attr_val0=m_data->CreateAttrValue(m_old_value,m_charact_mgr->a_apl_charact_val_ver_table_val);
						CaplAttrValue *attr_val1=m_data->CreateAttrValue(m_value,m_charact_mgr->a_apl_charact_val_ver_table_val);
						if(attr_val0->ArhiveAggr!=0) delete attr_val0->ArhiveAggr;
						attr_val0->ArhiveAggr=new CaplAggr;
						if(attr_val1->ArhiveAggr!=0) attr_val0->ArhiveAggr->Append(*(attr_val1->ArhiveAggr));	*/
					}
					else
						m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_table_val, aggr0);

					for( int i=0;i<aggr0.GetSize();i++){
						CaplInstance *t_inst;
						aggr0.GetByIndex(i,t_inst);
						if(!t_inst) continue;
						if(t_inst!=m_value) m_charact_mgr->DeleteCharacteristic(t_inst);
					}
					m_data->DeleteInstance(m_value);
					m_value=m_old_value;
					m_old_value=0;
				}
			}
	
		}
		else if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value))
		{
			if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_step_unit))
			{
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_meas_val,rval1);
				if(rval1!=rval)
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_meas_val,rval);
				
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_meas_min,min_dev1);
				if(min_dev1!=min_dev)
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_meas_min,min_dev);
				
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_meas_max,max_dev1);
				if(max_dev1!=max_dev)
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_meas_max,max_dev);
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_descript_unit))
			{
				m_str_val_ctrl.GetWindowText(sval);
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_descr_val,buf);
				if(buf!=sval)
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_descr_val,sval);
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_monetary_unit))
			{
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_monet_val,rval1);
				if(rval1!=rval)
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_monet_val,rval);
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_reference_unit))
			{
				CaplInstance *tmp_inst;
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_reference_val,tmp_inst);
				if(m_cur_ref_val!=tmp_inst)
				{
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_reference_val,m_cur_ref_val);
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_unit,m_unit);
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_time_unit))
			{
				COleDateTime odt,odt0,odt1,odt_old; 
				odt=COleDateTime::GetCurrentTime();
				CString s_date;
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_time_val_s,s_date);
				//bool f=true;
				//if(s_date==_T("")) f=false;
				aplString2Date(s_date,odt_old);
				m_date_ctrl.GetTime(odt0);
				m_time_ctrl.GetTime(odt1);
				odt.SetDateTime(odt0.GetYear(),odt0.GetMonth(),odt0.GetDay(),
					odt1.GetHour(),odt1.GetMinute(),odt1.GetSecond());
				if(odt!=odt_old)
				{
					aplDate2String(odt,s_date);
					//if(f)
						m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_time_val_s,s_date);	
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_enum_unit))
			{
				m_enum_val_ctrl.GetWindowText(sval);
				m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_enum_val,buf);
				if(buf!=sval)
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_enum_val,sval);
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_apl_aggr_unit))
			{
				if(m_old_value)
				{
					CaplAggr aggr0,aggr1;
					m_data->GetAttr(m_old_value,m_charact_mgr->a_apl_charact_val_aggr_val, aggr0);
					m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_aggr_val, aggr1);
					m_data->PutAttr(m_old_value,m_charact_mgr->a_apl_charact_val_aggr_val, aggr1);
					for(int i=0;i<aggr0.GetSize();i++){
						CaplInstance *t_inst;
						aggr0.GetByIndex(i,t_inst);
						if(!t_inst) continue;
						if(t_inst!=m_value) m_charact_mgr->DeleteCharacteristic(t_inst);
					}
					m_data->DeleteInstance(m_value);
					m_value=m_old_value;
					m_old_value=0;
				}
			}
			else if(m_data->IsKindOf(m_unit,m_charact_mgr->e_table_unit))
			{
				if(m_old_value)
				{
					int i;
					for(i=0;i<m_val_map.Size;i++)
					{
						if((CaplInstance*)(m_val_map[i].out)==m_value) continue;
						if(((CaplInstance*)(m_val_map[i].out))->GetType()==0) continue;
						((CaplInstance*)(m_val_map[i].out))->SetId(((CaplInstance*)(m_val_map[i].in))->GetId());
						((CaplInstance*)(m_val_map[i].in))->SetId(0);
					}
					CaplAggr aggr0,aggr1;
					m_data->GetAttr(m_old_value,m_charact_mgr->a_apl_charact_val_table_val, aggr0);
					m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_table_val, aggr1);
					m_data->PutAttr(m_old_value,m_charact_mgr->a_apl_charact_val_table_val, aggr1);

					CaplInstance::CaplValueDefinition *attr_val0=m_data->GetAttrValue(m_old_value,m_charact_mgr->a_apl_charact_val_table_val,true);
					CaplInstance::CaplValueDefinition *attr_val1=m_data->GetAttrValue(m_value,m_charact_mgr->a_apl_charact_val_table_val,true);
					if(attr_val0->ArhiveAggr!=0) delete attr_val0->ArhiveAggr;
					attr_val0->ArhiveAggr=new CaplAggr;
					if(attr_val1->ArhiveAggr!=0) attr_val0->ArhiveAggr->Append(*(attr_val1->ArhiveAggr));	

					for( i=0;i<aggr0.GetSize();i++){
						CaplInstance *t_inst;
						aggr0.GetByIndex(i,t_inst);
						if(!t_inst) continue;
						if(t_inst!=m_value) m_charact_mgr->DeleteCharacteristic(t_inst);
					}
					m_data->DeleteInstance(m_value);
					m_value=m_old_value;
					m_old_value=0;
				}
			}
		}	
			
	

		int i,j;
		if(m_data->IsKindOf(m_value,m_charact_mgr->e_apl_charact_value_ver))
		{
			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_num,i);
			m_measure_count.GetWindowText(sval);
			j=_atoi(sval);
			if(i!=j) 
			{
				m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_num,j);
				smth_changed=true;
			}
			
			m_scope.GetWindowText(sval);
			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_scope,buf);
			if(buf!=sval) 
			{
				m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_scope,sval);
				smth_changed=true;
			}

			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_type,inst);
			if(inst!=type) 
			{
				m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_type,type);
				smth_changed=true;
			}
		
			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_charact,inst);
			if(inst!=m_charactteristic)	
			{
				m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_charact,m_charactteristic);
				smth_changed=true;
			}
			if(smth_changed)
				m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_is_changed,true);
		}
		else
		{
			if(m_item!=0) 
			{
				m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_base_item,m_item);	
				if(!m_data->IsKindOf(m_item,m_api->m_bp_mgr.e_bp))
					m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_item,m_item);	
			}

			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_num,i);
			m_measure_count.GetWindowText(sval);
			j=_atoi(sval);
			if(i!=j) m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_num,j);
			
			m_scope.GetWindowText(sval);
			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_scope,buf);
			if(buf!=sval) m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_scope,sval);

			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_type,inst);
			if(inst!=type) m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_type,type);

		
			m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_charact,inst);
			if(inst!=m_charactteristic)	m_data->PutAttr(m_value,m_charact_mgr->a_apl_charact_val_charact,m_charactteristic);
		}

	}

	if(bSaveChanges)m_data->NET_SaveChanges();
	
	aplEndWaitDlg(wait_dlg);
	return true;
}

void CCharacteristicDlg::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 CCharacteristicDlg::OnBPropsAdd() 
{
	CaplPropsView* pView	=NULL;

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

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

void CCharacteristicDlg::OnBPropsDel() 
{
	CaplPropsView* pView	=NULL;

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

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

void CCharacteristicDlg::OnBPropsProps() 
{
	CaplPropsView* pView	=NULL;

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

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

bool CCharacteristicDlg::CheckIn()
{
	CaplInstance *char_ver_char_value=0;
	
	if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value))
		char_ver_char_value= m_value;
	else if(m_api->m_data.IsKindOf(m_value, m_api->m_charact_mgr.e_apl_charact_value_ver))
		m_data->GetAttr(m_value,m_charact_mgr->a_apl_charact_val_ver_char_value,char_ver_char_value);
	
	if(char_ver_char_value)
	{
		CaplInstance *item=0;
		m_data->GetAttrBN(char_ver_char_value,_T("item"),item);
		if(!item)
		{
			m_data->GetAttr(char_ver_char_value,m_charact_mgr->a_apl_charact_val_base_item,item);
			return false;
		}
		if(!SaveChanges(false)) return false;
		bool check_in_result=false;
		
		if(m_data->IsKindOf(item,m_charact_mgr->m_api->m_bp_mgr.e_bp))
		{
			check_in_result=m_api->m_bp_mgr.CheckInWithRequest(item);
		}
		else
			check_in_result=m_charact_mgr->CheckIn(char_ver_char_value);
		
		if(check_in_result)
		{
			m_check_out_ctrl.ShowWindow(SW_SHOW);
			m_check_in_ctrl.ShowWindow(SW_HIDE);
			m_undo_check_out_ctrl.ShowWindow(SW_HIDE);
			m_autoCheckinCtrl.ShowWindow(SW_HIDE);
			
			m_ReadOnly=true;
			SetWindowText( APL_T("Характеристика"));
			SetReadOnlyItems();
			m_value=char_ver_char_value;
		}
	}

	return true;
}
