// ChooseCharacteristicsDlg.cpp : implementation file
//

#include "stdafx.h"
//#include "psm.h"
#include "ChooseCharacteristicsDlg.h"

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



bool AFX_EXT_API DoChooseCharacteristicsDlg(CStringArray *columns,
	CaplTAggr<CStringArray*,CStringArray*,APLAGGR_AUTOKILLREF|APLAGGR_LIST> *items,
	CUIntArray *mask,CString dialog_name,CString left_name,CString right_name)
{
	int res;
	if(columns==0 ||items==0)return false;
	CaplSetResourceHandle setres(module_inst);
	
	CChooseCharacteristicsDlg dlg;
	dlg.m_Columns=columns;
	dlg.m_Items=items;
	dlg.m_Mask=mask;
	if(dialog_name!=_T(""))dlg.m_dialog_name=dialog_name;
	if(left_name!=_T(""))dlg.m_left_name=left_name;
	if(right_name!=_T(""))dlg.m_right_name=right_name;
	res=dlg.DoModal();
	if(res==IDOK)return true;
	return false;
}
/////////////////////////////////////////////////////////////////////////////
// CChooseCharacteristicsDlg dialog


CChooseCharacteristicsDlg::CChooseCharacteristicsDlg(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CChooseCharacteristicsDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChooseCharacteristicsDlg)
	m_left_name =  APL_T("Отображаемые характеристики");
	m_right_name =  APL_T("Неотображаемые характеристики");
	//}}AFX_DATA_INIT
	m_dialog_name= APL_T("Выбор характеристик");
}


void CChooseCharacteristicsDlg::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChooseCharacteristicsDlg)
	DDX_Control(pDX, IDOK, m_BtnOk);
	DDX_Control(pDX, IDCANCEL, m_BtnCancel);
	DDX_Control(pDX, IDC_TOP, m_BtnTop);
	DDX_Control(pDX, IDC_ONE_RIGHT, m_BtnOneRight);
	DDX_Control(pDX, IDC_ONE_LEFT, m_BtnOneLeft);
	DDX_Control(pDX, IDC_BOTTOM, m_BtnBottom);
	DDX_Control(pDX, IDC_ALL_RIGHT, m_BtnAllRight);
	DDX_Control(pDX, IDC_ALL_LEFT, m_BtnAllLeft);
	DDX_Control(pDX, ID_SAVE_CHARACT_LIST, m_BtnSaveChar);
	DDX_Control(pDX, ID_LOAD_CHARACT_LIST, m_BtnLoadChar);
	DDX_Text(pDX, IDC_STATIC_LEFT_NAME, m_left_name);
	DDX_Text(pDX, IDC_STATIC_RIGHT_NAME, m_right_name);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChooseCharacteristicsDlg, CResizableDialog)
	//{{AFX_MSG_MAP(CChooseCharacteristicsDlg)
	ON_BN_CLICKED(IDC_ALL_LEFT, OnAllLeft)
	ON_BN_CLICKED(IDC_ONE_LEFT, OnOneLeft)
	ON_BN_CLICKED(IDC_ALL_RIGHT, OnAllRight)
	ON_BN_CLICKED(IDC_ONE_RIGHT, OnOneRight)
	ON_BN_CLICKED(IDC_TOP, OnTop)
	ON_BN_CLICKED(IDC_BOTTOM, OnBottom)
	ON_BN_CLICKED(ID_SAVE_CHARACT_LIST, OnSaveCharactList)
	ON_BN_CLICKED(ID_LOAD_CHARACT_LIST, OnLoadCharactList)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChooseCharacteristicsDlg message handlers

