// RequirementPropertiesDlg.cpp : implementation file
//

#include "stdafx.h"
#include "RequirementPropertiesDlg.h"

#define IDM_FONTSIZE_STYLE   5005

CString CreateGUID()
{
	CString guid=_T("");

	::CoInitialize(NULL);
	GUID pGuid = GUID_NULL;
	::CoCreateGuid(&pGuid);
	if(pGuid==GUID_NULL) return _T("");

	guid.Format(_T("{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
		pGuid.Data1, pGuid.Data2, pGuid.Data3,
		pGuid.Data4[0], pGuid.Data4[1], pGuid.Data4[2], pGuid.Data4[3],
		pGuid.Data4[4], pGuid.Data4[5], pGuid.Data4[6], pGuid.Data4[7]);

	::CoUninitialize();

	guid.Delete(0);
	guid.Delete( guid.GetLength()-1 );

	return guid;
}


// CRequirementPropertiesDlg dialog

IMPLEMENT_DYNAMIC(CRequirementPropertiesDlg, CaplResizableDialog)

CRequirementPropertiesDlg::CRequirementPropertiesDlg(CaplAPI *api, CaplInstance *ciReq, CaplInstance *ciParent, CWnd* pParent, UINT idd)
	: CaplResizableDialog(idd, pParent)
{
	m_pHTML = 0;
	m_api = api;
	m_ciReq = ciReq;
	m_bReadOnlyMode = false;
	m_ciParent = ciParent;	

	m_ciExecutor = NULL;
	m_ciSource = NULL;

	if(!ciReq) m_bNewRequirement = true;
	else m_bNewRequirement = false;

	if(m_ciReq)
	{
		if(m_ciReq->GetAccessmode() >= aplRO)
			m_bReadOnlyMode = true;

		if(m_api)
		{
			CString str;
			m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_wf_state, str);
			if(str == _T("approved")) m_bReadOnlyMode = true;
		}
	}
}

CRequirementPropertiesDlg::~CRequirementPropertiesDlg()
{
	
}

void CRequirementPropertiesDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);

	DDX_Text(pDX, IDC_ID, m_sId);
	DDX_Text(pDX, IDC_NAME, m_sName);
	DDX_Text(pDX, IDC_SOURCE, m_sSourceName);
	DDX_Text(pDX, IDC_DEVELOPER, m_sDeveloper);
	DDX_Text(pDX, IDC_VS, m_sVS);
	DDX_Text(pDX, IDC_NOTES, m_sNotes);
	
	DDX_Control(pDX, IDOK, m_ok_btn);
	DDX_Control(pDX, IDCANCEL, m_cancel_btn);
		
	DDX_Control(pDX, IDC_ALIGN_LEFT, m_left_align);
	DDX_Control(pDX, IDC_ALIGN_CENTER, m_center_align);
	DDX_Control(pDX, IDC_ALIGN_RIGHT, m_right_align);

	DDX_Control(pDX, IDC_ITALIC, m_italic);
	DDX_Control(pDX, IDC_BOLD, m_bold);
	DDX_Control(pDX, IDC_UNDERLINE, m_underline);

	DDX_Control(pDX, IDC_CUT, m_cut);
	DDX_Control(pDX, IDC_COPY, m_copy);
	DDX_Control(pDX, IDC_PASTE, m_paste);

	DDX_Control(pDX, IDC_IMAGE, m_picture);
	DDX_Control(pDX, IDC_FONT_COLOR, m_color);

	DDX_Control(pDX, IDC_FONT_NAME, m_FontName);
	DDX_Control(pDX, IDC_FONT_SIZE, m_FontSize);

	DDX_Control(pDX, IDC_CHOOSE_SOURCE, m_choose_source);
	DDX_Control(pDX, IDC_DEL_SOURCE, m_del_source);

	VirtualDDX(pDX);
}

void CRequirementPropertiesDlg::VirtualDDX(CDataExchange* pDX)
{
	DDX_Control(pDX, IDC_EXECUTOR, m_executorEdit);
	DDX_Control(pDX, IDC_EV_DATE, m_evDateCtrl);
	DDX_Control(pDX, IDC_CUR_STATE, m_stateEdit);
	DDX_Control(pDX, IDC_MOS, m_MOS);
	DDX_Control(pDX, IDC_LIST, m_list);
	DDX_Control(pDX, IDC_CHOOSE_EXEC, m_choose_exec);
	DDX_Control(pDX, IDC_CLEAR_EXEC, m_clear_exec);
	DDX_Text(pDX, IDC_CUR_STATE, m_sState);
}

BEGIN_MESSAGE_MAP(CRequirementPropertiesDlg, CaplResizableDialog)
	ON_BN_CLICKED(IDC_ALIGN_LEFT, &CRequirementPropertiesDlg::OnBnClickedAlignLeft)
	ON_BN_CLICKED(IDC_ALIGN_CENTER, &CRequirementPropertiesDlg::OnBnClickedAlignCenter)
	ON_BN_CLICKED(IDC_ALIGN_RIGHT, &CRequirementPropertiesDlg::OnBnClickedAlignRight)
	ON_BN_CLICKED(IDC_ITALIC, &CRequirementPropertiesDlg::OnBnClickedItalic)
	ON_BN_CLICKED(IDC_BOLD, &CRequirementPropertiesDlg::OnBnClickedBold)
	ON_BN_CLICKED(IDC_UNDERLINE, &CRequirementPropertiesDlg::OnBnClickedUnderline)
	ON_BN_CLICKED(IDC_IMAGE, &CRequirementPropertiesDlg::OnBnClickedImage)
	ON_NOTIFY(NM_CLICK, IDC_HTML, OnHTMLClick)
	ON_CBN_SELCHANGE(IDC_FONT_NAME, &CRequirementPropertiesDlg::OnCbnSelchangeFontName)
	ON_BN_CLICKED(IDC_CUT, &CRequirementPropertiesDlg::OnBnClickedCut)
	ON_BN_CLICKED(IDC_COPY, &CRequirementPropertiesDlg::OnBnClickedCopy)
	ON_BN_CLICKED(IDC_PASTE, &CRequirementPropertiesDlg::OnBnClickedPaste)

	ON_WM_TIMER()
	ON_CBN_SELCHANGE(IDC_FONT_SIZE, &CRequirementPropertiesDlg::OnCbnSelchangeFontSize)
	ON_BN_CLICKED(IDC_FONT_COLOR, &CRequirementPropertiesDlg::OnBnClickedFontColor)
	ON_BN_CLICKED(IDC_CLEAR_EXEC, &CRequirementPropertiesDlg::OnBnClickedClearExec)
	ON_BN_CLICKED(IDC_CHOOSE_EXEC, &CRequirementPropertiesDlg::OnBnClickedChooseExec)
	ON_BN_CLICKED(IDC_CHOOSE_SOURCE, &CRequirementPropertiesDlg::OnBnClickedChooseSource)
	ON_BN_CLICKED(IDC_DEL_SOURCE, &CRequirementPropertiesDlg::OnBnClickedDelSource)
