#include "stdafx.h"
#include <comdef.h>	// For _bstr_t
#include "VisVim.h"
#include "Commands.h"
#include "OleAut.h"

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

#endif


// Change directory before opening file?
#define CD_SOURCE		0	// Cd to source path
#define CD_SOURCE_PARENT	1	// Cd to parent directory of source path
#define CD_NONE			2	// No cd


static BOOL g_bEnableVim = TRUE;	// Vim enabled
static BOOL g_bDevStudioEditor = FALSE;	// Open file in Dev Studio editor simultaneously
static BOOL g_bNewTabs = FALSE;
static int g_ChangeDir = CD_NONE;	// CD after file open?

static void VimSetEnableState(BOOL bEnableState);
static BOOL VimOpenFile(BSTR& FileName, long LineNr);
static DISPID VimGetDispatchId(COleAutomationControl& VimOle, char* Method);
static void VimErrDiag(COleAutomationControl& VimOle);
static void VimChangeDir(COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName);
static void DebugMsg(char* Msg, char* Arg = NULL);


/////////////////////////////////////////////////////////////////////////////
// CCommands

CCommands::CCommands()
{
	// m_pApplication == NULL; M$ Code generation bug!!!
	m_pApplication = NULL;
	m_pApplicationEventsObj = NULL;
	m_pDebuggerEventsObj = NULL;
}

CCommands::~CCommands()
{
	ASSERT(m_pApplication != NULL);
	if (m_pApplication)
	{
		m_pApplication->Release();
		m_pApplication = NULL;
	}
}

void CCommands::SetApplicationObject(IApplication * pApplication)
{
	// This function assumes pApplication has already been AddRef'd
	// for us, which CDSAddIn did in its QueryInterface call
	// just before it called us.
	m_pApplication = pApplication;
	if (! m_pApplication)
		return;

	// Create Application event handlers
	XApplicationEventsObj::CreateInstance(&m_pApplicationEventsObj);
	if (! m_pApplicationEventsObj)
	{
		ReportInternalError("XApplicationEventsObj::CreateInstance");
		return;
	}
	m_pApplicationEventsObj->AddRef();
	m_pApplicationEventsObj->Connect(m_pApplication);
	m_pApplicationEventsObj->m_pCommands = this;

#ifdef NEVER
	// Create Debugger event handler
	CComPtr < IDispatch > pDebugger;
	if (SUCCEEDED(m_pApplication->get_Debugger(&pDebugger))
	    && pDebugger != NULL)
	{
		XDebuggerEventsObj::CreateInstance(&m_pDebuggerEventsObj);
		m_pDebuggerEventsObj->AddRef();
		m_pDebuggerEventsObj->Connect(pDebugger);
		m_pDebuggerEventsObj->m_pCommands = this;
	}
#endif

	// Get settings from registry HKEY_CURRENT_USER\Software\Vim\VisVim
	HKEY hAppKey = GetAppKey("Vim");
	if (hAppKey)
	{
		HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
		if (hSectionKey)
		{
			g_bEnableVim = GetRegistryInt(hSectionKey, "EnableVim",
						       g_bEnableVim);
			g_bDevStudioEditor = GetRegistryInt(hSectionKey,
					"DevStudioEditor", g_bDevStudioEditor);
			g_bNewTabs = GetRegistryInt(hSectionKey, "NewTabs",
						    g_bNewTabs);
			g_ChangeDir = GetRegistryInt(hSectionKey, "ChangeDir",
						      g_ChangeDir);
			RegCloseKey(hSectionKey);
		}
		RegCloseKey(hAppKey);
	}
}

void CCommands::UnadviseFromEvents()
{
	ASSERT(m_pApplicationEventsObj != NULL);
	if (m_pApplicationEventsObj)
	{
		m_pApplicationEventsObj->Disconnect(m_pApplication);
		m_pApplicationEventsObj->Release();
		m_pApplicationEventsObj = NULL;
	}

#ifdef NEVER
	if (m_pDebuggerEventsObj)
	{
		// Since we were able to connect to the Debugger events, we
		// should be able to access the Debugger object again to
		// unadvise from its events (thus the VERIFY_OK below--see
		// stdafx.h).
		CComPtr < IDispatch > pDebugger;
		VERIFY_OK(m_pApplication->get_Debugger(&pDebugger));
		ASSERT(pDebugger != NULL);
		m_pDebuggerEventsObj->Disconnect(pDebugger);
		m_pDebuggerEventsObj->Release();
		m_pDebuggerEventsObj = NULL;
	}
#endif
}


/////////////////////////////////////////////////////////////////////////////
// Event handlers

// Application events

HRESULT CCommands::XApplicationEvents::BeforeBuildStart()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::BuildFinish(long nNumErrors, long nNumWarnings)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

