// DlgSetInstAccess.cpp : implementation file
//

#include "stdafx.h"
#include "DlgSetInstAccess.h"
#include "DlgAccessPatterns.h"

#include <apl_gui.h>

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

#define PATTERN_NOT_SET  APL_T("<Шаблон доступа не задан>")
extern CImageList imagelist;
//extern CaplLog m_MainLog;

/////////////////////////////////////////////////////////////////////////////
// 


/////////////////////////////////////////////////////////////////////////////
// CDlgSetInstAccess dialog


CDlgSetInstAccess::CDlgSetInstAccess(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CDlgSetInstAccess::IDD, pParent)
	, m_PatternName(_T(""))
	,m_ind_unk(false)
{
	//{{AFX_DATA_INIT(CDlgSetInstAccess)
	m_IndAccess = FALSE;
	//}}AFX_DATA_INIT
	m_is_edited = false;
	m_only_RO = false;	
	m_edit_access_pattern = false;
	m_pattern_changed = false;
	m_new_pattern = 0;

	m_ListAccess2Inst = 0;
	m_main_table = 0;
	m_data = 0;

}



void CDlgSetInstAccess::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgSetInstAccess)
	DDX_Control(pDX, IDOK, m_CtrlOk);
	DDX_Control(pDX, IDCANCEL, m_CtrlCancel);
	DDX_Control(pDX, IDC_COMBO_ACCESS, m_CmbxAccess);
	DDX_Control(pDX, ID_ACCESS_AGENT_CHNG, m_CtrlBtnChng);
	DDX_Control(pDX, IDC_LIST_ACCESS_AGENTS, m_ListAccessAgents);
	DDX_Control(pDX, ID_ACCESS_AGENT_DEL, m_CtrlBtnDel);
	DDX_Control(pDX, ID_ACCESS_AGENT_ADD, m_CtrlBtnAdd);
	DDX_Control(pDX, IDC_IND_ACCESS, m_IndAccessCtrl);
	DDX_Control(pDX, IDC_STATIC_1, m_Static1);
	DDX_Control(pDX, IDC_DEF_ACCESS, m_CmbxDefAccess);
	DDX_Check(pDX, IDC_IND_ACCESS, m_IndAccess);
	//}}AFX_DATA_MAP
	DDX_Text(pDX, IDC_EDIT_PATTERN, m_PatternName);
	DDX_Control(pDX, IDC_STATIC_TEXT_PAT, m_StTextPat);
	DDX_Control(pDX, IDC_EDIT_PATTERN, m_EdtPat);
	DDX_Control(pDX, IDC_SELECT_PATTERN, m_ButPat);
}


BEGIN_MESSAGE_MAP(CDlgSetInstAccess, CaplResizableDialog)
//{{AFX_MSG_MAP(CDlgSetInstAccess)
	ON_BN_CLICKED(IDC_IND_ACCESS, OnIndAccess)
	ON_CBN_SELCHANGE(IDC_DEF_ACCESS, OnSelchangeDefAccess)
	ON_BN_CLICKED(ID_ACCESS_AGENT_ADD, OnButtonAdd)
	ON_BN_CLICKED(ID_ACCESS_AGENT_DEL, OnButtonDelete)
	ON_NOTIFY(NM_RCLICK, IDC_LIST_ACCESS_AGENTS, OnRclickListAccessAgents)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST_ACCESS_AGENTS, OnDblclkListAccessAgents)
	ON_BN_CLICKED(ID_ACCESS_AGENT_CHNG, OnAccessAgentChng)
	ON_NOTIFY(NM_CLICK, IDC_LIST_ACCESS_AGENTS, OnClickListAccessAgents)
//}}AFX_MSG_MAP
	//ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipShow)
	ON_BN_CLICKED(IDC_SELECT_PATTERN, &CDlgSetInstAccess::OnBnClickedSelectPattern)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgSetInstAccess message handlers

#define MOVE_RECT(rect,delta) rect.top-=delta;rect.bottom-=delta;