END_MESSAGE_MAP()

BOOL CRequirementPropertiesDlg::OnInitDialog()
{
	CaplResizableDialog::OnInitDialog();
	if(m_api==NULL)
	{
		EndDialog(0);
		return FALSE;
	}

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

	// заполняем возможные варианты соответствий
	FillMOS();

	// заполняем всеми возможными шрифтами
	FillFonts();

	// инициализиарем список иконок
	CreateImageList();

	// инициализирем тулбар
	InitToolBar();

	// инициализация списка документов
	InitList();

	if(!m_ciParent)
	{
		GetDlgItem(IDC_DEVELOPER)->EnableWindow(TRUE);
		GetDlgItem(IDC_VS)->EnableWindow(TRUE);
	}

	// отображаем данные, если они есть
	if(m_ciReq)
	{
		FillDocuments();
		m_api->m_req_mgr.LoadReqInfo(m_ciReq);

		// обозначение
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_id, m_sId);

		// соответствие
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_state, m_sState);

		// неформатированный текст
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_name, m_sName);

		// разработчик
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_developer, m_sDeveloper);
		m_sOldDeveloper = m_sDeveloper;

		// примечания
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_notes, m_sNotes);

		// тип ВС
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_vs, m_sVS);
		m_sOldVS = m_sVS;

		// не требуется
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_no_need, m_bNoNeed);
		if(m_bNoNeed) ((CButton*)GetDlgItem(IDC_DO_NOT_NEED))->SetCheck(1);
		else ((CButton*)GetDlgItem(IDC_DO_NOT_NEED))->SetCheck(0);

		// последнее обновление
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_last_updated, m_sLastUpdated);

		// методика опредеения соответствия
		if(m_MOS.GetSafeHwnd())
		{
			m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_mos, m_sMOS);	
			if(!m_sMOS.IsEmpty()) m_MOS.SetCurSel( _atoi(m_sMOS) );
		}

		// форматированный текст
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_html, m_sHTML);
		if(!m_sHTML.IsEmpty())
		{
			CreateTemproryFilesForPictures(m_sHTML);
			m_pHTML->SetDocumentHTML(m_sHTML);
		}

		CString buf;
		COleDateTime time;
		
		// дата определения соответствия
		if(m_evDateCtrl)
		{
			m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_equivalence_date, m_sEqvDate);
			aplString2Date(m_sEqvDate, time);
			m_evDateCtrl.SetTime(time);
		}

		// источник
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_source, m_ciSource);
		if(m_ciSource) 
		{
			m_del_source.EnableWindow(TRUE);
			m_api->m_req_mgr.LoadReqInfo(m_ciSource);
			m_api->GetItemName(m_ciSource, m_sSourceName);
		}

		// исполнитель
		m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_executor, m_ciExecutor);
		if(m_ciExecutor && m_executorEdit.GetSafeHwnd()) 
		{
			m_clear_exec.EnableWindow(TRUE);
			m_api->m_appr_mgr.GetPersonName(m_ciExecutor, buf, false);
			m_executorEdit.SetWindowText(buf);
		}

		UpdateData(FALSE);
		if(m_bReadOnlyMode) SetFiledsReadOnly();
	}	

	AddAnchors();
	SetTimer(IDC_TIMER, 500, NULL);

	return TRUE;
}

bool CRequirementPropertiesDlg::CreateHTMLedit()
{
	CRect rect;
	GetDlgItem(IDC_STATIC_BORDER)->GetWindowRect(rect);
	ScreenToClient(rect);

	m_pHTML = new CHtmlEditCtrl();
	m_pHTML->Create(_T(""), WS_CHILD | WS_VSCROLL| WS_HSCROLL | WS_TABSTOP | ES_DISABLENOSCROLL | 
		ES_WANTRETURN | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, rect, this, IDC_HTML);

	m_pHTML->SetDesignMode(true);
	if(!m_ciReq)
	{
		m_pHTML->SetDocumentHTML(_T("<DIV Style='LINE-HEIGHT:1'></DIV>"));
		m_pHTML->GetDocumentHTML(m_sHTML);		
	}

	return true;
}

bool CRequirementPropertiesDlg::ChangeToWin1251( CString &html )
{
	html.Replace(_T("charset=unicode"), _T("charset=windows-1251"));
	return true;
}