BOOL CChooseCharacteristicsDlg::OnInitDialog() 
{
	int i,j,size;
	bool is_left;
	if(m_Columns==0)return FALSE;
	CResizableDialog::OnInitDialog();
	
	ModifyStyleEx(0, WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT);   
	ModifyStyle(0, WS_MAXIMIZEBOX);   

	m_invisible_charact.CreateFromStatic(IDC_INVISIBLE_CHARACTERISTICS,this);
	m_visible_charact.CreateFromStatic(IDC_VISIBLE_CHARACTERISTICS, this,LVS_NOSORTHEADER);
	// TODO: Add extra initialization here
	SetWindowText(m_dialog_name);

	m_ItemsVisible.Clear();
	m_ItemsInvisible.Clear();

	SItemStringData* el_string_data;
	CString buf;
	CStringArray* array;
	CaplMap map;

	// установка данных для окошек
	for (i = 0; i < m_Items->GetSize(); i++)
	{
		array=m_Items->GetAt(i);
		if(array==0)return FALSE;
		if(array->GetSize()==0)return FALSE;
		size=m_Columns->GetSize()<array->GetSize()?m_Columns->GetSize():array->GetSize();

		el_string_data=new SItemStringData();
		el_string_data->m_inst=(CaplInstance*)i;

		for(j=0;j<size;j++){
			el_string_data->m_values.Add(array->GetAt(j));
		}

		is_left=false;
		// поиск в маске
		for (j = 0; j < m_Mask->GetSize(); j++){
			if(m_Mask->GetAt(j)==(UINT)i){is_left=true;break;}
		}
		if(is_left){
			// заполнение левого окошка
			map.Add(j,(long)el_string_data);
		}else{
			// заполнение правого окошка
			m_ItemsInvisible.Add(el_string_data);
		}
	}
	map.SortIn();
	for(i=0;i<map.Size;i++){
		// заполнение левого окошка
		m_ItemsVisible.Add((SItemStringData*)map[i].out);
	}

	AddAnchor(IDC_STATIC_LEFT_NAME,TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_TOP,MIDDLE_LEFT);
	AddAnchor(IDC_BOTTOM,MIDDLE_LEFT);
	AddAnchor(IDC_VISIBLE_CHARACTERISTICS,TOP_LEFT,BOTTOM_CENTER);

	AddAnchor(ID_SAVE_CHARACT_LIST,BOTTOM_LEFT);
	AddAnchor(ID_LOAD_CHARACT_LIST,BOTTOM_CENTER);

	AddAnchor(IDC_ALL_LEFT,MIDDLE_CENTER);
	AddAnchor(IDC_ONE_LEFT,MIDDLE_CENTER);
	AddAnchor(IDC_ALL_RIGHT,MIDDLE_CENTER);
	AddAnchor(IDC_ONE_RIGHT,MIDDLE_CENTER);
	
	AddAnchor(IDC_STATIC_RIGHT_NAME, TOP_CENTER,TOP_RIGHT);
	AddAnchor(IDC_INVISIBLE_CHARACTERISTICS,TOP_CENTER,BOTTOM_RIGHT);
	
	AddAnchor(IDOK,BOTTOM_CENTER);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);
	
	m_BtnOk.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_BtnOk.SetFlat(FALSE);
	m_BtnCancel.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_BtnCancel.SetFlat(FALSE);

	m_BtnTop.SetIcon(GetAplTableIco(APL_TABLE_TOP));
	m_BtnTop.SetFlat(FALSE);
	m_BtnTop.SetTooltipText( APL_T("Сдвинуть вверх"));
	m_BtnBottom.SetIcon(GetAplTableIco(APL_TABLE_BOTTOM));
	m_BtnBottom.SetFlat(FALSE);
	m_BtnBottom.SetTooltipText( APL_T("Сдвинуть вниз"));

	m_BtnOneRight.SetIcon(GetAplStdIco16(APLSTDICO_RIGHT));
	m_BtnOneRight.SetFlat(FALSE);
	m_BtnOneRight.SetTooltipText( APL_T("Удалить"));
	m_BtnOneLeft.SetIcon(GetAplStdIco16(APLSTDICO_LEFT));
	m_BtnOneLeft.SetFlat(FALSE);
	m_BtnOneLeft.SetTooltipText( APL_T("Добавить"));
	m_BtnAllRight.SetIcon(GetAplStdIco16(APLSTDICO_RIGHT_ALL));
	m_BtnAllRight.SetFlat(FALSE);
	m_BtnAllRight.SetTooltipText( APL_T("Удалить все"));
	m_BtnAllLeft.SetIcon(GetAplStdIco16(APLSTDICO_LEFT_ALL));
	m_BtnAllLeft.SetFlat(FALSE);
	m_BtnAllLeft.SetTooltipText( APL_T("Добавить все"));

	m_BtnSaveChar.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	m_BtnSaveChar.SetFlat(FALSE);
	m_BtnSaveChar.SetTooltipText( APL_T("Сохранить в текстовый файл"));
	m_BtnLoadChar.SetIcon(GetAplTableIco(APL_TABLE_OPEN));
	m_BtnLoadChar.SetFlat(FALSE);
	m_BtnLoadChar.SetTooltipText( APL_T("Прочитать из текстового файла"));

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

