/*
*********************************************************************
*
*	The Essence of OLE
*
*	Source code sample
*
*	Copyright (c) 1996, Rolling Thunder Computing, Ipswich MA
*
*	e-mail: essence@rollthunder.com
*	CompuServe: 73540,3430
*	Web: http://www.rollthunder.com
*
*********************************************************************
*/

#include <windows.h>
#include "scriptengine.h"
#include "scriptthread.h"

CScriptEngine::CScriptEngine(void)
{
	m_RefCount = 1 ;
	m_pActiveSite = NULL ;
	m_pScriptText = NULL ;
}

CScriptEngine::~CScriptEngine(void)
{

}


STDMETHODIMP CScriptEngine::SetScriptSite(IActiveScriptSite *pass)
{
	MessageBox (NULL, "SetSite", "", 0) ;
	if (pass)
	{
		m_pActiveSite = pass ;
		m_pActiveSite->AddRef ( ) ;
	}
	return S_OK ;
}

STDMETHODIMP CScriptEngine::GetScriptSite(REFIID riid, void **ppv)
{
	MessageBox (NULL, "GetSite", "", 0) ;
	if (m_pActiveSite)
	{
		return m_pActiveSite->QueryInterface (riid, ppv) ;
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE ;
	}
}


STDMETHODIMP CScriptEngine::SetScriptState(SCRIPTSTATE ss) 
{
	 m_ss = ss ;
	MessageBox (NULL, "SetState", "", 0) ;

/*
Told to connect script. Spin off a thread to execute it.
*/
	 if (m_ss == SCRIPTSTATE_CONNECTED)
	 {
		DWORD dwId ;

		HANDLE hThread = CreateThread (NULL, 0, ScriptThreadFunc,
			this, 0, &dwId) ;

		CloseHandle (hThread) ;
	 }

	 return S_OK ;
}

STDMETHODIMP CScriptEngine::GetScriptState(SCRIPTSTATE *pssState)
{
	MessageBox (NULL, "GetState", "", 0) ;
	if (*pssState)
	{
		*pssState = m_ss ;
	}

	return S_OK ;
}

STDMETHODIMP CScriptEngine::Close(void)
{
	MessageBox (NULL, "Close", "", 0) ;
	if (m_pActiveSite)
	{
		m_pActiveSite->Release ( ) ;
		m_pActiveSite = NULL ;
	}
	return S_OK ;
}

STDMETHODIMP CScriptEngine::AddNamedItem(LPCOLESTR pstrName, DWORD dwFlags)
{
	MessageBox (NULL, "AddItem", "", 0) ;
	return S_OK ;
}

STDMETHODIMP CScriptEngine::AddTypeLib(REFGUID rguidTypeLib, DWORD dwMajor, DWORD dwMinor, DWORD dwFlags) 
{
	MessageBox (NULL, "AddTypeLib", "", 0) ;
	return S_OK ;
}

STDMETHODIMP CScriptEngine::GetScriptDispatch(LPCOLESTR pstrItemName, IDispatch **ppdisp) 
{
	MessageBox (NULL, "GetScriptDispatch", "ScriptEngine", 0) ;
	*ppdisp = NULL ;
	return E_NOTIMPL ;
}

STDMETHODIMP CScriptEngine::GetCurrentScriptThreadID(SCRIPTTHREADID *pstidThread)
{
	if (pstidThread)
	{
		*pstidThread = GetCurrentThreadId( ) ;
	}
	return S_OK  ;
}

STDMETHODIMP CScriptEngine::GetScriptThreadID(DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
{
	if (pstidThread)
	{
		*pstidThread = GetCurrentThreadId( ) ;
	}
	return S_OK  ;
}


STDMETHODIMP CScriptEngine::GetScriptThreadState(SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
{
	*pstsState = (SCRIPTTHREADSTATE) 0 ;
	return E_NOTIMPL ;
}

STDMETHODIMP CScriptEngine::InterruptScriptThread(SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
{
	MessageBox (NULL, "InterruptScriptThread", "ScriptEngine", 0) ;
	return E_NOTIMPL ;
}

STDMETHODIMP CScriptEngine::Clone(IActiveScript **ppscript)
{
	MessageBox (NULL, "Clone", "ScriptEngine", 0) ;
	return E_NOTIMPL ;
}
 
/*
IActiveScriptParse methods
*/


STDMETHODIMP CScriptEngine::InitNew( void)
{
	if (m_pScriptText)
	{
		free (m_pScriptText) ;
		m_pScriptText = NULL ;
	}

	return S_OK ;
}
        

STDMETHODIMP CScriptEngine::AddScriptlet(LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode,
            LPCOLESTR pstrItemName, LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName,
            LPCOLESTR pstrDelimiter, DWORD dwSourceContextCookie, ULONG ulStartingLineNumber,
            DWORD dwFlags, BSTR *pbstrName, EXCEPINFO *pexcepinfo)
{
	return S_OK ;
}
        

STDMETHODIMP CScriptEngine::ParseScriptText(LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
            IUnknown *punkContext, LPCOLESTR pstrDelimiter, DWORD dwSourceContextCookie,
            ULONG ulStartingLineNumber, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
{

/*
Get length of script string
*/
	int length = wcslen (pstrCode) ;

/*
Allocate buffer of that size.
*/
	m_pScriptText = (char *)malloc (length + 1) ;

	if (m_pScriptText == NULL) 
	{
		return E_OUTOFMEMORY ;
	}

/*
Copy script text into script engine's storage, converting it to ANSI.
*/
	WideCharToMultiByte (CP_ACP, 0, pstrCode, length+1, m_pScriptText, length+1, NULL, NULL) ;

	return S_OK ;
}
         

		
STDMETHODIMP CScriptEngine::QueryInterface(REFIID riid, LPVOID *ppv)
{
    if (riid == IID_IUnknown || riid == IID_IActiveScript)
	{
        *ppv = (IActiveScript *)this;
		AddRef( ) ;
		return NOERROR;
	}
	else if (riid == IID_IActiveScriptParse)
	{
        *ppv = (IActiveScriptParse *)this;
		AddRef( ) ;
		return NOERROR;
	}
	else
	{
    	*ppv = NULL ;
    	return  E_NOINTERFACE ;
	}
}


STDMETHODIMP_(ULONG) CScriptEngine::AddRef(void)
{
    return ++m_RefCount;
}


STDMETHODIMP_(ULONG) CScriptEngine::Release(void)
{
	m_RefCount -- ;

    if (m_RefCount == 0)
	{
        delete this;
		return 0 ;
	}

    return m_RefCount ;
}



				  	