bool CRequirementPropertiesDlg::CreateTemproryFilesForPictures( CString &html )
{
	if(!m_ciReq) return false;
	if(html.IsEmpty()) return false;

	int nIndex = 0;
	CString sSRC = _T("src=\"");
	
	CString sFileName, sBlobName;
	aplExtent aePictures;

	// заполняем мап с документами. которые уже есть
	m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_pictures, aePictures);
	for(int i=0; i<aePictures.Size; i++)
	{
		m_api->m_data.GetAttr(aePictures[i], m_api->m_doc_mgr.a_apl_stored_document_source, sBlobName);
		m_Blobs.Add(sBlobName, (long)aePictures[i]);
	}
	
	while(true)
	{
		int nIndexFind = html.Find(sSRC, nIndex);
		if(nIndexFind == -1) break;

		// находим начало ссылки на файл
		int nLastQuoteIndex = html.Find(_T("\""), nIndexFind+sSRC.GetLength());

		// получаем номер блоба
		sBlobName = html.Mid(nIndexFind+sSRC.GetLength(), nLastQuoteIndex - nIndexFind-sSRC.GetLength());

		// ищем блоб в мапе
		int nMapIndex = m_Blobs.Find(sBlobName);	
		
		sFileName=_T("");
		if(nMapIndex != -1)
		{
			CaplInstance *ciFile = (CaplInstance*)m_Blobs.GetAt(nMapIndex)->val;

			// сохраняем файл на диск
			sFileName = CreateGUID();
			CString buf;
			aplGetTempPath(buf);
			buf+=sFileName;
			sFileName = buf;
			m_api->m_data.NET_LoadBlob(ciFile, m_api->m_doc_mgr.a_apl_stored_document_source, sFileName);

			// удаляем старую ссылку файла
			html.Delete(nIndexFind+sSRC.GetLength(), nLastQuoteIndex - nIndexFind-sSRC.GetLength());

			// устанавливаем новую ссылку файла
			html.Insert(nIndexFind+sSRC.GetLength(), sFileName);

			// изменяем имя файла в мапе (и пересортировыаем его)
			m_Blobs.GetAt(nMapIndex)->str = sFileName;			
			m_Blobs.Sort();
		}				

		// идем дальше
		nIndex = nIndexFind + sSRC.GetLength() + sFileName.GetLength();
	}	
	
	return true;
}

bool CRequirementPropertiesDlg::ReplaceImagesSRC(CString &html)
{
	CString fileName, sBlob;
	CString sNewFileName;
	int nIndex = 0, nMapIndex;
	CString tmp = html, sSRC = _T("src=\"");
	aplExtent newPictures;
	aplExtent oldPictures;
	CaplInstance *ciFile;
		
	html = tmp;
	while(true)
	{
		int nIndexFind = html.Find(sSRC, nIndex);
		if(nIndexFind == -1) break;

		// находим начало ссылки на файл
		int nLastQuoteIndex = html.Find(_T("\""), nIndexFind + sSRC.GetLength());

		// получаем адрес файла
		fileName = html.Mid(nIndexFind + sSRC.GetLength(), nLastQuoteIndex - nIndexFind - sSRC.GetLength());
		if(fileName.Left(8) == _T("file:///")) 
		{
			fileName.Delete(0, 8);
			fileName.Replace(_T("/"), _T("\\"));
		}

		if(fileName.Left(7) == _T("file://")) 
			fileName.Delete(0, 7);					

		// смотрим, может такой файл уже был
		nMapIndex = m_Blobs.Find(fileName);

		if(nMapIndex == -1)
		{
			// создаем блоб на сервере
			CaplInstance *ciNewFile = m_api->m_doc_mgr.CreateFile(fileName);

			sNewFileName=_T("");
			if(ciNewFile)
			{
				m_api->m_data.GetAttr(ciNewFile, m_api->m_doc_mgr.a_apl_stored_document_source, sNewFileName);
				newPictures.Add(ciNewFile);
			}						
		}
		else
		{
			// получаем имя файла
			sNewFileName = m_Blobs.GetAt(nMapIndex)->str;

			// удаляем сам файл
			::DeleteFile(sNewFileName);

			// получаем номер блоба (он же будет новой ссылкой для файла
			m_api->m_data.GetAttr((CaplInstance*)m_Blobs.GetAt(nMapIndex)->val, m_api->m_doc_mgr.a_apl_stored_document_source, sNewFileName);

			// удаляем из карты
			m_Blobs.Remove(nMapIndex);
		}

		// удаляем старое имя файла
		html.Delete(nIndexFind + sSRC.GetLength(), nLastQuoteIndex - nIndexFind - sSRC.GetLength());

		// и подменяем его на номер блоба
		html.Insert(nIndexFind + sSRC.GetLength(), sNewFileName);

		// двигаемся дальше
		nIndex = nIndexFind + sSRC.GetLength() + sNewFileName.GetLength();
	}

	// смотрим, что было раньше
	m_api->m_data.GetAttr(m_ciReq, m_api->m_req_mgr.a_req_pictures, oldPictures);

	// если блобы остались - значит эти файлы удалили из описания требования
	for(int i=0; i<m_Blobs.GetSize(); i++)
	{
		ciFile = (CaplInstance*)m_Blobs.GetAt(i)->val;

		// удаляем блоб
		m_api->m_data.NET_DeleteBlob(ciFile, m_api->m_doc_mgr.a_apl_stored_document_source);
		m_api->m_data.DeleteInstance(ciFile);
		
		// удаляем файл на диске
		::DeleteFile(m_Blobs.GetAt(i)->str);

		// удаляем из старого массива атрибутов
		for(int j=0; j<oldPictures.GetSize(); j++)
		{
			if(oldPictures[j] == ciFile)
			{
				oldPictures.Remove(j);
				break;
			}
		}
	}

	// добавляем новые блобы на новые картинки
	oldPictures.Append(newPictures);
		
	// сохраняем получившийся массив
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_pictures, oldPictures);

	return true;
}

CString CRequirementPropertiesDlg::GetCorrectedDocumentHTML()
{
	CString sFullHTML;
	m_pHTML->GetDocumentHTML(sFullHTML);

	ChangeToWin1251(sFullHTML);
	ReplaceImagesSRC(sFullHTML);

	return sFullHTML;
}

