// DlgQlLang.cpp : implementation file
//

#include "stdafx.h"
#include "aplNetStepData.h"
#include <apl_gui.h>
#include <aplAggr.h>
#include "DlgQlLang.h"
#include "HelpText.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDlgQlLang dialog


CDlgQlLang::CDlgQlLang(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CDlgQlLang::IDD, pParent),query(0)
{
	//{{AFX_DATA_INIT(CDlgQlLang)
	m_lng_query = _T("");
	m_NameQuery = _T("");
	m_IsSave2BD = FALSE;
	m_IsMakeTable = FALSE;
	//}}AFX_DATA_INIT
	m_hStepData = 0;
	m_is_parsed = false;
	m_is_ro = false;
	m_only_ro = false;
	m_can_save2bd = false;
}

CDlgQlLang::~CDlgQlLang()
{
}


void CDlgQlLang::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgQlLang)
	DDX_Control(pDX, IDC_CHK_MAKE_TABLE_RESULT, m_ChkMakeTable);
	DDX_Control(pDX, IDC_CHECK_SAVE2BD, m_ChkSave2BD);
	DDX_Control(pDX, IDC_EDIT_NAME, m_EditQueryName);
	DDX_Control(pDX, IDC_STATIC_NAME, m_StName);
	DDX_Control(pDX, IDC_BEGIN_EDIT, m_btn_edit);
	DDX_Control(pDX, IDC_HELP_LANG, m_btn_help_lang);
	DDX_Control(pDX, IDRUN, m_btn_run);
	DDX_Control(pDX, IDCANCEL, m_btn_cancel);
	DDX_Control(pDX, IDC_BTN_SAVE_FFILE, m_btn_save);
	DDX_Control(pDX, IDC_BTN_LOAD_FFILE, m_btn_load);
	DDX_Control(pDX, IDC_BTN_CUT, m_btn_cut);
	DDX_Control(pDX, IDC_BTN_COPY, m_btn_copy);
	DDX_Control(pDX, IDC_BTN_PASTE, m_btn_paste);
	DDX_Control(pDX, IDC_STATUS_QL_LANG, m_StatusQlLang);
	DDX_Control(pDX, IDC_EDT_QL_LANG, m_EdtQlLang);
	DDX_Text(pDX, IDC_EDT_QL_LANG, m_lng_query);
	DDX_Text(pDX, IDC_EDIT_NAME, m_NameQuery);
	DDX_Check(pDX, IDC_CHECK_SAVE2BD, m_IsSave2BD);
	DDX_Check(pDX, IDC_CHK_MAKE_TABLE_RESULT, m_IsMakeTable);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgQlLang, CaplResizableDialog)
	//{{AFX_MSG_MAP(CDlgQlLang)
	ON_BN_CLICKED(IDC_BTN_LOAD_FFILE, OnBtnLoadFfile)
	ON_BN_CLICKED(IDRUN, OnRun)
	ON_WM_CANCELMODE()
	ON_NOTIFY(EN_SELCHANGE, IDC_EDT_QL_LANG, OnSelchangeEdtQlLang)
	ON_BN_CLICKED(IDC_BTN_SAVE_FFILE, OnBtnSaveFfile)
	ON_BN_CLICKED(IDC_HELP_LANG, OnHelpLang)
	ON_BN_CLICKED(IDC_BEGIN_EDIT, OnEdit)
	ON_BN_CLICKED(IDC_BTN_COPY, OnBtnCopy)
	ON_BN_CLICKED(IDC_BTN_PASTE, OnBtnPaste)
	ON_BN_CLICKED(IDC_BTN_CUT, OnBtnCut)
	ON_BN_CLICKED(IDC_CHECK_SAVE2BD, OnCheckSave2bd)
	ON_WM_CONTEXTMENU()
	//}}AFX_MSG_MAP
	//ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipShow)
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgQlLang message handlers

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

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

	// TODO: Add extra initialization here
	EnableToolTips(TRUE);
	

	m_btn_run.SetIcon(GetAplTableIco(APL_TABLE_RUN));
	m_btn_cancel.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_btn_help_lang.SetIcon(GetAplStdIco16(APLSTDICO_QUERY));
	m_btn_save.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	m_btn_load.SetIcon(GetAplTableIco(APL_TABLE_OPEN));
	m_btn_edit.SetIcon(GetAplTableIco(APL_TABLE_EDIT));
	m_btn_cut.SetIcon(GetAplTableIco(APL_TABLE_CUT));
	m_btn_copy.SetIcon(GetAplTableIco(APL_TABLE_COPY));
	m_btn_paste.SetIcon(GetAplTableIco(APL_TABLE_PASTE));

	m_EditQueryName.EnableWindow(m_can_save2bd);
	m_StName.EnableWindow(m_can_save2bd);
	m_ChkSave2BD.EnableWindow(m_can_save2bd && !m_IsSave2BD);
	m_ChkMakeTable.EnableWindow(m_can_save2bd);

	m_statusbar.Create(WS_VISIBLE |WS_CHILD |CCS_BOTTOM|SBARS_SIZEGRIP, CRect(0,0,0,0),this,IDC_STATUS_BAR);

	AddAnchor(IDRUN,TOP_LEFT);
	AddAnchor(IDCANCEL,TOP_LEFT);
	AddAnchor(IDC_BTN_SAVE_FFILE,TOP_LEFT);
	AddAnchor(IDC_BEGIN_EDIT,TOP_LEFT);
	AddAnchor(IDC_HELP_LANG,TOP_LEFT);
	AddAnchor(IDC_BTN_SAVE_FFILE,TOP_LEFT);
	AddAnchor(IDC_BTN_LOAD_FFILE,TOP_LEFT);
	AddAnchor(IDC_BTN_CUT,TOP_LEFT);
	AddAnchor(IDC_BTN_COPY,TOP_LEFT);
	AddAnchor(IDC_BTN_PASTE,TOP_LEFT);
	AddAnchor(IDC_EDIT_NAME,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_EDIT_NAME,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_CHK_MAKE_TABLE_RESULT,TOP_RIGHT);
	AddAnchor(IDC_STATIC_NAME,TOP_LEFT);
	AddAnchor(IDC_EDT_QL_LANG,TOP_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDC_STATUS_QL_LANG,BOTTOM_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDC_STATUS_BAR,BOTTOM_LEFT,BOTTOM_RIGHT);

	SetState();
	
	if(m_hStepData== 0)return false;

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

	query.m_data=m_hStepData;
	m_EdtQlLang.SetEventMask(m_EdtQlLang.GetEventMask() |ENM_SELCHANGE | ENM_MOUSEEVENTS);

	CRect rect;
	m_statusbar.GetClientRect(&rect);
	const int nParts = 3;
	int widths[nParts] = { rect.right-200, rect.right-100, -1 };
	m_statusbar.SetParts(nParts, widths);


	// Установим шрифт для окна запросов и окна сообщений
	m_cf.dwMask = CFM_FACE|CFM_SIZE;

	_sprintf(m_cf.szFaceName, _T("Courier New"));
	m_cf.yHeight=180;
	m_EdtQlLang.SetDefaultCharFormat(m_cf);
	m_StatusQlLang.SetDefaultCharFormat(m_cf);

	if(m_lng_query == _T(""))
	{
		m_lng_query = _T("SELECT\n")
			_T("	Ext\n")
			_T("FROM\n")
			_T("	Ext {product.id='12345'}\n")
			_T("END_SELECT");
	}

	m_dlg_selectEA.m_data=m_hStepData;
	m_dlg_selectEA.m_parent=this;



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