BOOL CDlgSetInstAccess::OnInitDialog() 
{
	if(m_main_table== 0 && m_ListAccess2Inst == 0)
	{
		AfxMessageBox(APL_T("Ошибка! Не задана таблица доступа!"));
		return FALSE;
	}
	if(m_main_table== 0)
	{
		m_main_table = &m_internal_main_table;
		m_main_table->Set(m_ListAccess2Inst);
	}

	CaplResizableDialog::OnInitDialog();
	if(m_data==NULL)
	{
		EndDialog(0);
		return FALSE;
	}

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

	CaplMenu::Install(this);

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

	m_ListAccessAgents.SetUniqueName(_T("CDlgSetInstAccess::m_ListAccessAgents"));
	EnableToolTips(TRUE);
	m_CmbxAccess.SetParent(&m_ListAccessAgents);
	// TODO: Add extra initialization here
	m_list=NULL;
	m_dlg_select.Attach(m_data);

	m_CmbxDefAccess.AddString( APL_T("Полный доступ"));
	m_CmbxDefAccess.AddString( APL_T("Чтение-запись"));
	m_CmbxDefAccess.AddString( APL_T("Только чтение"));
	m_CmbxDefAccess.AddString( APL_T("Нет доступа"));

	m_CmbxAccess.AddString( APL_T("Полный доступ"));
	m_CmbxAccess.AddString( APL_T("Чтение-запись"));
	m_CmbxAccess.AddString( APL_T("Только чтение"));
	m_CmbxAccess.AddString( APL_T("Нет доступа"));

	if(m_edit_access_pattern)
	{
		// прячем поля для шаблона
		CRect rect_b,rect_m1,rect_m20,rect_m21,rect_m22,rect_m23,rect_m3;
		int delta;

		m_CmbxDefAccess.AddString( APL_T("Не изменять"));
		m_ButPat.GetWindowRect(rect_b);
		m_IndAccessCtrl.GetWindowRect(rect_m1);
		m_Static1.GetWindowRect(rect_m20);
		m_CtrlBtnDel.GetWindowRect(rect_m21);
		m_CtrlBtnAdd.GetWindowRect(rect_m22);
		m_CtrlBtnChng.GetWindowRect(rect_m23);
		m_ListAccessAgents.GetWindowRect(rect_m3);

		ScreenToClient(rect_b);
		ScreenToClient(rect_m1);
		ScreenToClient(rect_m20);
		ScreenToClient(rect_m21);
		ScreenToClient(rect_m22);
		ScreenToClient(rect_m23);
		ScreenToClient(rect_m3);

		m_ButPat.ShowWindow(SW_HIDE);
		m_EdtPat.ShowWindow(SW_HIDE);
		m_StTextPat.ShowWindow(SW_HIDE);

		delta=rect_m1.top-rect_b.top;

		MOVE_RECT(rect_m1,delta);
		m_IndAccessCtrl.MoveWindow(rect_m1,TRUE);
		MOVE_RECT(rect_m20,delta);
		m_Static1.MoveWindow(rect_m20);
		MOVE_RECT(rect_m21,delta);
		m_CtrlBtnDel.MoveWindow(rect_m21);
		MOVE_RECT(rect_m22,delta);
		m_CtrlBtnAdd.MoveWindow(rect_m22);
		MOVE_RECT(rect_m23,delta);
		m_CtrlBtnChng.MoveWindow(rect_m23);
		MOVE_RECT(rect_m3,delta);
		m_ListAccessAgents.MoveWindow(rect_m3,TRUE);


	}
	
	///////// Заполняем дерево пользователей и групп
	PrepareData();
	CreateList();
	FillDefAccessVal();
	
	UpdateData(FALSE);
	// отрисовывает тип доступа
	DrawIndAccess();

	AddAnchor(IDOK,BOTTOM_RIGHT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);
	AddAnchor(ID_ACCESS_AGENT_ADD,TOP_RIGHT);
	AddAnchor(ID_ACCESS_AGENT_DEL,TOP_RIGHT);
	AddAnchor(ID_ACCESS_AGENT_CHNG,TOP_RIGHT);
	AddAnchor(IDC_IND_ACCESS,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_DEF_ACCESS,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_STATIC_1,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_LIST_ACCESS_AGENTS,TOP_LEFT,BOTTOM_RIGHT);

	AddAnchor(IDC_EDIT_PATTERN,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_SELECT_PATTERN,TOP_RIGHT);

	
	m_CtrlCancel.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));m_CtrlCancel.SetFlat(FALSE);
	m_CtrlOk.SetIcon(GetAplStdIco16(APLSTDICO_OK));m_CtrlOk.SetFlat(FALSE);

	m_CtrlBtnAdd.SetIcon( GetAplTableIco(APL_TABLE_NEW));m_CtrlBtnAdd.SetFlat(FALSE);
	m_CtrlBtnDel.SetIcon( GetAplTableIco(APL_TABLE_DEL));m_CtrlBtnDel.SetFlat(FALSE);
	m_CtrlBtnChng.SetIcon(GetAplTableIco(APL_TABLE_PROP));m_CtrlBtnChng.SetFlat(FALSE);
	
	if(m_only_RO){
		m_CtrlOk.EnableWindow(FALSE);
		m_CmbxAccess.EnableWindow(FALSE);
		m_CtrlBtnChng.EnableWindow(FALSE);
		//m_ListAccessAgents.EnableWindow(FALSE);
		m_CtrlBtnDel.EnableWindow(FALSE);
		m_CtrlBtnAdd.EnableWindow(FALSE);
		m_IndAccessCtrl.EnableWindow(FALSE);
		m_Static1.EnableWindow(FALSE);
		m_CmbxDefAccess.EnableWindow(FALSE);
		SetWindowText( APL_T("Просмотр прав доступа"));
		m_EdtPat.EnableWindow(FALSE);
	}

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


