// DlgSelectEntityAttrs.cpp : implementation file
//

#include "stdafx.h"
#include "aplNetStepData.h"
#include "DlgSelectEntityAttrs.h"
#include "DlgQlLang.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDlgSelectEntityAttrs dialog


CDlgSelectEntityAttrs::CDlgSelectEntityAttrs(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CDlgSelectEntityAttrs::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgSelectEntityAttrs)
	m_FindWord = _T("");
	m_Radio1 = 0;
	m_Radio2 = -1;
	m_FilterEntity = _T("");
	m_FilterAttrib = _T("");
	//}}AFX_DATA_INIT
	m_data = 0;
	m_string = _T("");
	m_parent = 0;
	m_prev_ent = true;
	m_selected_ent = 0;
}

CDlgSelectEntityAttrs::~CDlgSelectEntityAttrs()
{
	ClearMap();
}

void CDlgSelectEntityAttrs::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgSelectEntityAttrs)
	DDX_Control(pDX, IDC_STATIC_GROUP, m_StGroup);
	DDX_Control(pDX, IDC_LIST_ATTRS, m_ListAttrs);
	DDX_Control(pDX, IDC_LIST_ENTITIES, m_ListEntities);
	DDX_Text(pDX, IDC_EDIT_PARENT_SELECTION, m_FindWord);
	DDX_Radio(pDX, IDC_RADIO1, m_Radio1);
	DDX_Radio(pDX, IDC_RADIO2, m_Radio2);
	//}}AFX_DATA_MAP
	DDX_Text(pDX, IDC_EDIT_FILTER_ENTITY, m_FilterEntity);
	DDX_Text(pDX, IDC_EDIT_FILTER_ATTRIB, m_FilterAttrib);
}


BEGIN_MESSAGE_MAP(CDlgSelectEntityAttrs, CaplResizableDialog)
	//{{AFX_MSG_MAP(CDlgSelectEntityAttrs)
	ON_BN_CLICKED(IDC_PASTE_ENTITY_NAME, OnPasteEntityName)
	ON_BN_CLICKED(IDC_PASTE_ATTR_NAME, OnPasteAttrName)
	ON_BN_CLICKED(IDC_PASTE_ENTITY_DOT_ATTR, OnPasteEntityDotAttr)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_ENTITIES, OnItemchangedListEntities)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_ATTRS, OnItemchangedListAttrs)
	ON_BN_CLICKED(IDC_RADIO1, OnRadio)
	ON_EN_CHANGE(IDC_EDIT_PARENT_SELECTION, OnChangeEditParentSelection)
	ON_BN_CLICKED(IDC_RADIO2, OnRadio)
	ON_EN_SETFOCUS(IDC_EDIT_PARENT_SELECTION, OnChangeEditParentSelection)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST_ENTITIES, OnDblclkListEntities)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST_ATTRS, OnDblclkListAttrs)
	//}}AFX_MSG_MAP
	ON_EN_CHANGE(IDC_EDIT_FILTER_ENTITY, &CDlgSelectEntityAttrs::OnEnChangeEditFilterEntity)
	ON_EN_CHANGE(IDC_EDIT_FILTER_ATTRIB, &CDlgSelectEntityAttrs::OnEnChangeEditFilterAttrib)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgSelectEntityAttrs message handlers


void CDlgSelectEntityAttrs::StartDialog()
{
	if(m_hWnd== 0){
		Create(IDD_DLG_SELECT_ENTITY_ATTRS,m_parent);
	}
	CPoint point;
	CRect rect;
	int len_x,len_y;
	GetCursorPos(&point);
	GetWindowRect(&rect);

	len_x=rect.right-rect.left;
	len_y=rect.bottom-rect.top;

	rect.left=point.x;
	rect.right=point.x+len_x;
	rect.top=point.y;
	rect.bottom=point.y+len_y;

	MoveWindow(&rect);

	ShowWindow(SW_SHOW);
	SetForegroundWindow();

	m_parent->GetSel(m_FindWord);
	UpdateData(FALSE);
	MakeList();
}