// The open document event handle is the place where the real interface work
// is done.
// Vim gets called from here.
//
HRESULT CCommands::XApplicationEvents::DocumentOpen(IDispatch * theDocument)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if (! g_bEnableVim)
		// Vim not enabled or empty command line entered
		return S_OK;

	// First get the current file name and line number

	// Get the document object
	CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(theDocument);
	if (! pDoc)
		return S_OK;

	BSTR FileName;
	long LineNr = -1;

	// Get the document name
	if (FAILED(pDoc->get_FullName(&FileName)))
		return S_OK;

	LPDISPATCH pDispSel;

	// Get a selection object dispatch pointer
	if (SUCCEEDED(pDoc->get_Selection(&pDispSel)))
	{
		// Get the selection object
		CComQIPtr < ITextSelection, &IID_ITextSelection > pSel(pDispSel);

		if (pSel)
			// Get the selection line number
			pSel->get_CurrentLine(&LineNr);

		pDispSel->Release();
	}

	// Open the file in Vim and position to the current line
	if (VimOpenFile(FileName, LineNr))
	{
		if (! g_bDevStudioEditor)
		{
			// Close the document in developer studio
			CComVariant vSaveChanges = dsSaveChangesPrompt;
			DsSaveStatus Saved;

			pDoc->Close(vSaveChanges, &Saved);
		}
	}

	// We're done here
	SysFreeString(FileName);
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::BeforeDocumentClose(IDispatch * theDocument)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::DocumentSave(IDispatch * theDocument)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::NewDocument(IDispatch * theDocument)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if (! g_bEnableVim)
		// Vim not enabled or empty command line entered
		return S_OK;

	// First get the current file name and line number

	CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(theDocument);
	if (! pDoc)
		return S_OK;

	BSTR FileName;
	HRESULT hr;

	hr = pDoc->get_FullName(&FileName);
	if (FAILED(hr))
		return S_OK;

	// Open the file in Vim and position to the current line
	if (VimOpenFile(FileName, 0))
	{
		if (! g_bDevStudioEditor)
		{
			// Close the document in developer studio
			CComVariant vSaveChanges = dsSaveChangesPrompt;
			DsSaveStatus Saved;

			pDoc->Close(vSaveChanges, &Saved);
		}
	}

	SysFreeString(FileName);
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::WindowActivate(IDispatch * theWindow)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::WindowDeactivate(IDispatch * theWindow)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::WorkspaceOpen()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::WorkspaceClose()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

HRESULT CCommands::XApplicationEvents::NewWorkspace()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}

// Debugger event

HRESULT CCommands::XDebuggerEvents::BreakpointHit(IDispatch * pBreakpoint)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return S_OK;
}


/////////////////////////////////////////////////////////////////////////////
// VisVim dialog

class CMainDialog : public CDialog
{
    public:
	CMainDialog(CWnd * pParent = NULL);	// Standard constructor

	//{{AFX_DATA(CMainDialog)
	enum { IDD = IDD_ADDINMAIN };
	int	m_ChangeDir;
	BOOL	m_bDevStudioEditor;
	BOOL	m_bNewTabs;
	//}}AFX_DATA

	//{{AFX_VIRTUAL(CMainDialog)
    protected:
	virtual void DoDataExchange(CDataExchange * pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

    protected:
	//{{AFX_MSG(CMainDialog)
	afx_msg void OnEnable();
	afx_msg void OnDisable();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CMainDialog::CMainDialog(CWnd * pParent /* =NULL */ )
	: CDialog(CMainDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMainDialog)
	m_ChangeDir = -1;
	m_bDevStudioEditor = FALSE;
	m_bNewTabs = FALSE;
	//}}AFX_DATA_INIT
}

void CMainDialog::DoDataExchange(CDataExchange * pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMainDialog)
	DDX_Radio(pDX, IDC_CD_SOURCE_PATH, m_ChangeDir);
	DDX_Check(pDX, IDC_DEVSTUDIO_EDITOR, m_bDevStudioEditor);
	DDX_Check(pDX, IDC_NEW_TABS, m_bNewTabs);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
	//{{AFX_MSG_MAP(CMainDialog)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CCommands methods

STDMETHODIMP CCommands::VisVimDialog()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// Use m_pApplication to access the Developer Studio Application
	// object,
	// and VERIFY_OK to see error strings in DEBUG builds of your add-in
	// (see stdafx.h)

	VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));

	CMainDialog Dlg;

	Dlg.m_bDevStudioEditor = g_bDevStudioEditor;
	Dlg.m_bNewTabs = g_bNewTabs;
	Dlg.m_ChangeDir = g_ChangeDir;
	if (Dlg.DoModal() == IDOK)
	{
		g_bDevStudioEditor = Dlg.m_bDevStudioEditor;
		g_bNewTabs = Dlg.m_bNewTabs;
		g_ChangeDir = Dlg.m_ChangeDir;

		// Save settings to registry HKEY_CURRENT_USER\Software\Vim\VisVim
		HKEY hAppKey = GetAppKey("Vim");
		if (hAppKey)
		{
			HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
			if (hSectionKey)
			{
				WriteRegistryInt(hSectionKey, "DevStudioEditor",
						  g_bDevStudioEditor);
				WriteRegistryInt(hSectionKey, "NewTabs",
						  g_bNewTabs);
				WriteRegistryInt(hSectionKey, "ChangeDir", g_ChangeDir);
				RegCloseKey(hSectionKey);
			}
			RegCloseKey(hAppKey);
		}
	}

	VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
	return S_OK;
}

STDMETHODIMP CCommands::VisVimEnable()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	VimSetEnableState(true);
	return S_OK;
}

STDMETHODIMP CCommands::VisVimDisable()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	VimSetEnableState(false);
	return S_OK;
}

STDMETHODIMP CCommands::VisVimToggle()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	VimSetEnableState(! g_bEnableVim);
	return S_OK;
}

STDMETHODIMP CCommands::VisVimLoad()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// Use m_pApplication to access the Developer Studio Application object,
	// and VERIFY_OK to see error strings in DEBUG builds of your add-in
	// (see stdafx.h)

	CComBSTR bStr;
	// Define dispatch pointers for document and selection objects
	CComPtr < IDispatch > pDispDoc, pDispSel;

	// Get a document object dispatch pointer
	VERIFY_OK(m_pApplication->get_ActiveDocument(&pDispDoc));
	if (! pDispDoc)
		return S_OK;

	BSTR FileName;
	long LineNr = -1;

	// Get the document object
	CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(pDispDoc);

	if (! pDoc)
		return S_OK;

	// Get the document name
	if (FAILED(pDoc->get_FullName(&FileName)))
		return S_OK;

	// Get a selection object dispatch pointer
	if (SUCCEEDED(pDoc->get_Selection(&pDispSel)))
	{
		// Get the selection object
		CComQIPtr < ITextSelection, &IID_ITextSelection > pSel(pDispSel);

		if (pSel)
			// Get the selection line number
			pSel->get_CurrentLine(&LineNr);
	}

	// Open the file in Vim
	VimOpenFile(FileName, LineNr);

	SysFreeString(FileName);
	return S_OK;
}


//
// Here we do the actual processing and communication with Vim
//

// Set the enable state and save to registry
//
static void VimSetEnableState(BOOL bEnableState)
{
	g_bEnableVim = bEnableState;
	HKEY hAppKey = GetAppKey("Vim");
	if (hAppKey)
	{
		HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
		if (hSectionKey)
			WriteRegistryInt(hSectionKey, "EnableVim", g_bEnableVim);
		RegCloseKey(hAppKey);
	}
}

// Open the file 'FileName' in Vim and goto line 'LineNr'
// 'FileName' is expected to contain an absolute DOS path including the drive
// letter.
// 'LineNr' must contain a valid line number or 0, e. g. for a new file
//
static BOOL VimOpenFile(BSTR& FileName, long LineNr)
{

	// OLE automation object for com. with Vim
	// When the object goes out of scope, its destructor destroys the OLE
	// connection;
	// This is important to avoid blocking the object
	// (in this memory corruption would be likely when terminating Vim
	// while still running DevStudio).
	// So keep this object local!
	COleAutomationControl VimOle;

	// :cd D:/Src2/VisVim/
	//
	// Get a dispatch id for the SendKeys method of Vim;
	// enables connection to Vim if necessary
	DISPID DispatchId;
	DispatchId = VimGetDispatchId(VimOle, "SendKeys");
	if (! DispatchId)
		// OLE error, can't obtain dispatch id
		goto OleError;

	OLECHAR Buf[MAX_OLE_STR];
	char FileNameTmp[MAX_OLE_STR];
	char VimCmd[MAX_OLE_STR];
	char *s, *p;

	// Prepend CTRL-\ CTRL-N to exit insert mode
	VimCmd[0] = 0x1c;
	VimCmd[1] = 0x0e;
	VimCmd[2] = 0;

#ifdef SINGLE_WINDOW
	// Update the current file in Vim if it has been modified.
	// Disabled, because it could write the file when you don't want to.
	sprintf(VimCmd + 2, ":up\n");
#endif
	if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
		goto OleError;

	// Change Vim working directory to where the file is if desired
	if (g_ChangeDir != CD_NONE)
		VimChangeDir(VimOle, DispatchId, FileName);

	// Make Vim open the file.
	// In the filename convert all \ to /, put a \ before a space.
	if (g_bNewTabs)
	{
		sprintf(VimCmd, ":tab drop ");
		s = VimCmd + 10;
	}
	else
	{
		sprintf(VimCmd, ":drop ");
		s = VimCmd + 6;
	}
	sprintf(FileNameTmp, "%S", (char *)FileName);
	for (p = FileNameTmp; *p != '\0' && s < VimCmd + MAX_OLE_STR - 4; ++p)
		if (*p == '\\')
			*s++ = '/';
		else
		{
			if (*p == ' ')
				*s++ = '\\';
			*s++ = *p;
		}
	*s++ = '\n';
	*s = '\0';

	if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
		goto OleError;

	if (LineNr > 0)
	{
		// Goto line
		sprintf(VimCmd, ":%ld\n", LineNr);
		if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
			goto OleError;
	}

	// Make Vim come to the foreground
	if (! VimOle.Method("SetForeground"))
		VimOle.ErrDiag();

	// We're done
	return true;

    OleError:
	// There was an OLE error
	// Check if it's the "unknown class string" error
	VimErrDiag(VimOle);
	return false;
}