void CDlgSetInstAccess::OnOK() 
{
	// TODO: Add extra validation here
	aplAccessList* list = 0;
	aplAccessEl* el = 0;
	int i,j;
	CString tmp,tmp2;
	int DefAccessPos;
	
	UpdateData(TRUE);
	TestEdited();

	// Определим доступ по умолчанию
	// на выходе флаг m_ind_old==true значит, что флаг индивидуального доступа был снят
	// и настройки инд доступа будут удалены
	DefAccessPos=m_CmbxDefAccess.GetCurSel();

	if(m_IndAccess==TRUE && m_list_groupe.GetSize()== 0 && m_list_users.GetSize()== 0)
	{
		MessageBox( APL_T("Уберите флаг индивидуального доступа или задайте индивидуальный доступ!"),
			 APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR);
		return;
	}
	if(m_IndAccess== false && (m_list_groupe.GetSize() != 0 || m_list_users.GetSize() != 0))
	{
		if(MessageBox( APL_T("Индивидуальные настройки доступа для всех \n пользователей к обрабатываемым объектам \n будут удалены. Вы уверены?"),
				 APL_T("Служба RPC PDM Step Suite"),MB_ICONQUESTION|MB_YESNO|MB_TASKMODAL)!=IDYES)
		{
			return;
		}
	}

	if(DefAccessPos > aplNOT_DEFINED || DefAccessPos < aplOWN)
	{
		tmp =  APL_T("Необходимо задать доступ по умолчанию!");
		MessageBox( tmp, APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR);
		return;
	}
	if(m_ind_unk)
	{
		tmp =  APL_T("Для некоторых обрабатываемых объектов флаг индивидуального доступа не задан. ");
		tmp += APL_T("Для них индивидуальный доступ не будет назначен. Если вы согласны с этим - нажмите \'Да\'.\n");
		tmp += APL_T(" Если вы хотите назначить индивидуальный доступ для всех объектов - нажмите \'Нет\' и поставьте галочку \'Учитывать индивидуальный доступ\'");
		if(MessageBox( tmp, APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR | MB_YESNO)==IDNO) return;

	}
	if(m_patterns.GetSize()>1)
	{
		tmp =  APL_T("Должен быть выбран один шаблон доступа!");
		MessageBox( tmp, APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR);
		return;
	}

	// при редактировании шаблона ограничения существенно жестче
	if(m_edit_access_pattern)
	{
		if(DefAccessPos == aplNOT_DEFINED )
		{
			bool is_temp_users = false;
			for(i = 0;i<m_main_table->GetSize();i++)
			{
				if(m_main_table->GetAt(i)->user != 0)
				{
					if(m_main_table->GetAt(i)->user->GetId() == 1 || m_main_table->GetAt(i)->user->GetId() == 2)
					{
						if(m_main_table->GetAt(i)->GetSize() > 0)
						{
							if(m_main_table->GetAt(i)->GetAt(0)->access != aplNOT_DEFINED)
								is_temp_users = true;
						}
					}
				}
				if(is_temp_users)
					break;
			}
			if(!is_temp_users)
			{
				tmp =  APL_T("Для шаблона без подстановок (текущего пользователя или его группы) необходимо задать доступ по умолчанию!");
				MessageBox( tmp,APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR);
				return;
			}
		}
		for(i = 0;i<m_main_table->GetSize();i++)
		{
			if(m_main_table->GetAt(i)->multy)
			{
				if(m_main_table->GetAt(i)->user== 0)
				{
					tmp =  APL_T("Для доступа по умолчанию должно быть задано одно значение доступа!");
				}
				else
				{
					if(m_IndAccess == false) break;
					m_data->GetAplUserName(m_main_table->GetAt(i)->user, tmp2);
					tmp =  APL_T("Для пользователя ")+tmp2+ APL_T(" должно быть задано одно значение доступа!");
				}
				MessageBox( tmp, APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR);
				return;
			}
		}
	}

	// сейчас сюда будем искать доступ по умолчанию
	m_list = 0;
	// ищем list, который переносит доступ по умолчанию
	// параллельно - если снят флаг инди видуального доступа - чистим и его
	for(i = 0;i<m_main_table->GetSize();i++)
	{
		list=m_main_table->GetAt(i);
		if(list== 0)continue;
		if(list->user== 0)
		{
			m_list=list;
			if(m_IndAccess==TRUE)
			{
				// чистить индивидуальный доступ не надо, доступ по умолчанию уже нашли. Делать в цикле больше нечего
				break;
			}
			continue;
		}
		if(m_IndAccess== false)
		{
			// это индивидуальный доступ. Его надо почистить
			for(j = 0;j<list->GetSize();j++)
			{
				el=list->GetAt(j);
				el->access=aplNOT_DEFINED;
			}
		}
	}
	if(m_list== 0 && (DefAccessPos!=aplNOT_DEFINED || m_new_pattern != 0 ))
	{
		// странно, записи для доступа по умолчанию нет - но доступа то задан, или шаблон задан
		// надо создать запись!
		m_list = new aplAccessList();
		m_list->user = 0;
		m_main_table->Add(m_list);

	}
	if(m_list != 0)
	{
		if(m_list->GetSize()== 0)
		{
			el=new aplAccessEl();
			m_list->Add(el);
		}
		for(j = 0;j<m_list->GetSize();j++)
		{
			el=m_list->GetAt(j);
			if(DefAccessPos != aplNOT_DEFINED )
			{
				if(el->access!=DefAccessPos || (el->is_individual!=m_IndAccess==TRUE))m_list->changed = true;
				el->access = (aplAccessModeType)DefAccessPos;
			}
			if(!m_ind_unk) el->is_individual = m_IndAccess;
			if(m_pattern_changed)el->pattern=m_new_pattern;
		}
		if(m_pattern_changed)m_list->changed = true;
		// поиск дублей доступа по умолчанию
		CheckUserUnique(m_list);
	}

	if(m_ListAccess2Inst != 0)
	{
		aplAccess2Inst* el;
		m_ListAccess2Inst->Set(m_main_table,false);
		// проверка индивидуального доступа
		for(i = 0;i<m_ListAccess2Inst->Size;i++)
		{
			el=m_ListAccess2Inst->GetAt(i);
			if(el->is_individual == TRUE && el->GetSize()== 0)
			{
				tmp =  APL_T("Флаг индивидуального доступа был установлен для всех объектов;\n в то же время индивидуальный доступ для них не задан.\n Необходимо задать как минимум одно значение индивидуального доступа!");
				MessageBox( tmp,APL_T("Служба RPC PDM Step Suite"),MB_ICONERROR);
				return;
			}
		}
	}

	CDialog::OnOK();
}//void CDlgSetInstAccess::OnOK() 