BOOL CDlgSelectEntityAttrs::OnInitDialog() 
{
	CaplResizableDialog::OnInitDialog();

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

	if(m_data== 0)return TRUE;
// 	if(m_parent != 0){
// 		ModifyStyleEx(0,WS_EX_TOOLWINDOW);
// 		UpdateWindow();
// 	}
	// предотвращаем потерю модальности после диалога с бочками из aplSocketTransport
	CORRECT_LOOSE_MODAL_ON_CLASS(m_data);


	AddAnchor(IDC_STATIC1,TOP_LEFT,TOP_CENTER);
	AddAnchor(IDC_LIST_ENTITIES,TOP_LEFT,BOTTOM_CENTER);
	AddAnchor(IDC_STATIC2,TOP_CENTER,TOP_RIGHT);
	AddAnchor(IDC_LIST_ATTRS,TOP_CENTER,BOTTOM_RIGHT);
	AddAnchor(IDC_STATIC3,TOP_RIGHT);
	AddAnchor(IDC_STATIC_GROUP,TOP_RIGHT);
	AddAnchor(IDC_EDIT_PARENT_SELECTION,TOP_RIGHT);
	AddAnchor(IDC_RADIO1,TOP_RIGHT);
	AddAnchor(IDC_RADIO2,TOP_RIGHT);
	AddAnchor(IDC_PASTE_ENTITY_NAME,TOP_RIGHT);
	AddAnchor(IDC_PASTE_ENTITY_DOT_ATTR,TOP_RIGHT);
	AddAnchor(IDC_PASTE_ATTR_NAME,TOP_RIGHT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);

	CRect rect;
	m_ListEntities.GetWindowRect(rect);
	m_ListEntities.InsertColumn(0,_T(""),LVCFMT_LEFT,rect.Width()-1);
	m_ListAttrs.GetWindowRect(rect);
	m_ListAttrs.InsertColumn(0,_T(""),LVCFMT_LEFT,rect.Width()-1,2);
	
	HWND hWnd;
	hWnd = ::GetDlgItem(m_hWnd, IDC_LIST_ENTITIES);
	ListView_SetExtendedListViewStyle(hWnd,ListView_GetExtendedListViewStyle(hWnd) | LVS_EX_FULLROWSELECT /*| LVS_EX_GRIDLINES */);
	hWnd = ::GetDlgItem(m_hWnd, IDC_LIST_ATTRS);
	ListView_SetExtendedListViewStyle(hWnd,ListView_GetExtendedListViewStyle(hWnd) | LVS_EX_FULLROWSELECT /*| LVS_EX_GRIDLINES */);

	// TODO: Add extra initialization here
	MakeList();

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
void CDlgSelectEntityAttrs::ClearMap()
{
	int i;
	CStringArray *str_arr;
	for(i = 0;i<m_attr_map.GetSize();i++)
	{
		str_arr=(CStringArray *)m_attr_map.GetAt(i)->val;
		delete str_arr;
	}
	m_attr_map.Clear();
}

void CDlgSelectEntityAttrs::MakeList()
{
	CaplEntity* ent;
	CaplAttr* attr;
	int i,j,indx;
	CUIntArray *int_arr;
	CString name;
	int selected=-1;
	bool added;

	m_selected_ent = 0;

	UpdateData(TRUE);

	SetRedraw(FALSE);

	if(m_Radio1== 0){
		if(m_ent_map.GetSize()== 0){
			for(i = 0;i<m_data->entities.GetSize();i++){
				ent=m_data->entities.GetAt(i);
				name=ent->name;
				m_ent_map.Add(name,(long)ent);
			}
			m_ent_map.Sort();
			m_prev_ent = false;
		}
		if(!m_prev_ent){
			m_ListAttrs.DeleteAllItems();
			m_ListEntities.DeleteAllItems();
			for(i = 0;i<m_ent_map.GetSize();i++)
			{
				name=m_ent_map.GetAt(i)->str;
				ent=(CaplEntity*)m_ent_map.GetAt(i)->val;
				indx=m_ListEntities.InsertItem(i,name);
				m_ListEntities.SetItemData(indx,(DWORD)ent);
			}
		}
		name=m_FindWord;
		while(selected==-1 && name.GetLength()>0){
			//selected=m_ent_map.Find(name);
			for(i = 0;i<m_ent_map.GetSize();i++)
			{
				if(m_ent_map.GetAt(i)->str.Left(name.GetLength())==name){
					selected=i;break;
				}
			}
			name.Delete(name.GetLength()-1);
		}
		if(selected!=-1){
			m_ListEntities.SetItemState(selected,LVNI_ALL| LVNI_SELECTED ,LVNI_ALL| LVNI_SELECTED/* NULL*/);
			m_ListEntities.EnsureVisible(selected,1);
		}

	}else{
		if(m_attr_map.GetSize()== 0){
			for(i = 0;i<m_data->entities.GetSize();i++){
				ent=m_data->entities.GetAt(i);
				for(j = 0;j<ent->all_attrs.GetSize();j++){
					attr=ent->all_attrs.GetAt(j);
					name=attr->name;
					int_arr=(CUIntArray *)m_attr_map.GetP(name);
					added = false;
					if(int_arr== 0){
						int_arr=new CUIntArray();
						m_attr_map.Add(name,(long)int_arr);
						added = true;
					}
					int_arr->Add((int)ent->id);
					if(added)m_attr_map.Sort();
				}
			}
			m_prev_ent = true;
		}
		if(m_prev_ent){
			m_ListAttrs.DeleteAllItems();
			m_ListEntities.DeleteAllItems();
			for(i = 0;i<m_attr_map.GetSize();i++)
			{
				name=m_attr_map.GetAt(i)->str;
				indx=m_ListAttrs.InsertItem(i,name);
				m_ListAttrs.SetItemData(indx,(DWORD)m_attr_map.GetAt(i)->val);
			}
		}
		name=m_FindWord;
		while(selected==-1 && name.GetLength()>0){
			//selected=m_attr_map.Find(name);
			for(i = 0;i<m_attr_map.GetSize();i++)
			{
				if(m_attr_map.GetAt(i)->str.Left(name.GetLength())==name){
					selected=i;break;
				}
			}
			name.Delete(name.GetLength()-1);
		}
		if(selected!=-1){
			m_ListAttrs.SetItemState(selected,LVNI_ALL| LVNI_SELECTED ,LVNI_ALL| LVNI_SELECTED/* NULL*/);
			m_ListAttrs.EnsureVisible(selected,1);
		}

	}
	m_prev_ent=m_Radio1== 0;

	SetRedraw(TRUE);
	Invalidate();
}

void CDlgSelectEntityAttrs::MakeListEnt()
{
	CaplEntity* ent;
	int i,indx;
	CString name;
	int selected=-1;
	UpdateData(TRUE);

	SetRedraw(FALSE);

	if(m_ent_map.GetSize()== 0){
		for(i = 0;i<m_data->entities.GetSize();i++){
			ent=m_data->entities.GetAt(i);
			name=ent->name;
			m_ent_map.Add(name,(long)ent);
		}
		m_ent_map.Sort();
		m_prev_ent = false;
	}
	m_ListAttrs.DeleteAllItems();
	m_ListEntities.DeleteAllItems();
	for(i = 0;i<m_ent_map.GetSize();i++)
	{
		name=m_ent_map.GetAt(i)->str;
		if(m_FilterEntity != _T(""))
		{
			if(name.Find(m_FilterEntity)==-1)
			{
				continue;
			}
		}
		ent=(CaplEntity*)m_ent_map.GetAt(i)->val;
		indx=m_ListEntities.InsertItem(i,name);
		m_ListEntities.SetItemData(indx,(DWORD)ent);
	}

	m_prev_ent=m_Radio1== 0;

	SetRedraw(TRUE);
	Invalidate();
}

void CDlgSelectEntityAttrs::MakeListAttrs()
{
	int i,indx;
	CString name;
	CaplAttr *attr;
	int selected=-1;
	UpdateData(TRUE);

	SetRedraw(FALSE);

	m_ListAttrs.DeleteAllItems();
	if(m_selected_ent != 0)
	{
		for(i = 0;i<m_selected_ent->all_attrs.GetSize();i++)
		{
			attr=m_selected_ent->all_attrs.GetAt(i);
			name=attr->name;
			if(m_FilterAttrib != _T(""))
			{
				if(name.Find(m_FilterAttrib)==-1)
				{
					continue;
				}
			}
			indx=m_ListAttrs.InsertItem(i,name);
			m_ListAttrs.SetItemData(indx,(DWORD)attr);
		}
	}

	m_prev_ent=m_Radio1== 0;

	SetRedraw(TRUE);
	Invalidate();
}

void CDlgSelectEntityAttrs::OnItemchangedListEntities(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	
	*pResult = 0;

	if(m_data== 0)return;
	UpdateData(TRUE);
	m_FilterAttrib.Empty();
	UpdateData(FALSE);

	CaplEntity* ent;
	CaplAttr* attr;
	int i,indx;
	CString name;

	if(m_Radio1== 0){
		m_ListAttrs.DeleteAllItems();
		indx=m_ListEntities.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
		if(indx==-1)return;
		
		ent=(CaplEntity*)m_ListEntities.GetItemData(indx);
		if(ent== 0)return;
		m_selected_ent=ent;
		for(i = 0;i<ent->all_attrs.GetSize();i++){
			attr=ent->all_attrs.GetAt(i);
			name=attr->name;
			indx=m_ListAttrs.InsertItem(i,name);
			m_ListAttrs.SetItemData(indx,(DWORD)attr);
		}
	}
}

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

	*pResult = 0;

	if(m_data== 0)return;
	int i,indx;
	CaplEntity *ent;
	CUIntArray *int_arr;
	
	if(m_Radio2== 0){
		m_ListEntities.DeleteAllItems();
		indx=m_ListAttrs.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
		if(indx==-1)return;
		
		m_selected_ent = 0;
		int_arr=(CUIntArray*)m_ListAttrs.GetItemData(indx);
		if(int_arr== 0)return;
		for(i = 0;i<int_arr->GetSize();i++){
			ent=m_data->GetEntityById(int_arr->GetAt(i));
			if(ent== 0)continue;
			indx=m_ListEntities.InsertItem(i,ent->name);
		}
	}
}