void CChooseCharacteristicsDlg::Redraw()
{
	int i,last_sort=-1;
	for(i=0;i<(int)m_invisible_charact.GetColumnCount();i++){
		if(!m_invisible_charact.NotInCombinedSortedColumnList(i)){
			last_sort=i;break;
		}
	}
	m_invisible_charact.SetData(*m_Columns,m_ItemsInvisible);
	m_visible_charact.SetData(*m_Columns,m_ItemsVisible);
	
	m_invisible_charact.FillTable();
	m_visible_charact.FillTable();
	if(last_sort!=-1){
		m_invisible_charact.SortColumn(last_sort);
		m_invisible_charact.SortColumn(last_sort);
	}
	
}


void CChooseCharacteristicsDlg::OnAllLeft() 
{
	m_ItemsInvisible.AutoKillReference=false;
	m_ItemsVisible.AutoKillReference=false;
	
	for (int i = 0; i < m_ItemsInvisible.GetSize(); i++){
		m_ItemsVisible.Add(m_ItemsInvisible.GetAt(i));
	}
	m_ItemsInvisible.Clear();
	m_ItemsInvisible.AutoKillReference=true;
	m_ItemsVisible.AutoKillReference=true;
	Redraw();

}

void CChooseCharacteristicsDlg::OnAllRight() 
{
	m_ItemsInvisible.AutoKillReference=false;
	m_ItemsVisible.AutoKillReference=false;
	for (int i = 0; i < m_ItemsVisible.GetSize(); i++){
		m_ItemsInvisible.Add(m_ItemsVisible.GetAt(i));
	}
	m_ItemsVisible.Clear();
	m_ItemsInvisible.AutoKillReference=true;
	m_ItemsVisible.AutoKillReference=true;
	Redraw();
	
}

void CChooseCharacteristicsDlg::OnOneLeft() 
{
	CUIntArray array;
	m_invisible_charact.GetSelectedElements(array);
	MoveGroupLeft(array);
}

void CChooseCharacteristicsDlg::MoveGroupLeft(CUIntArray &array)
{
	int i,j;
	m_ItemsInvisible.AutoKillReference=false;
	m_ItemsVisible.AutoKillReference=false;
	for(i=0;i<array.GetSize();i++){
		m_ItemsVisible.Add(m_ItemsInvisible.GetAt(array.GetAt(i)));
	}
	for(i=m_ItemsInvisible.GetSize()-1;i>=0;i--){
		for(j=0;j<array.GetSize();j++){
			if(array.GetAt(j)==(UINT)i){
				m_ItemsInvisible.Remove(i);
				break;
			}
		}
	}
	m_ItemsInvisible.AutoKillReference=true;
	m_ItemsVisible.AutoKillReference=true;
	Redraw();}

void CChooseCharacteristicsDlg::OnOneRight() 
{
	CUIntArray array;
	int i,j;
	m_ItemsInvisible.AutoKillReference=false;
	m_ItemsVisible.AutoKillReference=false;
	m_visible_charact.GetSelectedElements(array);
	for(i=0;i<array.GetSize();i++){
		m_ItemsInvisible.Add(m_ItemsVisible.GetAt(array.GetAt(i)));
	}
	for(i=m_ItemsVisible.GetSize()-1;i>=0;i--){
		for(j=0;j<array.GetSize();j++){
			if(array.GetAt(j)==(UINT)i){
				m_ItemsVisible.Remove(i);
				break;
			}
		}
	}
	m_ItemsInvisible.AutoKillReference=true;
	m_ItemsVisible.AutoKillReference=true;
	Redraw();
}

void CChooseCharacteristicsDlg::OnTop() 
{
	CUIntArray array;
	SItemStringData* el;
	m_visible_charact.GetSelectedElements(array);
	if(array.GetSize()==0)return;

	int position = array[0];
	if (position != LB_ERR && position != 0)
	{
		el=m_ItemsVisible[position];
		m_ItemsVisible.AutoKillReference=false;
		m_ItemsVisible.Remove(position);
		m_ItemsVisible.Insert(position - 1,el);
		m_ItemsVisible.AutoKillReference=true;
		Redraw();
		m_visible_charact.SetSelectedElement(position - 1);
	}
	
}

void CChooseCharacteristicsDlg::OnBottom() 
{
	CUIntArray array;
	SItemStringData* el;
	m_visible_charact.GetSelectedElements(array);
	if(array.GetSize()==0)return;
	
	int position = array[0];

	if (position != LB_ERR && position != (m_ItemsVisible.GetSize() - 1))
	{
		el=m_ItemsVisible[position];
		m_ItemsVisible.AutoKillReference=false;
		m_ItemsVisible.Remove(position);
		m_ItemsVisible.Insert(position + 1,el);
		m_ItemsVisible.AutoKillReference=true;
		
		Redraw();
		m_visible_charact.SetSelectedElement(position + 1);
	}
}