/////////////////////////////////////////////////////
void CDlgSetInstAccess::OnIndAccess() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	ProcessIndAccess();
}
void CDlgSetInstAccess::ProcessIndAccess() 
{
	CheckIndAccess();
	DrawIndAccess();
	aplAccessList* list=m_main_table->Find(0);
	if(list != 0){list->changed = true;}
}

void CDlgSetInstAccess::DrawIndAccess() 
{
	m_Static1.EnableWindow(m_IndAccess);
	m_ListAccessAgents.EnableWindow(m_IndAccess);
	EnableButtons(/*m_IndAccess && m_list*/);
}

// устанавливает указанный доступ для всех инстансов указанного списком юзера (или текущего юзера из дерева)
void CDlgSetInstAccess::SetUserAccess(aplAccessModeType access, aplAccessList* list)
{
	if(list== 0)list=m_list;
	if(list->GetSize() == 0)
	{
		aplAccessEl* el;
		el = new aplAccessEl();
		el->inst = 0;
		el->access = access;
		list->Add(el);
	}
	else
	{
		for(int i = 0;i<list->GetSize();i++)
		{
			list->GetAt(i)->access = access;
		}
	}
	list->changed = true;
	list->multy  = false;
	// поиск дублей указанного юзера
	CheckUserUnique(list);

}

// поиск дублей указанного юзера
void CDlgSetInstAccess::CheckUserUnique(aplAccessList* list)
{
	int j;
	for(j = 0;j<m_main_table->GetSize();j++)
	{
		if(m_main_table->GetAt(j)!=list)
		{
			if(m_main_table->GetAt(j)->user==list->user)
			{
				m_main_table->RemoveAtWithDel(j);
				j--;
			}
		}
	}
}

// 
void CDlgSetInstAccess::EnableButtons()
{
	m_CtrlBtnAdd.EnableWindow(m_IndAccess && !m_only_RO);
	m_CtrlBtnDel.EnableWindow(m_IndAccess && m_list != 0 && !m_only_RO);
	m_CtrlBtnChng.EnableWindow(m_IndAccess && m_list != 0 && !m_only_RO);
}