void CRequirementPropertiesDlg::OK()
{
	CString buf;
	COleDateTime time;

	UpdateData();

	if(m_sId.IsEmpty())
	{
		MessageBox( APL_T("Введите обозначение требования!"),  APL_T("Не задано обозначение"), MB_ICONINFORMATION);
		((CEdit*)GetDlgItem(IDC_ID))->SetFocus();
		return;
	}

	if(m_ciParent)
	{
		if(!m_api->m_req_mgr.IsRequirementUniqueId(m_ciParent, m_ciReq, m_sId))
		{
			MessageBox( APL_T("Обозначение должно быть уникальным в составе родительского правила."),  APL_T("Обозначение не уникально"), MB_ICONINFORMATION);
			((CEdit*)GetDlgItem(IDC_ID))->SetFocus();
			return;
		}
	}

	m_pHTML->GetDocumentHTML(m_sHTML); 
	if(!m_ciReq)
		SetNormalInterliage(m_sHTML);

	ChangeToWin1251(m_sHTML);

	if(m_MOS.GetSafeHwnd())
		m_sMOS.Format(_T("%d"), m_MOS.GetCurSel() );
	aplDate2String(COleDateTime::GetCurrentTime(), m_sLastUpdated);

	if(m_evDateCtrl.GetSafeHwnd())
	{
		m_evDateCtrl.GetTime(time);
		aplDate2String(time, m_sEqvDate);
	}

	if(!m_ciReq) m_ciReq = m_api->m_data.CreateInstance(m_api->m_req_mgr.e_requirement);
	if(!m_ciReq)  OnCancel();

	ReplaceImagesSRC(m_sHTML);
	if(!SetInstAttrs()) OnCancel();

	CString str;
	m_pHTML->GetDlgItemText(IDC_HTML, str);
	m_pHTML->GetWindowText(str);

	KillTimer(IDC_TIMER);
}

void CRequirementPropertiesDlg::OnOK()
{
	OK();	
	CaplResizableDialog::OnOK();	
}

bool CRequirementPropertiesDlg::SetInstAttrs()
{
	m_sVS.Trim();
	m_sDeveloper.Trim();

	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_id, m_sId);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_state, m_sState);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_name, m_sName);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_html, m_sHTML);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_developer, m_sDeveloper);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_vs, m_sVS);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_no_need, ((CButton*)GetDlgItem(IDC_DO_NOT_NEED))->GetCheck()?true:false);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_last_updated, m_sLastUpdated);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_updated_person, m_api->m_appr_mgr.GetCurrentPerson());
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_mos, m_sMOS);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_executor, m_ciExecutor);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_equivalence_date, m_sEqvDate);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_notes, m_sNotes);
	m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_source, m_ciSource);

	if(m_bNewRequirement) m_api->m_data.PutAttr(m_ciReq, m_api->m_req_mgr.a_req_wf_state, m_api->m_req_mgr.GetInitialRequirementState());
	else if(!m_bNewRequirement && (m_sOldDeveloper!= m_sDeveloper || m_sOldVS!=m_sVS)) m_api->m_req_mgr.SetAttrForChilds(m_ciReq);

	return true;
}

bool CRequirementPropertiesDlg::FillMOS()
{
	if(0 == m_MOS.GetSafeHwnd())
		return false;

	// возможно методика заполняется из справочника
	CaplInstance *option = m_api->m_options_mgr.FindOptionBN(_T("PSS\\Требования\\Обозначение справочника методики"));
	if (option)
	{
		CString clsfID;
		m_api->m_data.GetAttr(option, m_api->m_options_mgr.a_str_value, clsfID);

		if (clsfID.IsEmpty() == false)
		{
			CaplInstance *system =  m_api->m_classifier_mgr.GetClassifierSystemById(clsfID, true);
			if (system)
			{
				aplExtent levels;
				m_api->m_classifier_mgr.LoadSubClassifierLevels(system, levels, false, true);

				std::vector<CString> vec;
				for (int i = 0; i < levels.Size; ++i)
				{
					CString id, name, value;
					m_api->m_data.GetAttr(levels[i], m_api->m_classifier_mgr.a_apl_classifier_level_id, id);
					m_api->m_data.GetAttr(levels[i], m_api->m_classifier_mgr.a_apl_classifier_level_name, name);

					value = id + _T(" - " + name);
					vec.push_back(value);
				}

				for (unsigned int i = 0; i < vec.size(); ++i)
					m_MOS.InsertString(i, vec[i]);
				
				m_MOS.SetCurSel(0);
				return true;
			}
		}
	}

	// нет, просто жестко заданные значения
	m_MOS.InsertString(0,  APL_T("0 - Инж. оценка – рассмотрение требований"));
	m_MOS.InsertString(1,  APL_T("1 - Инж. оценка – рассмотрение конструкции"));
	m_MOS.InsertString(2,  APL_T("2 - Инж. оценка - расчеты / анализы"));
	m_MOS.InsertString(3,  APL_T("3 - Инж. оценка - рассмотрение консрукции"));
	m_MOS.InsertString(4,  APL_T("4 - Испытания - стендовые / лабораторные"));
	m_MOS.InsertString(5,  APL_T("5 - Испытания - наземные"));
	m_MOS.InsertString(6,  APL_T("6 - Испытания - летные"));
	m_MOS.InsertString(7,  APL_T("7 - Испытания - моделирование"));
	m_MOS.InsertString(8,  APL_T("8 - Испытания КИ"));
	m_MOS.InsertString(9,  APL_T("9 - Опыт эксплуатации"));

	m_MOS.SetCurSel(0);
	return true;
}

bool CRequirementPropertiesDlg::CreateImageList()
{
	CBitmap bmp;
	bmp.LoadBitmap(IDB_REQUIREMENT);

	m_Image.Create(24, 24, ILC_MASK|ILC_COLOR24, 0, 10);
	m_Image.Add(&bmp, RGB(192, 192, 192));

	return true;
}