void CDlgQlLang::OnBtnLoadFfile()
{
	// TODO: Add your control notification handler code here
	//Определяем что за файл
	UpdateData(TRUE);
	CFileDialog* dlg;
	CString filter= APL_T("Все файлы (*.*)|*.*||");
	dlg=new CFileDialog(TRUE,_T(""),
		0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST,
		filter,this);
	if(dlg->DoModal()==IDCANCEL){
		delete dlg;
		return;
	};
	CFile file;
	file.Open(dlg->GetPathName(),CFile::modeRead);
	int len=(int)file.GetLength();
	char* buf=new char[len+1];//UUUU здесь надо как-то определять что текст в файле A или W
	file.Read(buf,len);
	buf[len] = 0;
	m_lng_query=buf;
	delete []buf;
	delete dlg;
	UpdateData(FALSE);
	m_is_ro = false;
	SetState();
}

void CDlgQlLang::OnBtnSaveFfile() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	CFileDialog *dlg;
	CString filter= APL_T("Все файлы (*.*)|*.*||");
	dlg=new CFileDialog(FALSE,_T(""),
		0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |OFN_CREATEPROMPT,
		filter,this);
	if(dlg->DoModal()==IDCANCEL){
		delete dlg;
		return;
	};
	CFile file;
	file.Open(dlg->GetPathName(),CFile::modeWrite|CFile::modeCreate);
	CString buf;
	m_EdtQlLang.GetWindowText(buf);
	file.Write(buf,buf.GetLength());
	file.Close();
	delete dlg;
	UpdateData(FALSE);
	
}

