//-------------------------------------------------------------------------------------------------
// <copyright file="LWAsynchScriptContextLua.h" company="LiquidRobotics">
//  Copyright (c) Liquid Robotics Corporation, confidential and proprietary.  All rights reserved. 
// </copyright>
//
// <summary>
//	Declarations for LWAsynchScriptContextLua class, an implementation of metatable
//	methods exposed to lua.  The context represents a command invocation: whenever
//	a lua method is invoked as a command, the global SMCContext variable is set to
//	an instance of LWAsynchScriptContextLua.  Methods that want to appear to be
//	synchronous (i.e. which hold up execution of subsequent commands until they
//	complete asynchronously) make a copy of SMCContext and call the SetAsynch member.
//	ReportComplete is called when the method is actually complete.
// </summary>
//
// <owner>Mike Cookson</owner>
//-------------------------------------------------------------------------------------------------

#ifndef __LWAsynchScriptContextLua_h__
#define __LWAsynchScriptContextLua_h__

#include "LqrSMACLuaInstance.h"
#include "LqrSMACSharedLib.h"
#include "Luna2.h"
#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>

namespace LiquidRobotics {
namespace LuaWrapper {

class SHARED_LIB_PUBLIC LWAsynchScriptContextLua : public boost::noncopyable
{
public:

	typedef LiquidRobotics::SMACFramework::LuaInstance LuaInstance;
	typedef std::string string;

	struct Event
	{
		enum EventType { AppendOutput, ReportComplete, SetAsynch, SetSuccessFlag };

		Event(EventType et) : eventType(et) { }
		Event(EventType et, const string& _s) : eventType(et), s(_s), b(false) { }
		Event(EventType et, const bool& _b) : eventType(et), b(_b) { }

		EventType eventType;
		string s;
		bool b;
	};

	typedef boost::signals2::signal<void (LWAsynchScriptContextLua& sender, const Event& evt)> NotifySignalType;
	typedef boost::signals2::scoped_connection ScopedConnection;
	typedef boost::shared_ptr<ScopedConnection> ScopedConnectionPtr;

	LWAsynchScriptContextLua(LuaInstance& L);
	virtual ~LWAsynchScriptContextLua();

	static string GetClassName();
	static int GetRegistrations(const Luna2<LWAsynchScriptContextLua>::RegType*& regBase);
	static void PreRegistration(LuaInstance& L);

	int AppendOutput(LuaInstance& L);
	int ReportComplete(LuaInstance& L);
	int SetAsynch(LuaInstance& L);
	int SetSuccessFlag(LuaInstance& L);

	ScopedConnectionPtr Subscribe(NotifySignalType::slot_type slot);

private:

	static const Luna2<LWAsynchScriptContextLua>::RegType registrations[];
	static const size_t registrationCount;

	NotifySignalType sig;
};

}
}

#endif