bool CRequirementPropertiesDlg::SetDefaultAlign()
{
	m_left_align.SetCheck(1);
	m_pHTML->ExecHelperSetVal(IDM_JUSTIFYLEFT);

	return true;
}

bool CRequirementPropertiesDlg::ResetAlign(CaplButton &Btn)
{
	if(Btn != m_left_align) m_left_align.SetCheck(0);
	if(Btn != m_center_align) m_center_align.SetCheck(0);
	if(Btn != m_right_align) m_right_align.SetCheck(0);

	return true;
}

bool CRequirementPropertiesDlg::InitToolBar()
{
	// кнопки выравнивая
	m_left_align.SetIcon(GetAplTableIco(14));
	m_left_align.SetFlat(TRUE);
	m_left_align.SetCheck(0);
	m_left_align.SetTooltipText( APL_T("Выровнять по левому краю"));

	m_center_align.SetIcon(GetAplTableIco(15));
	m_center_align.SetFlat(TRUE);
	m_center_align.SetCheck(0);
	m_center_align.SetTooltipText( APL_T("Выровнять по центру"));

	m_right_align.SetIcon(GetAplTableIco(16));
	m_right_align.SetFlat(TRUE);
	m_right_align.SetCheck(0);
	m_right_align.SetTooltipText( APL_T("Выровнять по правому краю"));

	SetDefaultAlign();

	// кнопки типа шрифта
	m_italic.SetIcon(GetAplTableIco(APL_TABLE_ITALIC));
	m_italic.SetFlat(TRUE);
	m_italic.SetCheck(0);
	m_italic.SetTooltipText( APL_T("Курсив"));

	m_bold.SetIcon(GetAplTableIco(APL_TABLE_BOLD));
	m_bold.SetFlat(TRUE);
	m_bold.SetCheck(0);
	m_bold.SetTooltipText( APL_T("Жирный"));

	m_underline.SetIcon(GetAplTableIco(APL_TABLE_UNDERLINE));
	m_underline.SetFlat(TRUE);
	m_underline.SetCheck(0);
	m_underline.SetTooltipText( APL_T("Подчеркнутый"));

	// кнопки типа копи-паст
	m_cut.SetIcon(GetAplTableIco(APL_TABLE_CUT));
	m_cut.SetFlat(TRUE);
	m_cut.SetTooltipText( APL_T("Вырезать"));

	m_copy.SetIcon(GetAplTableIco(APL_TABLE_COPY));
	m_copy.SetFlat(TRUE);
	m_copy.SetTooltipText( APL_T("Копировать"));

	m_paste.SetIcon(GetAplTableIco(APL_TABLE_PASTE));
	m_paste.SetFlat(TRUE);
	m_paste.SetTooltipText( APL_T("Вставить"));

	// вставка изображения и замена цвета
	m_picture.SetIcon(GetAplStdIco16(APL_STD_IMAGE));
	m_picture.SetFlat(TRUE);
	m_picture.SetTooltipText( APL_T("Вставить изображение"));

	m_color.SetIcon(GetAplTableIco(9));
	m_color.SetFlat(TRUE);
	m_color.SetTooltipText( APL_T("Изменить цвет текста"));

	// выбрать / очистить исполнителя
	if(m_choose_exec.GetSafeHwnd())
	{
		m_choose_exec.SetIcon(aplGetButtonIco(APL_24_SELECT));
		m_choose_exec.SetFlat(TRUE);
		m_choose_exec.SetTooltipText( APL_T("Выбрать исполнителя"));
	}

	if(m_clear_exec.GetSafeHwnd())
	{
		m_clear_exec.SetIcon(aplGetButtonIco(APL_24_CLEAR));
		m_clear_exec.SetFlat(TRUE);
		m_clear_exec.SetTooltipText( APL_T("Очистить поле"));
	}

	// кнопки ок и отмена
	m_ok_btn.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_ok_btn.SetFlat(FALSE);

	m_cancel_btn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_cancel_btn.SetFlat(FALSE);

	// выбрать / очистить источник
	m_choose_source.SetIcon(aplGetButtonIco(APL_24_SELECT));
	m_choose_source.SetFlat(TRUE);
	m_choose_source.SetTooltipText( APL_T("Выбрать источник"));

	m_del_source.SetIcon(aplGetButtonIco(APL_24_CLEAR));
	m_del_source.SetFlat(TRUE);
	m_del_source.SetTooltipText( APL_T("Очистить поле"));

	return true;
}

void CRequirementPropertiesDlg::OnBnClickedAlignLeft()
{
	m_pHTML->ExecHelperSetVal(IDM_JUSTIFYLEFT);
	m_pHTML->SetFocus();
}

void CRequirementPropertiesDlg::OnBnClickedAlignCenter()
{
	m_pHTML->ExecHelperSetVal(IDM_JUSTIFYCENTER);
	m_pHTML->SetFocus();
}

void CRequirementPropertiesDlg::OnBnClickedAlignRight()
{
	m_pHTML->ExecHelperSetVal(IDM_JUSTIFYRIGHT);
	m_pHTML->SetFocus();
}

void CRequirementPropertiesDlg::OnBnClickedItalic()
{
	m_pHTML->ExecHelperSetVal(IDM_ITALIC);
	m_pHTML->SetFocus();
}

void CRequirementPropertiesDlg::OnBnClickedBold()
{
	m_pHTML->ExecHelperSetVal(IDM_BOLD);
	m_pHTML->SetFocus();
}

void CRequirementPropertiesDlg::OnBnClickedUnderline()
{
	m_pHTML->ExecHelperSetVal(IDM_UNDERLINE);
	m_pHTML->SetFocus();	
}

void CRequirementPropertiesDlg::OnBnClickedImage()
{
	m_pHTML->ExecHelperSetVal(IDM_IMAGE);
	m_pHTML->SetFocus();
}

void CRequirementPropertiesDlg::OnCancel()
{
	DeleteTemproryFiles();
	
	KillTimer(IDC_TIMER);
	CaplResizableDialog::OnCancel();
}

