#pragma once
#include "resource.h"       // main symbols
#include "Strawberry_h.h"

class CStrawberryDoc;//forward declartion, CStrawberrySvr is a friend of CStrawberryDoc


/******************************************************************************
CStrawberrySvr - plamen

	there will be just one instance of this class per process 
		ATTENTION this is not the singleton idiom ( not DECLARE_CLASSFACTORY_SINGLETON, but REGCLS_SINGLEUSE )!

	if the exe is run as com server
		after FinalRelease must close the application ( strange, but the exe dosnt want to close automaticly )
		on FinalConstruct open 1 document to serve the prolog program
	if the exe is not run as com server - there will be  dummy instance of the class,
		but with no special behaviot on ctor/dtor

	to access the only instance use CStrawberrySvr::m_obj

	implemented incomming interface - IStrawberrySvr
		com client calls the method, Strawberry Engine process it and calls prolog program

	implemented outgoing interface - _IStrawberrySvrEvents
		prolog program raises the event, Strawberry Engine process it and sends it to all com clients

******************************************************************************/
class ATL_NO_VTABLE CStrawberrySvr : 
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<CStrawberrySvr, &CLSID_Server>,
	public IDispatchImpl<IStrawberrySvr, &IID_IStrawberrySvr, &LIBID_Strawberry, /*wMajor =*/ 2, /*wMinor =*/ 6>,
	public IConnectionPointContainerImpl<CStrawberrySvr>,
	public IConnectionPointImpl<CStrawberrySvr, &__uuidof(_IStrawberrySvrEvents)>
{
public:
	DECLARE_REGISTRY_RESOURCEID(IDR_STRAWBERRYSVR)
	DECLARE_PROTECT_FINAL_CONSTRUCT()
	DECLARE_GET_CONTROLLING_UNKNOWN()

	BEGIN_COM_MAP(CStrawberrySvr)
		COM_INTERFACE_ENTRY(IStrawberrySvr)
		COM_INTERFACE_ENTRY(IDispatch)
		COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
		COM_INTERFACE_ENTRY(IConnectionPointContainer)
	END_COM_MAP()

	BEGIN_CONNECTION_POINT_MAP(CStrawberrySvr)
		CONNECTION_POINT_ENTRY(__uuidof(_IStrawberrySvrEvents))
	END_CONNECTION_POINT_MAP()

	CStrawberrySvr();
	HRESULT FinalConstruct();
	void FinalRelease();

	CComPtr<IUnknown> m_pUnkMarshaler;

protected:
	CStrawberryDoc* m_pOutputDoc;//if run as com server - the document of the prolog_program for the com client

public:
	static CStrawberrySvr* m_obj;//the only instance of the class

public:
	//IStrawberrySvr  - incoming messages
	STDMETHOD(get_program)(BSTR* pVal);
	STDMETHOD(put_program)(BSTR newVal);
	STDMETHOD(get_predicate)(BSTR* pVal);
	STDMETHOD(put_predicate)(BSTR newVal);
	STDMETHOD(get_arguments)(BSTR* pVal);
	STDMETHOD(put_arguments)(BSTR newVal);
	STDMETHOD(get_result)(VARIANT* pVal);
	STDMETHOD(put_result)(VARIANT newVal);
	STDMETHOD(compile)(LONG* plResult);
	STDMETHOD(call)(LONG* plResult);

	//_IStrawberrySvrEvents - outgoing messages
  COleVariant Fire_RaiseTheEvent(const COleVariant& Val1,const COleVariant& Val2,const COleVariant& Val3);

};

OBJECT_ENTRY_AUTO(__uuidof(Server), CStrawberrySvr)
