// EditMultiLine.cpp : implementation file
//

#include "stdafx.h"
#include "mushclient.h"
#include "mainfrm.h"
#include "EditMultiLine.h"
#include "winplace.h"
#include "GoToLineDlg.h"

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

#define CLEAR_SELECTION 10200

/////////////////////////////////////////////////////////////////////////////
// CEditMultiLine dialog


CEditMultiLine::CEditMultiLine(CWnd* pParent /*=NULL*/)
	: CDialog(CEditMultiLine::IDD, pParent)
{
	//{{AFX_DATA_INIT(CEditMultiLine)
	m_strText = _T("");
	//}}AFX_DATA_INIT

  m_font = NULL;
  m_bScript = false;
  m_bLua = false;

}


void CEditMultiLine::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CEditMultiLine)
	DDX_Control(pDX, IDC_GOTO_LINE, m_ctlGoToLineButton);
	DDX_Control(pDX, IDC_COMPLETE_WORD, m_ctlCompleteFunctionButton);
	DDX_Control(pDX, IDC_FUNCTION_LIST, m_ctlFunctionListButton);
	DDX_Control(pDX, IDOK, m_ctlOK);
	DDX_Control(pDX, IDCANCEL, m_ctlCancel);
	DDX_Control(pDX, IDC_TEXT, m_ctlText);
	DDX_Text(pDX, IDC_TEXT, m_strText);
	//}}AFX_DATA_MAP

 if(!pDX->m_bSaveAndValidate)
   FixFont (m_font, m_ctlText, MUSHCLIENT_DEFAULT_FONT, 9, FW_NORMAL, DEFAULT_CHARSET);

}


BEGIN_MESSAGE_MAP(CEditMultiLine, CDialog)
	//{{AFX_MSG_MAP(CEditMultiLine)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_FUNCTION_LIST, OnFunctionList)
	ON_BN_CLICKED(IDC_COMPLETE_WORD, OnCompleteWord)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_GOTO_LINE, OnGotoLine)
	//}}AFX_MSG_MAP

  ON_COMMAND(CLEAR_SELECTION, OnRemoveSelection)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEditMultiLine message handlers



void CEditMultiLine::OnSize(UINT nType, int cx, int cy) 
  {
	CDialog::OnSize(nType, cx, cy);
	
  if (m_ctlText.m_hWnd && 
      m_ctlCancel.m_hWnd && 
      m_ctlFunctionListButton.m_hWnd &&
      m_ctlCompleteFunctionButton.m_hWnd &&
      m_ctlGoToLineButton.m_hWnd &&
      m_ctlOK)
    {
    // move OK and Cancel buttons
    WINDOWPLACEMENT wndpl;
    int iHeight;
    int iWidth;
    int iBorder = 10;

    const int iButtonCount = 5; // how many buttons

    // -----------------------
    // where is OK button?
    GetButtonSize (m_ctlOK, iHeight, iWidth);

    // move to near bottom

    m_ctlOK.MoveWindow (iBorder, cy - iHeight - 10, iWidth, iHeight);


    // ------------------------

    // calculate gaps for middle buttons - I will assume all buttons are the same size here

    // gap (between OK and cancel buttons) will be the width of the dialog
    // less the gaps on the side of those buttons, less the width of the iButtonCount buttons themselves

    int iGap = cx - (iBorder * 2) - (iWidth * iButtonCount);

    // we need (iButtonCount - 1) gaps:  OK --1-- Functions --2-- Complete --3-- GoToLine --4-- Cancel
    iGap /= iButtonCount - 1;

    // -----------------------

    // where is functions button?
    GetButtonSize (m_ctlFunctionListButton, iHeight, iWidth);

    // move to near bottom (need to allow 1 border, 1 gap and the width of the OK button)

    m_ctlFunctionListButton.MoveWindow (iBorder + iWidth + iGap, cy - iHeight - 10, iWidth, iHeight);

    // -----------------------

    // where is complete function button?
    GetButtonSize (m_ctlCompleteFunctionButton, iHeight, iWidth);

    // move to near bottom
    // need to allow 1 border, 2 gaps, and the width of 2 buttons

    m_ctlCompleteFunctionButton.MoveWindow (iBorder + (iWidth * 2) + (iGap * 2), cy - iHeight - 10, iWidth, iHeight);

    // where is GoToLine button?
    GetButtonSize (m_ctlGoToLineButton, iHeight, iWidth);

    // move to near bottom
    // need to allow 1 border, 3 gaps, and the width of 3 buttons

    m_ctlGoToLineButton.MoveWindow (iBorder + (iWidth * 3) + (iGap * 3), cy - iHeight - 10, iWidth, iHeight);

    // -----------------------
    // where is Cancel button?
    GetButtonSize (m_ctlCancel, iHeight, iWidth);

    // move to near bottom

    m_ctlCancel.MoveWindow (cx - iWidth - iBorder, cy - iHeight - 10, iWidth, iHeight);

    // -----------------------
    // where is Cancel button now?
    m_ctlCancel.GetWindowPlacement (&wndpl);

    // move text to just above it
	  m_ctlText.MoveWindow(0, 0, cx, wndpl.rcNormalPosition.top - 10);
    }

  }

BOOL CEditMultiLine::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
  CWindowPlacement wp;
  wp.Restore ("Edit MultiLine Dialog", this, false);

  if (!m_strTitle.IsEmpty ())
    SetWindowText (m_strTitle);	
	
  PostMessage (WM_COMMAND, CLEAR_SELECTION);

  if (!m_bScript)
    {
    m_ctlFunctionListButton.ShowWindow (SW_HIDE); 
    m_ctlCompleteFunctionButton.ShowWindow (SW_HIDE);
    m_ctlGoToLineButton.ShowWindow (SW_HIDE);
    }

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

void CEditMultiLine::OnRemoveSelection()
  {

  m_ctlText.SetSel (m_strText.GetLength (), m_strText.GetLength ());

  }

void CEditMultiLine::OnFunctionList() 
{
int nStartChar,
    nEndChar;
CString strSelection;

  // find the selection range
  m_ctlText.GetSel(nStartChar, nEndChar);
  // get window text
  m_ctlText.GetWindowText (strSelection);

  ShowFunctionslist (strSelection, nStartChar, nEndChar, m_bLua);
}

void CEditMultiLine::OnCompleteWord() 
{
  FunctionMenu (m_ctlText, m_bScript && m_bLua);
}

void CEditMultiLine::OnDestroy() 
{
	CDialog::OnDestroy();
	
  CWindowPlacement wp;
  wp.Save ("Edit MultiLine Dialog", this);
	
}

void CEditMultiLine::OnGotoLine() 
{
CGoToLineDlg dlg;

  dlg.m_iMaxLine = 	m_ctlText.GetLineCount ();

  // default to the current line number
  dlg.m_iLineNumber = m_ctlText.LineFromChar () + 1;

  if (dlg.DoModal () != IDOK)
    return;

  // find position in file - this needs to be zero-relative
  int iIndex = m_ctlText.LineIndex (dlg.m_iLineNumber - 1);

  if (iIndex == -1)
    return;   // failed to find position

  // go to the start of that line
  m_ctlText.SetSel(iIndex, iIndex);
	
  // ensure text box has the focus if you click on the button
  m_ctlText.SetFocus ();

}
