// aplMultilineStringDlg.cpp : implementation file
//

#include "stdafx.h"
#include "apl_gui.h"
#include "aplMultilineStringDlg.h"


// CaplMultilineStringDlg dialog

IMPLEMENT_DYNAMIC(CaplMultilineStringDlg, CaplResizableDialog)

CaplMultilineStringDlg::CaplMultilineStringDlg(LPCTSTR lpTitle /*= NULL*/, LPCTSTR lpFullString /*= NULL*/, LPAplMakeStrFunction lpStrFun /*= NULL*/, LPCTSTR lpDelimeters /*= NULL*/, CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CaplMultilineStringDlg::IDD, pParent)
	, m_pStrFunction(lpStrFun)
	, m_sTitle(_T(""))
	, m_sDelimeters(_T(","))
	, m_sFullString(_T(""))
{
	if (lpTitle)
		m_sTitle = lpTitle;

	if (lpFullString)
		m_sFullString = lpFullString;

	if (lpDelimeters)
		m_sDelimeters = lpDelimeters;

	if (m_sDelimeters.IsEmpty())
		m_sDelimeters = _T(",");
}

CaplMultilineStringDlg::~CaplMultilineStringDlg()
{
}

void CaplMultilineStringDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_ADD_BTN, m_add_btn);
	DDX_Control(pDX, IDC_DELETE_BTN, m_delete_btn);
	DDX_Control(pDX, IDC_UP_BTN, m_up_btn);
	DDX_Control(pDX, IDC_DOWN_BTN, m_down_btn);
	DDX_Control(pDX, IDC_STR_LIST, m_str_list_ctrl);
	DDX_Control(pDX, IDOK, m_ok_btn);
	DDX_Control(pDX, IDCANCEL, m_cancel_btn);
}


BEGIN_MESSAGE_MAP(CaplMultilineStringDlg, CaplResizableDialog)
	ON_STARTEDIT(IDC_STR_LIST, OnStartUserEditStrList)
	ON_NOTIFY(NM_CLICK, IDC_STR_LIST, &CaplMultilineStringDlg::OnNMClickStrList)
	ON_BN_CLICKED(IDC_ADD_BTN, &CaplMultilineStringDlg::OnBnClickedAddBtn)
	ON_BN_CLICKED(IDC_DELETE_BTN, &CaplMultilineStringDlg::OnBnClickedDeleteBtn)
	ON_BN_CLICKED(IDC_UP_BTN, &CaplMultilineStringDlg::OnBnClickedUpBtn)
	ON_BN_CLICKED(IDC_DOWN_BTN, &CaplMultilineStringDlg::OnBnClickedDownBtn)
END_MESSAGE_MAP()


// CaplMultilineStringDlg message handlers

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

	// TODO:  Add extra initialization here

	// заголовок
	SetWindowText(m_sTitle);

	// анчоры
	AddAnchor(IDC_ADD_BTN, TOP_RIGHT);
	AddAnchor(IDC_DELETE_BTN, TOP_RIGHT);
	AddAnchor(IDC_UP_BTN, TOP_RIGHT);
	AddAnchor(IDC_DOWN_BTN, TOP_RIGHT);
	AddAnchor(IDC_STR_LIST, TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDOK, BOTTOM_RIGHT);
	AddAnchor(IDCANCEL, BOTTOM_RIGHT);

	// кнопки
	m_add_btn.SetIcon(aplGetButtonIco(APL_24_PLUS));
	m_add_btn.SetFlat(TRUE);
	m_add_btn.SetWindowText(_T(""));
	m_add_btn.SetTooltipText( APL_T("Добавить строку"));

	m_delete_btn.SetIcon(aplGetButtonIco(APL_24_DELETE));
	m_delete_btn.SetFlat(TRUE);
	m_delete_btn.SetWindowText(_T(""));
	m_delete_btn.SetTooltipText( APL_T("Удалить строку"));

	m_up_btn.SetIcon(aplGetButtonIco(APL_24_UP));
	m_up_btn.SetFlat(TRUE);
	m_up_btn.SetWindowText(_T(""));
	m_up_btn.SetTooltipText( APL_T("Переместить вверх"));

	m_down_btn.SetIcon(aplGetButtonIco(APL_24_DOWN));
	m_down_btn.SetFlat(TRUE);
	m_down_btn.SetWindowText(_T(""));
	m_down_btn.SetTooltipText( APL_T("Переместить вниз"));

	m_ok_btn.SetIcon(aplGetButtonIco(APL_24_OK));
	m_ok_btn.SetFlat(FALSE);

	m_cancel_btn.SetIcon(aplGetButtonIco(APL_24_CANCEL));
	m_cancel_btn.SetFlat(FALSE);

	m_delete_btn.EnableWindow(FALSE);
	m_up_btn.EnableWindow(FALSE);
	m_down_btn.EnableWindow(FALSE);

	// инициализация списка
	CRect rect;
	m_str_list_ctrl.GetClientRect(&rect);
	rect.right-=::GetSystemMetrics(SM_CXVSCROLL)+1;

	if (m_pStrFunction)
	{
		m_str_list_ctrl.InsertColumn(0, _T(""), LVCFMT_LEFT, (int)(rect.Width()*0.9));
		m_str_list_ctrl.InsertColumn(1, _T(""), LVCFMT_LEFT, (int)(rect.Width()*0.1));
	}
	else
	{
		m_str_list_ctrl.InsertColumn(0, _T(""), LVCFMT_LEFT, (int)(rect.Width()));
	}

	// парсим строку
	ParseFullString();

	UpdateData(FALSE);

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