///////// Подготавливаем список пользователей и групп
void CDlgSetInstAccess::PrepareData()
{
	// Сначала присобачиваем набор картинок
	m_ListAccessAgents.SetImageList(&imagelist,1);//TVSIL_STATE);//TVSIL_NORMAL);//
	m_ListAccessAgents.DeleteColumn(0);
	m_ListAccessAgents.DeleteColumn(0);
	CRect rect;
	m_ListAccessAgents.GetClientRect(rect);
	m_ListAccessAgents.InsertColumn(0, APL_T("Имя"),LVCFMT_LEFT,rect.Width()*6/20);
	m_ListAccessAgents.InsertColumn(1, APL_T("Тип доступа"),LVCFMT_LEFT,rect.Width()*13/20);

	HWND hWnd = ::GetDlgItem(m_hWnd, IDC_LIST_ACCESS_AGENTS);
	ListView_SetExtendedListViewStyle(hWnd, 
		ListView_GetExtendedListViewStyle(hWnd) | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);

	int i = 0,j = 0;
	
	// Значение для активного итема
	aplAccessList *list = 0;
	CaplAggr aggr;
	CaplInstance *inst_user = 0,*inst_group = 0;
	CaplMap map_user2group;

	// убираем из таблицы дубликатов юзеров
	for(i = 0;i<m_main_table->GetSize();i++)
	{
		list=m_main_table->GetAt(i);
		for(j = 0;j<m_main_table->GetSize();j++)
		{
			if(m_main_table->GetAt(j)!=list)
			{
				if(m_main_table->GetAt(j)->user==list->user)
				{
					m_main_table->RemoveAtWithDel(j);
					j--;
				}
			}
		}
	}

	//Заносим в массив группы юзеров, у которых есть доступ к изучаемому объекту
	for(i = 0;i<m_dlg_select.m_ext_workgroup.GetSize();i++)
	{
		inst_group=m_dlg_select.m_ext_workgroup[i]; 
		if(inst_group->GetId()==DEFAILT_ID_ADMIN_GROUP)continue;
		list=m_main_table->Find(inst_group);
		if(list== 0)continue;
		// Проверка 
		if(list->IsSetAccess()){
			// Может, где-то в недрах спрятан ненулевой доступ
			m_list_groupe.Add(list);
			if(m_edit_access_pattern){
				m_IndAccess = true;
			}
		}
	}

	// Определяем юзеров c наличием доступа
	for(i = 0;i<m_dlg_select.m_ext_user.GetSize();i++)
	{
		// Определяем параметры юзера
		inst_user=m_dlg_select.m_ext_user[i];
		if(inst_user->GetId()==DEFAILT_ID_ADMIN_USER)continue;
		list=m_main_table->Find(inst_user);
		if(list== 0)continue;
		// Проверка 
		if(list->IsSetAccess()){
			// Может, где-то в недрах спрятан ненулевой доступ
			m_list_users.Add(list);
			if(m_edit_access_pattern){
				m_IndAccess = true;
			}
		}
	}
	// Устанавливаем активного пользователя (группу) если есть такой
}//void CDlgSetInstAccess::PreparationData(){


///////// Заполняем список пользователей и групп
void CDlgSetInstAccess::CreateList()
{
	aplAccessList* active_list = 0;
	int curr_selected = m_ListAccessAgents.GetNextItem( -1 , LVNI_ALL | LVNI_SELECTED );
	if(curr_selected!=-1)
	{
		active_list = (aplAccessList*) m_ListAccessAgents.GetItemData(curr_selected);
	}

	m_ListAccessAgents.DeleteAllItems();
	int i = 0;
	aplAccessList *list = 0;
	CString *pbuf = 0;
	CaplInstance *inst = 0;
	CaplStr2InstMap map_group;
	int image;

	// Для занесения надо отсортировать по имени
	for(i = 0;i<m_list_groupe.GetSize();i++)
	{
		pbuf=new CString();
		m_data->GetAplUserName(m_list_groupe[i]->user, *pbuf);
		map_group.Add(pbuf,m_list_groupe[i]->user);
	}
	map_group.SortStr();
	
	//Заносим в таблицу
	int pos = 0;
	for(i = 0;i<map_group.Size;i++)
	{
		inst=map_group.GetInstByIndx(i);  
		if(inst->GetId()==DEFAILT_ID_ADMIN_GROUP)continue;
		pbuf=map_group.GetStrByIndx(i);
		if(inst->GetId()==2){
			image=ICON_CUR_GROUPE;
		}else{
			image=ICON_GROUPE;
		}
		m_ListAccessAgents.InsertItem(pos,*pbuf,image);

		list=m_main_table->Find(inst);
		m_ListAccessAgents.SetItemText(pos,1,list->GetText(true));
		m_ListAccessAgents.SetItemData(pos,(DWORD)list);
		if(active_list==list){
			curr_selected=pos;
		}
		pos++;
	}
	// теперь юзеров
	map_group.Clear();
	for(i = 0;i<m_list_users.GetSize();i++)
	{
		pbuf=new CString();
		m_data->GetAplUserName(m_list_users[i]->user, *pbuf);
		map_group.Add(pbuf,m_list_users[i]->user);
	}
	map_group.SortStr();
	
	for(i = 0;i<map_group.Size;i++)
	{
		inst=map_group.GetInstByIndx(i);  
		if(inst->GetId()==DEFAILT_ID_ADMIN_USER)continue;
		pbuf=map_group.GetStrByIndx(i);
		if(inst->GetId()==1){
			image=ICON_CUR_USER;
		}else{
			image=ICON_USER;
		}
		m_ListAccessAgents.InsertItem(pos,*pbuf,image);
		list=m_main_table->Find(inst);
		m_ListAccessAgents.SetItemText(pos,1,list->GetText(true));
		m_ListAccessAgents.SetItemData(pos,(DWORD)list);
		if(active_list==list){
			curr_selected=pos;
		}
		pos++;
	}
	if(curr_selected!=-1){
		m_ListAccessAgents.SetItem(curr_selected  ,0,TVIF_STATE, NULL, 0, LVNI_SELECTED , LVNI_SELECTED ,0);
	}
}