void CDlgQlLang::OnOK() 
{
	// TODO: Add extra validation here
	CDialog::OnOK();
}

void CDlgQlLang::OnRun() 
{
	// TODO: Add extra validation here
	UpdateData(TRUE);
	CString str,str1;
	int pos = 0,str_num = 0,i1 = 0,i2 = 0;
	m_EdtQlLang.GetWindowText(str);
	str1=str;

	query.parse(str1);
	if(!query.m_is_parse){
		str=query.GetLastError(str_num,pos,&i1,&i2);
		str1.Format( APL_T("Ошибка в строке %i позиция %i :%s"),str_num,pos,(LPCTSTR)str);
		m_StatusQlLang.SetWindowText(str1);

		long char_line_begin = 0;
		// All function with m_EdtQlLang zero based!!!
		char_line_begin=m_EdtQlLang.LineIndex(str_num-1);
		m_EdtQlLang.SetSel(char_line_begin+pos-1-i2,char_line_begin+pos-1);
		m_EdtQlLang.SetFocus();

		//AfxMessageBox(str1);
		return;
	}
	m_is_parsed = true;
	OnOK();
}

void CDlgQlLang::OnCancelMode() 
{
	CDialog::OnCancelMode();
	
	// TODO: Add your message handler code here
	
}

void CDlgQlLang::OnSelchangeEdtQlLang(NMHDR* pNMHDR, LRESULT* pResult) 
{
	SELCHANGE *pSelChange = reinterpret_cast<SELCHANGE *>(pNMHDR);
	// TODO: The control will not send this notification unless you override the
	// CDialog::OnInitDialog() function to send the EM_SETEVENTMASK message
	// to the control with the ENM_SELCHANGE flag ORed into the lParam mask.
	
	// TODO: Add your control notification handler code here
	*pResult = 0;
	CString str;
	long char_sel_beg = 0,char_sel_end = 0,char_line_begin = 0,line = 0,char_in_line = 0;
	// All function result zero based!!!
	m_EdtQlLang.GetSel(char_sel_beg,char_sel_end);
	char_line_begin=m_EdtQlLang.LineIndex();
	line=m_EdtQlLang.LineFromChar(-1);
	// 
	char_in_line=char_sel_beg-char_line_begin;
	str.Format( APL_T("Строка: %i"),line+1);
	m_statusbar.SetText(str,1,0);
	str.Format( APL_T("Позиция: %i"),char_in_line+1);
	m_statusbar.SetText(str,2,0);
}