void CaplMultilineStringDlg::OnStartUserEditStrList(NMHDR* pNMHDR, LRESULT* pResult)
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	if(pNMListView->iSubItem>0)
	{
		// вызываем callback-функцию
		if (m_pStrFunction)
		{
			CString sResult = m_pStrFunction(m_str_list_ctrl.GetItemText(pNMListView->iItem, 0));
			m_str_list_ctrl.SetItemText(pNMListView->iItem, 0, sResult);
		}
	}

	*pResult = 0;
}

void CaplMultilineStringDlg::UpdateFullString()
{
	m_sFullString.Empty();

	CString sCurStr;
	for(int i=0; i<m_str_list_ctrl.GetItemCount(); ++i)
	{
		sCurStr = m_str_list_ctrl.GetItemText(i, 0);
		if (!sCurStr.IsEmpty())
		{
			if (!m_sFullString.IsEmpty())
				m_sFullString += m_sDelimeters[0];
			m_sFullString += sCurStr;
		}
	}
}

void CaplMultilineStringDlg::ParseFullString()
{
	m_str_list_ctrl.DeleteAllItems();

	int i=0;
	CString sCurStr = m_sFullString.Tokenize(m_sDelimeters, i);
	while(!sCurStr.IsEmpty())
	{
		int ind = m_str_list_ctrl.InsertItem(m_str_list_ctrl.GetItemCount(), sCurStr);
		if (ind>-1)
		{
			m_str_list_ctrl.SetItemEditType(ind, 0, aplTextCtrl);
			if (m_pStrFunction)
			{
				m_str_list_ctrl.SetItemText(ind, 1, _T("..."));
				m_str_list_ctrl.SetItemEditType(ind, 1, aplUser);
			}
		}
		sCurStr = m_sFullString.Tokenize(m_sDelimeters, i);
	}
}
void CaplMultilineStringDlg::OnNMClickStrList(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: Add your control notification handler code here
	m_delete_btn.EnableWindow((pNMItemActivate->iItem>-1)?TRUE:FALSE);
	unsigned int nSelected = m_str_list_ctrl.GetSelectedCount();
	m_up_btn.EnableWindow((nSelected==1&&pNMItemActivate->iItem>0)?TRUE:FALSE);
	m_down_btn.EnableWindow((nSelected==1&&pNMItemActivate->iItem<(m_str_list_ctrl.GetItemCount()-1))?TRUE:FALSE);
	*pResult = 0;
}

void CaplMultilineStringDlg::OnBnClickedAddBtn()
{
	// TODO: Add your control notification handler code here
	int ind = m_str_list_ctrl.InsertItem(m_str_list_ctrl.GetItemCount(), _T(""));
	if (ind>-1)
	{
		m_str_list_ctrl.SetItemEditType(ind, 0, aplTextCtrl);
		if (m_pStrFunction)
		{
			m_str_list_ctrl.SetItemText(ind, 1, _T("..."));
			m_str_list_ctrl.SetItemEditType(ind, 1, aplUser);
		}

		m_str_list_ctrl.StartEdit(ind, 0);
	}
}

void CaplMultilineStringDlg::OnBnClickedDeleteBtn()
{
	// TODO: Add your control notification handler code here
	int cur = m_str_list_ctrl.GetNextItem(-1, LVNI_SELECTED);
	while(cur>-1)
	{
		m_str_list_ctrl.DeleteItem(cur--);
		cur = m_str_list_ctrl.GetNextItem(cur, LVNI_SELECTED);
	}
}

void CaplMultilineStringDlg::OnBnClickedUpBtn()
{
	// TODO: Add your control notification handler code here
	int cur = m_str_list_ctrl.GetNextItem(-1, LVNI_SELECTED);
	if (cur>0)
	{
		CString sPrev = m_str_list_ctrl.GetItemText(cur-1, 0);
		m_str_list_ctrl.SetItemText(cur-1, 0, m_str_list_ctrl.GetItemText(cur, 0));
		m_str_list_ctrl.SetItemText(cur, 0, sPrev);
	}
}

void CaplMultilineStringDlg::OnBnClickedDownBtn()
{
	// TODO: Add your control notification handler code here
	int cur = m_str_list_ctrl.GetNextItem(-1, LVNI_SELECTED);
	if (cur<(m_str_list_ctrl.GetItemCount()-1))
	{
		CString sNext = m_str_list_ctrl.GetItemText(cur+1, 0);
		m_str_list_ctrl.SetItemText(cur+1, 0, m_str_list_ctrl.GetItemText(cur, 0));
		m_str_list_ctrl.SetItemText(cur, 0, sNext);
	}
}

void CaplMultilineStringDlg::OnOK()
{
	// TODO: Add your specialized code here and/or call the base class
	m_str_list_ctrl.EndEdit();

	UpdateData();

	UpdateFullString();

	CaplResizableDialog::OnOK();
}