// Определяет значение галочки и самого инд. доступа и их постоянство	
void CDlgSetInstAccess::FillDefAccessVal()
{
	aplAccessList* list = 0;
	aplAccessEl* el = 0;
	BOOL ind_access = true;
	bool f_def_access = false;
	int DefAccessPos=aplOWN;
	list=m_main_table->Find(0);

	f_def_access = false;// пока значение только одно
	m_ind_unk = false;
	CString various_access = _T(""),buf;
	bool used[4];
	// для разных инстансов разные шаблоны
	bool add_unkn_pattern = false;
	int indx;
	int i;
	bool is_new;

	for(i = 0;i<4;i++){used[i] = false;}

	if(list== 0)
	{
		// если записи для доступа по умолчанию нет - считаем что доступ полный
		DefAccessPos=aplOWN;
		ind_access = false;
	}
	else
	{
		if(list->GetSize()== 0)
		{
			DefAccessPos=aplNOT_DEFINED;
			ind_access = false;
		}
		else
		{
			el=list->GetAt(0);
			DefAccessPos=el->access;
			ind_access=el->is_individual?TRUE:FALSE;
		}
		for(i = 0;i<list->GetSize();i++)
		{
			el=list->GetAt(i);
			indx=el->access;
			if(el->pattern != 0)
			{
				m_patterns.Add(el->pattern);
			}
			else
			{
				if(m_patterns.GetSize()>0)add_unkn_pattern = true;
			}
			is_new = false;
			if(!used[indx]){is_new = true;used[indx] = true;}
			if(is_new)
			{
				various_access+=GetNameAccess((aplAccessModeType)el->access,true) + _T(",");
			}
			if(!f_def_access && (DefAccessPos!=el->access))
			{
				// значений доступа по умолчанию несколько
				f_def_access = true;
				list->multy = true;
			}
			if(!m_ind_unk && ind_access!=el->is_individual && !m_edit_access_pattern)
			{
				// значений "учитывать индивидуалов" несколько
				m_ind_unk = true;
				list->multy = true;
			}
		}
	}
	if(f_def_access)
	{
		various_access.Delete(various_access.GetLength()-1);
		m_CmbxDefAccess.AddString( APL_T("Не изменять (") + various_access + _T(")"));
		m_CmbxDefAccess.SetCurSel(aplNOT_DEFINED);// неясно что рисовать
	}
	else
	{
		m_CmbxDefAccess.SetCurSel(DefAccessPos);
	}
	if(m_patterns.GetSize()== 0)
	{
		m_PatternName=PATTERN_NOT_SET;
	}
	else
	{
		various_access = _T("");
		m_new_pattern=m_patterns[0];
		for(i = 0;i<m_patterns.GetSize();i++)
		{
			if(i>0)various_access += _T("; ");
			m_data->GetAttr(m_patterns[i],m_data->m_attr_apl_acc_pat__name,buf);
			various_access+=buf;
		}
		if(m_patterns.GetSize()>1 || add_unkn_pattern)
		{
			m_PatternName=APL_T("Не изменять (") + various_access;
			if(add_unkn_pattern)m_PatternName += CString(_T("; ")) + PATTERN_NOT_SET;
			m_PatternName += _T(")");
		}
		else
		{
			m_PatternName=various_access;
		}

	}
	if(!m_edit_access_pattern)
	{
		// если редактируем шаблоны - то галочка определяется в другом месте
		if(m_ind_unk)
		{
			m_IndAccess = true;// Рисуем галочку
			m_IndAccessCtrl.SetState(true);// на сером фоне
		}
		else
		{
		//	m_IndAccessCtrl.SetCheck(ind_access);
			m_IndAccess=ind_access;
		}
	}
	UpdateData(FALSE);
}