bool CRequirementPropertiesDlg::DeleteTemproryFiles()
{
	for(int i=0; i<m_Blobs.GetSize(); i++)
	{
		CString sFile = m_Blobs.GetAt(i)->str;
		::DeleteFile(sFile);
	}

	return true;	
}

void CRequirementPropertiesDlg::OnHTMLClick( NMHDR* pNMHDR, LRESULT* pResult )
{
}

void CRequirementPropertiesDlg::OnCbnSelchangeFontName()
{
	CString sName;
	m_FontName.GetWindowText(sName);

	if(!sName.IsEmpty()) m_pHTML->SetFontFace(sName);
}

bool CRequirementPropertiesDlg::FillFonts()
{
	CStringArray saFonts;
	GetSystemFonts(saFonts);

	for(int i=0; i<saFonts.GetSize(); i++)
		m_FontName.AddString(saFonts[i]);
	
	m_FontSize.SelectString(-1, _T("3"));
	m_FontName.SelectString(-1, _T("Times New Roman"));

	return true;
}

void CRequirementPropertiesDlg::GetSystemFonts(CStringArray &saFontList)
{
	CDC *pDC = GetDC ();

	EnumFonts (pDC->GetSafeHdc(),NULL,(FONTENUMPROC) CBEnumFonts,(LPARAM)&saFontList);//Enumerate

	ReleaseDC(pDC);
}

BOOL CALLBACK CRequirementPropertiesDlg::CBEnumFonts(LPLOGFONT lplf, LPTEXTMETRIC lptm, DWORD dwType, LPARAM lpData)
{
	if (dwType == TRUETYPE_FONTTYPE) 
	{
		((CStringArray *) lpData)->Add( lplf->lfFaceName );
	}

	return true;
}


void CRequirementPropertiesDlg::OnBnClickedCut()
{
	m_pHTML->Cut();
}

void CRequirementPropertiesDlg::OnBnClickedCopy()
{
	m_pHTML->Copy();	
}

void CRequirementPropertiesDlg::OnBnClickedPaste()
{
	m_pHTML->Paste();
}

void CRequirementPropertiesDlg::OnTimer(UINT nIDEvent) 
{
	UpdateCheckBoxes();
	CaplResizableDialog::OnTimer(nIDEvent);
}

bool CRequirementPropertiesDlg::UpdateCheckBoxes()
{
	UINT		check_boxes = 6;
	UINT		u32_bCmd[] = { IDM_BOLD, IDM_ITALIC, IDM_UNDERLINE, IDM_JUSTIFYLEFT, IDM_JUSTIFYCENTER, IDM_JUSTIFYRIGHT};
	CaplButton  *p_Check[] = { &m_bold, &m_italic, &m_underline, &m_left_align, &m_center_align, &m_right_align };

	// Set the checkboxes according to the current selection / cursor position
	for (UINT b=0; b<check_boxes; b++)
	{
		BOOL b_Active = (m_pHTML->QueryStatus(u32_bCmd[b]) & OLECMDF_LATCHED) > 0;
		if(p_Check[b]->GetCheck() != b_Active) p_Check[b]->SetCheck(b_Active);
	}

	return true;
}
void CRequirementPropertiesDlg::OnCbnSelchangeFontSize()
{
	CString sSize;
	m_FontSize.GetWindowText(sSize);

	if(!sSize.IsEmpty()) m_pHTML->SetFontSize(_atoi(sSize));
}