void CDlgSelectEntityAttrs::OnCancel() 
{
	// TODO: Add extra cleanup here
	CaplResizableDialog::OnCancel();
}


void CDlgSelectEntityAttrs::OnPasteEntityName() 
{
	// TODO: Add your control notification handler code here
	int indx;
	indx=m_ListEntities.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
	if(indx==-1){
		m_string.Empty();
	}else{
		m_string=m_ListEntities.GetItemText(indx,0);
	}

	if(m_parent== 0){
		EndDialog(IDC_PASTE_ENTITY_NAME);
	}else{
		m_parent->ReplaceSel(m_string);
	}
}

void CDlgSelectEntityAttrs::OnPasteAttrName() 
{
	// TODO: Add your control notification handler code here
	int indx;
	indx=m_ListAttrs.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
	if(indx==-1){
		m_string.Empty();
	}else{
		m_string=m_ListAttrs.GetItemText(indx,0);
	}

	if(m_parent== 0){
		EndDialog(IDC_PASTE_ATTR_NAME);
	}else{
		m_parent->ReplaceSel(m_string);
	}
}

void CDlgSelectEntityAttrs::OnPasteEntityDotAttr() 
{
	// TODO: Add your control notification handler code here
	int indx;
	CString ent_name,attr_name;
	indx=m_ListEntities.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
	if(indx==-1){
		ent_name.Empty();
	}else{
		ent_name=m_ListEntities.GetItemText(indx,0);
	}
	indx=m_ListAttrs.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
	if(indx==-1){
		attr_name.Empty();
	}else{
		attr_name=m_ListAttrs.GetItemText(indx,0);
	}

	m_string=ent_name + _T(".") + attr_name;
	if(m_parent== 0)
	{
		EndDialog(IDC_PASTE_ENTITY_DOT_ATTR);
	}
	else
	{
		m_parent->ReplaceSel(m_string);
	}
	
}