// Return the dispatch id for the Vim method 'Method'
// Create the Vim OLE object if necessary
// Returns a valid dispatch id or null on error
//
static DISPID VimGetDispatchId(COleAutomationControl& VimOle, char* Method)
{
	// Initialize Vim OLE connection if not already done
	if (! VimOle.IsCreated())
	{
		if (! VimOle.CreateObject("Vim.Application"))
			return NULL;
	}

	// Get the dispatch id for the SendKeys method.
	// By doing this, we are checking if Vim is still there...
	DISPID DispatchId = VimOle.GetDispatchId("SendKeys");
	if (! DispatchId)
	{
		// We can't get a dispatch id.
		// This means that probably Vim has been terminated.
		// Don't issue an error message here, instead
		// destroy the OLE object and try to connect once more
		//
		// In fact, this should never happen, because the OLE aut. object
		// should not be kept long enough to allow the user to terminate Vim
		// to avoid memory corruption (why the heck is there no system garbage
		// collection for those damned OLE memory chunks???).
		VimOle.DeleteObject();
		if (! VimOle.CreateObject("Vim.Application"))
			// If this create fails, it's time for an error msg
			return NULL;

		if (! (DispatchId = VimOle.GetDispatchId("SendKeys")))
			// There is something wrong...
			return NULL;
	}

	return DispatchId;
}

// Output an error message for an OLE error
// Check on the classstring error, which probably means Vim wasn't registered.
//
static void VimErrDiag(COleAutomationControl& VimOle)
{
	SCODE sc = GetScode(VimOle.GetResult());
	if (sc == CO_E_CLASSSTRING)
	{
		char Buf[256];
		sprintf(Buf, "There is no registered OLE automation server named "
			 "\"Vim.Application\".\n"
			 "Use the OLE-enabled version of Vim with VisVim and "
			 "make sure to register Vim by running \"vim -register\".");
		MessageBox(NULL, Buf, "OLE Error", MB_OK);
	}
	else
		VimOle.ErrDiag();
}

// Change directory to the directory the file 'FileName' is in or its parent
// directory according to the setting of the global 'g_ChangeDir':
// 'FileName' is expected to contain an absolute DOS path including the drive
// letter.
//	CD_NONE
//	CD_SOURCE_PATH
//	CD_SOURCE_PARENT
//
static void VimChangeDir(COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName)
{
	// Do a :cd first

	// Get the path name of the file ("dir/")
	CString StrFileName = FileName;
	char Drive[_MAX_DRIVE];
	char Dir[_MAX_DIR];
	char DirUnix[_MAX_DIR * 2];
	char *s, *t;

	_splitpath(StrFileName, Drive, Dir, NULL, NULL);

	// Convert to Unix path name format, escape spaces.
	t = DirUnix;
	for (s = Dir; *s; ++s)
		if (*s == '\\')
			*t++ = '/';
		else
		{
			if (*s == ' ')
				*t++ = '\\';
			*t++ = *s;
		}
	*t = '\0';


	// Construct the cd command; append /.. if cd to parent
	// directory and not in root directory
	OLECHAR Buf[MAX_OLE_STR];
	char VimCmd[MAX_OLE_STR];

	sprintf(VimCmd, ":cd %s%s%s\n", Drive, DirUnix,
		 g_ChangeDir == CD_SOURCE_PARENT && DirUnix[1] ? ".." : "");
	VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf));
}

#ifdef _DEBUG
// Print out a debug message
//
static void DebugMsg(char* Msg, char* Arg)
{
	char Buf[400];
	sprintf(Buf, Msg, Arg);
	AfxMessageBox(Buf);
}
#endif