//  изменили доступ по умолчанию
void CDlgSetInstAccess::OnSelchangeDefAccess() 
{
	// TODO: Add your control notification handler code here
	// проверяем, не была ли серой галочка
	CheckIndAccess();
	// отрисовываем новое состояние индивидуалов
	DrawIndAccess();

	int i;
	for(i = 0;i<m_main_table->GetSize();i++)
	{
		if(m_main_table->GetAt(i)->user== 0)
		{
			m_main_table->GetAt(i)->multy = false;
			break;
		}
	}

}

void CDlgSetInstAccess::CheckIndAccess()
{
	if(m_ind_unk)
	{
		// галочка была серой
		m_ind_unk = false;
		m_IndAccess = true;
		m_IndAccessCtrl.SetState(false);// а теперь не серая
		UpdateData(FALSE);
	}
	aplAccessList* list=m_main_table->Find(0);
	aplAccessEl *el;
	int i;
	if(list != 0)
	{
		list->changed = true;
		for(i = 0;i<list->GetSize();i++){
			el=list->GetAt(i);
			if(el== 0)continue;
			el->is_individual = m_IndAccess;
		}
	}
}

/* ЯАИ:  Перенесено в CaplTranslateDialog
//BOOL CDlgSetInstAccess::OnToolTipShow( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
	TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
	UINT nID = pNMHDR->idFrom;

	if (pTTT->uFlags & TTF_IDISHWND){
		nID = ::GetDlgCtrlID((HWND)nID);
// 		CString tooltip_text;
// 		tooltip_text.LoadString(nID);
// 		pTTT->lpszText = _tcsdup(tooltip_text);
		pTTT->lpszText = MAKEINTRESOURCE(nID);
		pTTT->hinst = AfxGetResourceHandle();
		return(true);
	}
	return false;
}*/

void CDlgSetInstAccess::OnButtonAdd() 
{
	// TODO: Add your control notification handler code here
	int i = 0;
	aplAccessList *list = 0;
	CaplInstance* inst;
	if(m_dlg_select.DoModal()==IDOK)
	{
		for(i = 0;i<m_dlg_select.m_ext_out.GetSize();i++)
		{
			inst=m_dlg_select.m_ext_out.GetAt(i);
			list=m_main_table->Find(inst);
			if(list== 0)
			{
				list=new aplAccessList();
				list->user = inst;
				m_main_table->Add(list);
			}		
			if(m_data->IsKindOf(inst,m_data->m_ent_apl_user))
			{
				m_list_users.Add(list);
			}
			else
			{
				m_list_groupe.Add(list);
			}
			SetUserAccess(m_dlg_select.m_res_access,list);
		}
		if(m_ind_unk)
		{
			// галочка была серой
			m_IndAccess = true;
			ProcessIndAccess();
		}
		CreateList();
	}
}

void CDlgSetInstAccess::OnButtonDelete() 
{
	// TODO: Add your control notification handler code here
	TestEdited();
	int num_curr = m_ListAccessAgents.GetNextItem( -1 , LVNI_ALL | LVNI_SELECTED );
	if(num_curr==-1)
	{
		m_list = 0;
	}
	else
	{
		m_list = (aplAccessList*) m_ListAccessAgents.GetItemData(num_curr);
	}
	if(m_list== 0)
	{
		AfxMessageBox( APL_T("Выберите элемент для удаления"));
		return;
	}
	if(m_list->user->GetType()==m_data->m_ent_apl_workgroup)
	{
		m_list_groupe.Remove(m_list_groupe.Find(m_list));
	}
	else
	{
		m_list_users.Remove(m_list_users.Find(m_list));
	}
	SetUserAccess(aplNOT_DEFINED);
	CreateList();
}

void CDlgSetInstAccess::OnAccessAgentChng() 
{
	// TODO: Add your control notification handler code here
	// Текущий юзер (группа юзеров)
	int num_curr = m_ListAccessAgents.GetNextItem( -1 , LVNI_ALL | LVNI_SELECTED );
	if(num_curr==-1){
		m_list = 0;
	}else{
		m_list = (aplAccessList*) m_ListAccessAgents.GetItemData(num_curr);
	}
	if(m_list== 0){
		AfxMessageBox( APL_T("Выберите элемент для изменения"));
		return;
	}
	CRect rect,rectc;
	
	m_ListAccessAgents.GetItemRect(num_curr,rect,LVIR_BOUNDS);
	m_ListAccessAgents.GetClientRect(&rectc);
	if(rectc.right<rect.right)rect.right=rectc.right;
	int col1size=m_ListAccessAgents.GetColumnWidth(0);
	rect.left+=col1size;
	int access = 0;
	if(m_list->GetSize()>0){
		access=m_list->GetAt(0)->access;
	}
	m_CmbxAccess.SetCurSel(access);

	m_CmbxAccess.SetWindowPos(&wndTop,rect.left,rect.top,rect.Width(),rect.Height(),
		SWP_SHOWWINDOW|SWP_NOCOPYBITS);
	m_is_edited = true;
}