void CDlgSelectEntityAttrs::OnRadio() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_Radio1== 0)
	{
		m_Radio1=-1;
		m_Radio2 = 0;
	}
	else
	{
		m_Radio1 = 0;
		m_Radio2=-1;
	}
	UpdateData(FALSE);
	MakeList();
}


void CDlgSelectEntityAttrs::OnChangeEditParentSelection() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CaplResizableDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	MakeList();
}

void CDlgSelectEntityAttrs::OnDblclkListEntities(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	int indx;
	indx=m_ListEntities.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
	if(indx!=-1){
		m_FindWord=m_ListEntities.GetItemText(indx,0);
		UpdateData(FALSE);
	}
	*pResult = 0;
}

void CDlgSelectEntityAttrs::OnDblclkListAttrs(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	int indx;
	indx=m_ListAttrs.GetNextItem( -1 , LVNI_ALL| LVNI_SELECTED );
	if(indx!=-1){
		m_FindWord=m_ListAttrs.GetItemText(indx,0);
		UpdateData(FALSE);
	}
	*pResult = 0;
}

void CDlgSelectEntityAttrs::OnEnChangeEditFilterEntity()
{
	// TODO:  If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CaplResizableDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO:  Add your control notification handler code here
	UpdateData(TRUE);
	m_FindWord.Empty();
	UpdateData(FALSE);

	MakeListEnt();
}

void CDlgSelectEntityAttrs::OnEnChangeEditFilterAttrib()
{
	// TODO:  If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CaplResizableDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO:  Add your control notification handler code here
	UpdateData(TRUE);
	m_FindWord.Empty();
	UpdateData(FALSE);

	MakeListAttrs();
}
