// MyScript.h : Declaration of the CMyScript

#ifndef __MYSCRIPT_H_
#define __MYSCRIPT_H_


//#include "stdafx.h"

#include "resource.h"       // main symbols

/* Interface implemented

  Create simple ATL object
  in classview rightclick "Implement Interface .."
  select blaxxunvrml.tbl
  select Script interface 

*/
#import "import\\blaxxunVRML.tlb" raw_interfaces_only, raw_native_types, no_namespace, named_guids 
// safe release of a COM ptr 
#define RELEASE(x) if (x) { x->Release(); x = NULL; }


// includes we need 
#include <math.h>
#include <stdlib.h>

#include "Utils.h"


 
/////////////////////////////////////////////////////////////////////////////
/*! CMyScript

  An ATL class implementing
  the Script Interface from blaxxunVRML.tlb


*/
class ATL_NO_VTABLE CMyScript : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CMyScript, &CLSID_MyScript>,
	public IDispatchImpl<IMyScript, &IID_IMyScript, &LIBID_NATIVESCRIPTDEMOLib>,
	public IDispatchImpl<Script, &IID_Script, &LIBID_blaxxunVRMLLib>
{
public:

	CMyScript();
	virtual ~CMyScript();

DECLARE_REGISTRY_RESOURCEID(IDR_MYSCRIPT)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMyScript)
	COM_INTERFACE_ENTRY(IMyScript)
//DEL 	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY2(IDispatch, IMyScript)
	COM_INTERFACE_ENTRY(Script)
END_COM_MAP()


private :
	// private script state

	// pointer to CC3D script node containing this object 

	CComPtr<Node> script;

	bool fieldsAreOk;

	// fields in Script node we are interested in 

	//field MFString serverUrl 
	CComQIPtr<EventOutMFString> serverUrl;

	//field SFBool echo
	CComQIPtr<EventOutSFBool> echo;


	//eventOut MFString receive
	CComQIPtr<EventInMFString> receive;


	// global state
	// simply shadowed here 

// IMyScript
public:

	// Script methods 


	// script instance is created
	// we get the pointer to the owning Script node
	// inorder to get access to fields (and browser object)

	STDMETHOD(setContainer)(Node * container);
	STDMETHOD(loadScriptObject)(BSTR urlData);

	STDMETHOD(initialize)();

	STDMETHOD(shutdown)();

	// main worker function, process  an eventIn
	
	STDMETHOD(processEvent)(
			BSTR name, // name of eventIn function
			INT eventId, // ID, for speed, numbered by definition order (+3) for built-in fields
			EventOut * value,	// the value 
			DOUBLE timeStamp
			);

	STDMETHOD(eventsProcessed)();


	// tools
private:

	// output COM MFString buffer 
	BSTR* outValue;
	int outValueCnt; 
	int outValueMax;

	bool hasOutValue() const { return outValueCnt>0; }

	//! append single string to output buffer

	bool AppendOut(LPCTSTR v) 
	{

		if (outValueCnt >= outValueMax)
			return false;

		CComBSTR bstrv (v); // convert & allocate BSTR 
		outValue[outValueCnt]= bstrv.Detach();
		outValueCnt++;

		return true;
	}

};

#endif //__MYSCRIPT_H_