void CDlgSetInstAccess::TestEdited()
{
	if(m_is_edited)
	{
		SetUserAccess((aplAccessModeType)m_CmbxAccess.GetCurSel());
		m_CmbxAccess.ShowWindow(SW_HIDE);
		m_is_edited = false;
		if(m_ind_unk)
		{
			// галочка была серой
			m_IndAccess = true;
			ProcessIndAccess();
		}
		CreateList();
	}
}

void CDlgSetInstAccess::OnClickListAccessAgents(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	TestEdited();
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	SetCurrList(pNMListView->ptAction);
	
	*pResult = 0;
}

void CDlgSetInstAccess::OnRclickListAccessAgents(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	TestEdited();
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	ContextMenuProcessed( pNMListView->ptAction);
	*pResult = 0;
}

void CDlgSetInstAccess::OnDblclkListAccessAgents(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	TestEdited();
//	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	OnAccessAgentChng();
	*pResult = 0;
}

void CDlgSetInstAccess::SetCurrList( CPoint point)
{
    UINT flag=TVHT_ONITEM|TVHT_ONITEMRIGHT;
    int cur_item=m_ListAccessAgents.HitTest(point,&flag);
	if(cur_item==-1){
		m_list = 0;
	}else{
		m_list=(aplAccessList*)m_ListAccessAgents.GetItemData(cur_item);
	}
	EnableButtons();
}

void CDlgSetInstAccess::ContextMenuProcessed( CPoint point)
{

	SetCurrList(point);
	CaplMenu up_menu;
	up_menu.LoadMenu(IDR_CONTEXT_MENU);
    CMenu* pPopup = up_menu.GetSubMenu(0);
	pPopup->SetDefaultItem(ID_ACCESS_AGENT_CHNG);
	
	if(m_list== 0 || m_only_RO)
	{
		pPopup->EnableMenuItem(ID_ACCESS_AGENT_CHNG, MF_BYCOMMAND | MF_GRAYED);
		pPopup->EnableMenuItem(ID_ACCESS_AGENT_DEL, MF_BYCOMMAND | MF_GRAYED);
	}
	if(m_only_RO){
		pPopup->EnableMenuItem(ID_ACCESS_AGENT_ADD, MF_BYCOMMAND | MF_GRAYED);
	}
	m_ListAccessAgents.ClientToScreen(&point);
	int res = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON ,
		point.x, point.y, this);
	
}

void CDlgSetInstAccess::MoveCtrl(CWnd &wnd,int cx, int cy,bool isMove)
{
	CRect rect;
	if(wnd.m_hWnd== 0)return;
	wnd.GetWindowRect(rect);
	ScreenToClient(rect);
	rect.bottom+=cy;
	rect.right+=cx;
	if(isMove){
		rect.left+=cx;
		rect.top+=cy;
	}
	wnd.MoveWindow(rect);
}


void CDlgSetInstAccess::OnBnClickedSelectPattern()
{
	// TODO: Add your control notification handler code here
	CDlgAccessPatterns dlg;
	CString buf;
	dlg.m_data=m_data;
	if(m_patterns.GetSize()==1){dlg.m_curr_pattern=m_patterns[0];}
	dlg.m_mode = _T("select_t");
	dlg.m_curr_pattern=m_new_pattern;
	dlg.m_RO=m_only_RO;
	if(dlg.DoModal()==IDOK)
	{
		m_new_pattern=dlg.m_curr_pattern;

		if(m_new_pattern== 0 && m_patterns.GetSize()>0){m_pattern_changed = true;}
		if(m_new_pattern != 0 && (m_patterns.GetSize()== 0 || m_patterns.GetSize()>1)){m_pattern_changed = true;}
		if(m_new_pattern != 0 && m_patterns.GetSize()==1 && m_new_pattern!=m_patterns[0]){m_pattern_changed = true;}

		if(m_new_pattern== 0)
		{
			buf=PATTERN_NOT_SET;
		}
		else
		{
			m_data->GetAttr(m_new_pattern,m_data->m_attr_apl_acc_pat__name,buf);
		}
		m_EdtPat.SetWindowText(buf);
		m_patterns.Clear();
	}
}