UINT HelpQLThread(LPVOID lpParameter)
{
	CDialog* dlg=(CDialog*)lpParameter;
	dlg->DoModal();
	return 0;
}


void CDlgQlLang::OnHelpLang() 
{
	// TODO: Add your control notification handler code here
/*	CHelpText dlg;
	dlg.m_header="О языке запросов...";
	HRSRC resource=FindResource(module_inst,MAKEINTRESOURCE(IDR_HELP_QL),"RTF");

	DWORD size_res=SizeofResource(module_inst,resource);
	HGLOBAL h_rtf=LoadResource(module_inst,resource);
	dlg.m_dbuf.Add(h_rtf,size_res);
	
	//	AfxBeginThread(HelpQLThread,(LPVOID)&dlg);
	HelpQLThread((LPVOID)&dlg);
*/
	CString path2file = _T(""), commandline = _T("hh.exe mk:@MSITStore:");
	int index;
	CWinApp* app=AfxGetApp();
	if(app != 0)
	{
		path2file=app->m_pszHelpFilePath;
		index=path2file.ReverseFind(_T('\\')) + 1;
		path2file.Delete(index,path2file.GetLength()-index);
		//commandline="hh.exe mk:@MSITStore:"+path2file+"Doc\\STEP_QL_d.chm::/STEP_QL_d.htm";
		path2file += _T("Doc\\API\\APL_API.chm"); 
	}
	else
	{
		//commandline="hh.exe mk:@MSITStore:C:\\Program%20Files\\PSS\\Doc\\STEP_QL_d.chm::/STEP_QL_d.htm";
		path2file = _T("hh.exe mk:@MSITStore:C:\\Program%20Files\\PSS\\Doc\\API\\APL_API.chm");
	}
	// проверка наличия файла
	FILE* f = _fopen(path2file, _T("rb"));
	if(f== 0)
	{
		AfxMessageBox( APL_T("Не найден файл справки\n") + path2file +
					   APL_T("\nУстановите руководство \n разработчика из дистрибутива"));
	}
	else
	{
		fclose(f);
		commandline += path2file + _T("::/step_ql_d.htm");
#ifdef _UNICODE
		CaplStringAdapter str_ad((LPCTSTR)commandline);
		UINT res = WinExec((const char*)str_ad, SW_SHOWNORMAL);
#else // #ifdef _UNICODE
		UINT res = WinExec(commandline, SW_SHOWNORMAL);
#endif // #ifdef _UNICODE
	}
}

// ЯАИ:  Перенесено в CaplTranslateDialog
/*BOOL CDlgQlLang::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);
		tooltip_text = CaplTranslate::Translate(tooltip_text);
		_strncpy(pTTT->szText, tooltip_text.GetBuffer(), 79);
		pTTT->szText[79] = _T('\0');
//		pTTT->lpszText = _tcsdup(tooltip_text);

		//pTTT->lpszText = MAKEINTRESOURCE(nID);
		//pTTT->hinst = AfxGetResourceHandle();
		return(true);
	}
	return false;
}
*/


void CDlgQlLang::OnEdit() 
{
	// TODO: Add your control notification handler code here
	if(AfxMessageBox( APL_T("При изменении текста запроса вручную Вы не сможете\n вернуться в диалог свойств запроса. Продолжить?\n")
					,MB_YESNO)==IDNO) return;
	m_is_ro = false;
	SetState();
	m_EdtQlLang.SetFocus();
}

void CDlgQlLang::SetState() 
{
	m_btn_edit.EnableWindow(m_is_ro && !m_only_ro);
	m_EdtQlLang.SetReadOnly(m_is_ro);
	m_btn_load.EnableWindow(!m_is_ro);
	m_EditQueryName.SetReadOnly(m_only_ro);
}