bool CRequirementPropertiesDlg::AddAnchors()
{
	AddAnchor(IDOK, BOTTOM_RIGHT);
	AddAnchor(IDCANCEL, BOTTOM_RIGHT);

	AddAnchor(IDC_NAME, TOP_LEFT, TOP_RIGHT);
	

	AddAnchor(IDC_ID, TOP_LEFT, CSize(25, 0));
	AddAnchor(IDC_STATIC_ID, TOP_LEFT);

	AddAnchor(IDC_VS, CSize(25, 0), CSize(50, 0));
	AddAnchor(IDC_STATIC_VS, CSize(25, 0), CSize(50, 0));

	AddAnchor(IDC_DEVELOPER, CSize(50, 0), CSize(75, 0));
	AddAnchor(IDC_STATIC_DEVELOPER, CSize(50, 0), CSize(75, 0));

	AddAnchor(IDC_SOURCE, CSize(75, 0), CSize(100, 0));
	AddAnchor(IDC_STATIC_SOURCE, CSize(75, 0), CSize(100, 0));	

	AddAnchor(IDC_STATIC_BORDER2, TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(m_pHTML->m_hWnd, TOP_LEFT, BOTTOM_RIGHT);

	AddAnchor(IDC_STATIC_NOTES, BOTTOM_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_NOTES, BOTTOM_LEFT, BOTTOM_RIGHT);			

	AddAnchor(IDC_LIST, CSize(0, 100), CSize(100, 100));
	AddAnchor(IDC_CHOOSE_SOURCE, TOP_RIGHT);
	AddAnchor(IDC_DEL_SOURCE, TOP_RIGHT);
	AddAnchor(IDC_DO_NOT_NEED, BOTTOM_LEFT);

	AddAnchorVirtual();
	return true;
}

void CRequirementPropertiesDlg::AddAnchorVirtual()
{
	AddAnchor(IDC_STATIC_BORDER4, CSize(0, 100), CSize(100, 100));
	AddAnchor(IDC_STATIC_BORDER3, CSize(0, 100), CSize(100, 100));
	AddAnchor(IDC_MOS, CSize(0, 100), CSize(25, 100));
	AddAnchor(IDC_STATIC_MOS, CSize(0, 100), CSize(25, 100));
	AddAnchor(IDC_CUR_STATE, CSize(25, 100), CSize(50, 100));
	AddAnchor(IDC_STATIC_STATE, CSize(25, 100), CSize(50, 100));
	AddAnchor(IDC_EV_DATE, CSize(50, 100), CSize(75, 100));
	AddAnchor(IDC_STATIC_EV, CSize(50, 100), CSize(75, 100));
	AddAnchor(IDC_EXECUTOR, CSize(75, 100), CSize(100, 100));
	AddAnchor(IDC_STATIC_EXECUTOR, CSize(75, 100), CSize(100, 100));
	AddAnchor(IDC_CHOOSE_EXEC, CSize(100, 100));
	AddAnchor(IDC_CLEAR_EXEC, CSize(100, 100));
}

void CRequirementPropertiesDlg::OnBnClickedFontColor()
{
	CColorDialog dlg;
	if(dlg.DoModal() == IDCANCEL) return;

	COLORREF cl = dlg.GetColor();

	CString red, green, blue;
	red.Format(_T("#%.2x"), GetRValue(cl));
	green.Format(_T("#%.2x"), GetGValue(cl));
	blue.Format(_T("#%.2x"), GetBValue(cl));

	m_pHTML->ExecHelperSetVal(IDM_FORECOLOR, red+green+blue);
}

bool CRequirementPropertiesDlg::SetNormalInterliage( CString &html )
{
	CString tmp = html;
	html = tmp;

	int nBodyOpen = html.Find(_T("<BODY"));
	if(nBodyOpen == -1) return false;

	int nBodyOpenLast = html.Find(_T(">"), nBodyOpen);
	if(nBodyOpenLast == -1) return false;

	html.Insert(nBodyOpenLast+1, _T("<DIV Style='LINE-HEIGHT:0'>"));

	int nBodyClose = html.Find(_T("</BODY>"));
	html.Insert(nBodyClose, _T("</DIV>"));
	
	m_pHTML->SetDocumentHTML(html);
	return true;
}

bool CRequirementPropertiesDlg::InitList()
{
	if(m_list.GetSafeHwnd())
	{
		CRect rect;
		m_list.GetClientRect(rect);

		m_list.InsertColumn(0,  APL_T("Документ"), LVCFMT_LEFT, (int)(rect.Width()*0.4));
		m_list.InsertColumn(1,  APL_T("Вид"), LVCFMT_LEFT, (int)(rect.Width()*0.3));
		m_list.InsertColumn(2,  APL_T("Состояние"), LVCFMT_LEFT, (int)(rect.Width()*0.3));

		m_list.SetImageList(aplGetInstImageList(), LVSIL_SMALL);
	}

	return true;
}

bool CRequirementPropertiesDlg::FillDocuments()
{
	if(!m_ciReq) return false;
	if(0 == m_list.GetSafeHwnd()) return false;

	aplExtent aeDocs, aeRels;
	CaplInstance *ciDoc = 0;

	m_api->m_doc_mgr.FindAssociatedDocuments(m_ciReq, aeDocs, aeRels);
	for(int i=0; i<aeRels.Size; i++)
	{
		if(!aeRels[i]) continue;

		m_api->m_data.GetAttr(aeRels[i], m_api->m_doc_mgr.a_apl_doc_ref_doc, ciDoc);
		if(!ciDoc) continue;

		int nIndex = AddDocument(ciDoc);		
		m_list.SetItemData(nIndex, (DWORD)aeRels[i]);
	}

	return true;
}

int CRequirementPropertiesDlg::AddDocument(CaplInstance *ciDoc)
{
	if(0 == m_list.GetSafeHwnd())
		return -1;

	CString buf;
	int icon = ICON_DOCUMENT;
	CaplInstance *ciKind, /**ciRev, *ciAuthor,*/ *ciLocker;

	// на редактировании ли
	m_api->m_data.GetAttr(ciDoc, m_api->m_doc_mgr.a_apl_doc_lock, ciLocker);
	if(ciLocker) icon = ICON_DOCUMENT_CHECKOUTED;

	// наименование
	buf=_T("");
	m_api->GetItemName(ciDoc, buf);
	int nIndex = m_list.InsertItem( m_list.GetItemCount(), buf, icon);

	// вид документа
	buf=_T("");
	m_api->m_data.GetAttr(ciDoc, m_api->m_doc_mgr.a_doc_kind, ciKind);
	if(ciKind) m_api->m_data.GetAttr(ciKind, m_api->m_doc_mgr.a_dt_pdt, buf);
	m_list.SetItemText(nIndex, 1, buf);	

	/*// автор активной версии
	buf=_T("");
	m_api->m_data.GetAttr(ciDoc, m_api->m_doc_mgr.a_apl_doc_active, ciRev);
	if(ciRev) 
	{
		m_api->m_data.GetAttr(ciRev, m_api->m_doc_mgr.a_apl_doc_rev_autor, ciAuthor);
		if(ciAuthor) m_api->GetItemName(ciAuthor, buf);
	}*/

	m_api->m_data.GetAttr(ciDoc, m_api->m_doc_mgr.a_apl_doc_wf_state, buf);
	buf=m_api->m_doc_mgr.GetWFStateName(buf);

	m_list.SetItemText(nIndex, 2, buf);
	m_list.SetItemData(nIndex, (DWORD)ciDoc);

	return nIndex;
}
void CRequirementPropertiesDlg::OnBnClickedClearExec()
{
	m_ciExecutor = 0;
	m_clear_exec.EnableWindow(FALSE);

	if(m_executorEdit.GetSafeHwnd())
		m_executorEdit.SetWindowText(_T(""));
}

void CRequirementPropertiesDlg::OnBnClickedChooseExec()
{
	CString str;
	aplExtent aeRoot;

	CaplInstance *ciExec = m_api->m_appr_mgr.SelectPersonOrOrganization(APL_MODE_SELECT_PERSON|APL_MODE_SELECT_ORG, aeRoot,  APL_T("Выбор исполнителя"),  APL_T("Выбор сотрудника"));
	if(!ciExec) return;

	m_ciExecutor = ciExec;
	m_api->m_appr_mgr.GetItemName(ciExec, str);
	m_clear_exec.EnableWindow(TRUE);

	if(m_executorEdit.GetSafeHwnd())
		m_executorEdit.SetWindowText(str);
}

HWND CRequirementPropertiesDlg::getParentWebBrowserWnd(HWND hMyWnd)
{
	HWND   hRetWBWnd = NULL;

	static TCHAR tszIEClass[] = _T("Internet Explorer_Server");
	TCHAR   tszClass[sizeof(tszIEClass)+1];

	// Compare if our window is of type IE class
	::GetClassName( hMyWnd,tszClass,sizeof(tszClass));
	if(0 == _tcscmp(tszClass, tszIEClass))
	{
		// Then get the Shell which hosts the IE doc view window

		hRetWBWnd = ::GetParent(::GetParent(hMyWnd));
	}
	return hRetWBWnd;
}

BOOL CRequirementPropertiesDlg::isThisOurBrowser(HWND hMyWnd)
{
	HWND hWndOurWebBrowser = (HWND)m_pHTML->GetSafeHwnd();
	// Get the Parent webbrowser window if any

	HWND hParentWBWnd = getParentWebBrowserWnd(hMyWnd);

	while(    (NULL != hParentWBWnd) &&
		(hParentWBWnd != hWndOurWebBrowser))
	{
		// Get the Parent of the Webbrowser window I have, recursively
		hParentWBWnd = getParentWebBrowserWnd(::GetParent(hParentWBWnd));
	}
	return (NULL != hParentWBWnd);
}

BOOL CRequirementPropertiesDlg::PreTranslateMessage( MSG* pMsg )
{
	if(m_pHTML)
	{
		if (WM_RBUTTONDOWN == pMsg->message || WM_RBUTTONDBLCLK == pMsg->message)			
		{
			// блокируем всплывающее меню
			if(isThisOurBrowser(pMsg->hwnd))
				return TRUE;	
		}
		else if(WM_KEYDOWN == pMsg->message)
		{
			// обрабатываем картинки в буфере обмена (пока оставим как есть)
			/*if (pMsg->wParam==_T('V') && GetKeyState(VK_CONTROL)<0)
			{
				MessageBox(_T("!"));
				return TRUE;
			}*/					
		}
	}

	return CaplResizableDialog::PreTranslateMessage(pMsg);
}

bool CRequirementPropertiesDlg::SetFiledsReadOnly()
{
	GetDlgItem(IDC_ID)->EnableWindow(FALSE);
	GetDlgItem(IDC_VS)->EnableWindow(FALSE);
	GetDlgItem(IDC_DEVELOPER)->EnableWindow(FALSE);
	GetDlgItem(IDC_SOURCE)->EnableWindow(FALSE);

	GetDlgItem(IDC_DO_NOT_NEED)->EnableWindow(FALSE);

	GetDlgItem(IDC_FONT_NAME)->EnableWindow(FALSE);
	GetDlgItem(IDC_FONT_SIZE)->EnableWindow(FALSE);

	GetDlgItem(IDC_CUT)->EnableWindow(FALSE);
	GetDlgItem(IDC_COPY)->EnableWindow(FALSE);
	GetDlgItem(IDC_PASTE)->EnableWindow(FALSE);
	
	GetDlgItem(IDC_BOLD)->EnableWindow(FALSE);
	GetDlgItem(IDC_ITALIC)->EnableWindow(FALSE);
	GetDlgItem(IDC_UNDERLINE)->EnableWindow(FALSE);

	GetDlgItem(IDC_UNDERLINE)->EnableWindow(FALSE);

	GetDlgItem(IDC_ALIGN_CENTER)->EnableWindow(FALSE);
	GetDlgItem(IDC_ALIGN_RIGHT)->EnableWindow(FALSE);
	GetDlgItem(IDC_ALIGN_LEFT)->EnableWindow(FALSE);

	GetDlgItem(IDC_IMAGE)->EnableWindow(FALSE);

	GetDlgItem(IDC_HTML)->EnableWindow(FALSE);
	GetDlgItem(IDC_NOTES)->EnableWindow(FALSE);

	if(m_MOS.GetSafeHwnd())
		m_MOS.EnableWindow(FALSE);
	if(m_stateEdit.GetSafeHwnd())
		m_stateEdit.EnableWindow(FALSE);
	if(m_evDateCtrl.GetSafeHwnd())
		m_evDateCtrl.EnableWindow(FALSE);
	if(m_executorEdit.GetSafeHwnd())
		m_executorEdit.EnableWindow(FALSE);
	if(m_choose_exec.GetSafeHwnd())
		m_choose_exec.EnableWindow(FALSE);
	if(m_clear_exec.GetSafeHwnd())
		m_clear_exec.EnableWindow(FALSE);

	GetDlgItem(IDC_CHOOSE_SOURCE)->EnableWindow(FALSE);
	GetDlgItem(IDC_DEL_SOURCE)->EnableWindow(FALSE);

	GetDlgItem(IDOK)->EnableWindow(FALSE);

	return true;
}
void CRequirementPropertiesDlg::OnBnClickedChooseSource()
{
	CaplInstance *ciReq = m_api->m_prd_mgr.SelectInstance(APL_MODE_SELECT_REQUIREMENT,  APL_T("Выбор источника для требования"));
	if(!ciReq) return;

	m_ciSource = ciReq;
	m_api->GetItemName(m_ciSource, m_sSourceName);
	GetDlgItem(IDC_SOURCE)->SetWindowText(m_sSourceName);

	m_del_source.EnableWindow(TRUE);
}

void CRequirementPropertiesDlg::OnBnClickedDelSource()
{
	m_ciSource = NULL;
	m_sSourceName=_T("");

	m_del_source.EnableWindow(FALSE);
	GetDlgItem(IDC_SOURCE)->SetWindowText(_T(""));
}