void CChooseCharacteristicsDlg::OnOK() 
{
	// TODO: Add extra validation here
	SItemStringData* el;
	m_Mask->RemoveAll();	// сбросим старое содержимое
	// заполним маску новым содержимым
	for (int i = 0; i < m_ItemsVisible.GetSize(); i++){
		el=m_ItemsVisible[i];
		m_Mask->Add((UINT)(el->m_inst));
	}
	CResizableDialog::OnOK();
}

void CChooseCharacteristicsDlg::OnSaveCharactList() 
{
	SItemStringData* el;
	CFileDialog save_dialog(FALSE, _T("txt"), _T(""),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		 APL_T("Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*||"));
 	if (save_dialog.DoModal() == IDOK)
	{
		CString FileName = save_dialog.GetFileName();
		CStdioFile save_file(FileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
		CString line,buf;
		line =  APL_T("Список характеристик для отображения:\n\n");
		save_file.WriteString(line);
		for (int i = 0; i < m_ItemsVisible.GetSize(); i++){
			el=m_ItemsVisible[i];
			line=el->m_values[0];
			if(m_visible_charact.GetColumnCount()>=2){
				if(el->m_values[1]!=_T("")){
					line+=_T(" (")+el->m_values[1]+_T(")");
				}
			}
			if(m_visible_charact.GetColumnCount()==3){
				if(el->m_values[2]!=_T("")){
					line+=_T(" [")+el->m_values[2]+_T("]");
				}
			}
			line+=_T("\n");
			save_file.WriteString(line);
		}

		save_file.Close();
	}
}

void CChooseCharacteristicsDlg::OnLoadCharactList() 
{
	SItemStringData* el;
	CStringArray def_values;
	CUIntArray array_res;
	int i;
	CString line;
	CFileDialog load_dialog(TRUE, _T("txt"), _T(""),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		 APL_T("Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*||"));
	if (load_dialog.DoModal() == IDOK)
	{
		CString FileName = load_dialog.GetFileName();
		CStdioFile load_file;
		CFileException e;
		if (!load_file.Open(FileName, CFile::modeRead | CFile::typeText, &e))
		{
			if (e.m_cause == CFileException::fileNotFound)
				MessageBox( APL_T("Файл не найден!"),  APL_T("Ошибка!"), MB_OK | MB_ICONEXCLAMATION);
			else
				MessageBox( APL_T("Файл не может быть открыт!"),  APL_T("Ошибка!"), MB_OK | MB_ICONEXCLAMATION);
			return;
		}
		// перекинем все характеристики из левого списка в правый 
		OnAllRight();
		// Сформируем массив строк для сравнения
		for (i = 0; i < m_ItemsInvisible.GetSize(); i++){
			el=m_ItemsInvisible[i];
			line=el->m_values[0];
			if(m_visible_charact.GetColumnCount()>=2){
				if(el->m_values[1]!=_T("")){
					line+=_T(" (")+el->m_values[1]+_T(")");
				}
			}
			if(m_visible_charact.GetColumnCount()==3){
				if(el->m_values[2]!=_T("")){
					line+=_T(" [")+el->m_values[2]+_T("]");
				}
			}
			def_values.Add(line);
		}

		
		// считаем характеристики из файла
		if (!load_file.ReadString(line))
		{
			MessageBox( APL_T("Файл пуст!"),  APL_T("Ошибка"), MB_OK | MB_ICONEXCLAMATION);
			return;
		}
		else if (line !=  APL_T("Список характеристик для отображения:"))
		{
			MessageBox( APL_T("Неверный формат файла!"),  APL_T("Ошибка"), MB_OK | MB_ICONEXCLAMATION);
			return;
		}
		else
			load_file.ReadString(line);	// прочитаем пустую строку
		while (load_file.ReadString(line))
		{
			// поиск строки
			int index=-1;
			for(int i=0;i<def_values.GetSize();i++){
				if(def_values[i]==line){
					index=i;break;
				}
			}
			
			if (index==-1)
			{	// характеристика не найдена
				CString err_line;
				err_line.Format( APL_T("Характеристика \"%s\" не найдена в списке"), line);
				MessageBox(err_line,  APL_T("Ошибка!"), MB_OK | MB_ICONEXCLAMATION);
			}
			else
			{
				array_res.Add(index);
			}
		}
		MoveGroupLeft(array_res);		
	}
	
}