void CDlgQlLang::OnBtnCopy() 
{
	// TODO: Add your control notification handler code here
	m_EdtQlLang.Copy();
	m_EdtQlLang.SetFocus();
	
}

void CDlgQlLang::OnBtnPaste() 
{
	// TODO: Add your control notification handler code here
	m_EdtQlLang.Paste();
	m_EdtQlLang.SetFocus();
	
}


void CDlgQlLang::OnBtnCut() 
{
	// TODO: Add your control notification handler code here
	m_EdtQlLang.Cut();
	m_EdtQlLang.SetFocus();
}

void CDlgQlLang::OnCheckSave2bd() 
{
	// TODO: Add your control notification handler code here
}


void CDlgQlLang::OnContextMenu(CWnd* pWnd, CPoint point) 
{

	CaplMenu up_menu;
	up_menu.LoadMenu(IDR_CONTEXT_MENU);
    CMenu* pPopup = up_menu.GetSubMenu(1);
	
	if(m_is_ro)
	{
		pPopup->EnableMenuItem(IDC_BTN_CUT, MF_BYCOMMAND | MF_GRAYED);
		pPopup->EnableMenuItem(IDC_BTN_PASTE, MF_BYCOMMAND | MF_GRAYED);
		pPopup->EnableMenuItem(IDC_BTN_SELECT_OBJECT, MF_BYCOMMAND | MF_GRAYED);
	}

	if(point.x==-1 && point.y==-1){
		// надо определить текущую позицию мышки - меню вызывают с клавиатуры
		GetCursorPos(&point);
	}
	
	//m_EdtQlLang.ClientToScreen(&point);
	int res = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON|TPM_RETURNCMD ,
		point.x, point.y,this);	

	switch(res)
	{
	case IDC_BTN_CUT:
		{
			OnBtnCut();
		}
		break;
	case IDC_BTN_COPY:
		{
			OnBtnCopy();
		}
		break;
	case IDC_BTN_PASTE:
		{
			OnBtnPaste();
		}
		break;
	case IDC_BTN_SELECT_OBJECT:
		{
			SelectInsertEntAttr();
		}
		break;
	}
}

void CDlgQlLang::SelectInsertEntAttr() 
{
	m_dlg_selectEA.StartDialog();
}

void CDlgQlLang::ReplaceSel(CString &text) 
{
	long nStartChar, nEndChar;
	if(text != _T(""))
	{
		m_EdtQlLang.GetSel(nStartChar, nEndChar );
		m_EdtQlLang.ReplaceSel(text);
		m_EdtQlLang.SetSel(nStartChar, nStartChar+text.GetLength());
	}
}

void CDlgQlLang::GetSel(CString &str)
{
	str = m_EdtQlLang.GetSelText();
}


void CDlgQlLang::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: Add your message handler code here and/or call default
	
	UINT aChar = nChar;

	CaplResizableDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

BOOL CDlgQlLang::PreTranslateMessage(MSG* pMsg)
{
	CString str1;
	// TODO: Add your specialized code here and/or call the base class
	if (pMsg->message == WM_SYSKEYDOWN)
	{
		//str1.Format("WM_SYSKEYDOWN! message %i, lParam %i, wParam %i, pt %i, time  %i",pMsg->message,pMsg->lParam,pMsg->wParam,pMsg->pt,pMsg->time);
		//m_StatusQlLang.SetWindowText(str1);
	}
	else if (pMsg->message == WM_KEYDOWN)
	{
		//str1.Format("WM_KEYDOWN! message %i, lParam %i, wParam %i, pt %i, time  %i",pMsg->message,pMsg->lParam,pMsg->wParam,pMsg->pt,pMsg->time);
		//m_StatusQlLang.SetWindowText(str1);
		if(pMsg->wParam==VK_F8)
		{
			OnRun();
			return 0;
		}
	}else{
		//str1="_ ";//
	}

	return CDialog::PreTranslateMessage(pMsg);
}