//------------------------------------------------------------------------
void SUIElementLuaCallback::Init(IUIElement* pElement)
{
	if (gEnv->pFlashUI)
	{
		if ( !pElement )
		{
			const int count = gEnv->pFlashUI->GetUIElementCount();
			for (int i = 0; i < count; ++i)
			{
				pElement = gEnv->pFlashUI->GetUIElement(i);
				IUIElementIteratorPtr elements = pElement->GetInstances();
				while (IUIElement* pInst = elements->Next())
				{
					pInst->RemoveEventListener(this); // to avoid double registration
					pInst->AddEventListener(this, "SUIElementLuaCallback");
				}
			}
		}
		else
		{
			IUIElementIteratorPtr elements = pElement->GetInstances();
			while (IUIElement* pInst = elements->Next())
			{
				pInst->RemoveEventListener(this); // to avoid double registration
				pInst->AddEventListener(this, "SUIElementLuaCallback");
			}
		}
	}
}
void CFlashUIElementListenerNode::ClearListener()
{
	if (GetElement())
	{
		IUIElementIteratorPtr elements = GetElement()->GetInstances();
		while (IUIElement* pElement = elements->Next())
			pElement->RemoveEventListener( this );
	}
}
//------------------------------------------------------------------------
int CScriptBind_UIAction::CallFunction( IFunctionHandler *pH, const char * elementName, int instanceID, const char* functionName )
{
	SUIArguments args;
	if (!SUIToLuaConversationHelper::LuaArgsToUIArgs(pH, 4, args))
	{
		UIACTION_WARNING( "LUA: Failed to call function %s on element %s: Invalid arguments", functionName, elementName );
		return pH->EndFunction(false);
	}

	IUIElement* pElement = GetElement( elementName, instanceID, true );
	if ( pElement )
	{
		const SUIEventDesc* pFctDesc = pElement->GetFunctionDesc( functionName );
		if ( pFctDesc )
		{
			TUIData res;
			bool bFctOk = true;
			if ( instanceID < 0 )
			{
				IUIElementIteratorPtr elements = pElement->GetInstances();
				while ( IUIElement* pInstance = elements->Next() )
					bFctOk &= pInstance->CallFunction( pFctDesc, args, &res);
			}
			else
			{
				bFctOk = pElement->CallFunction( pFctDesc, args, &res);
			}
			if ( bFctOk )
			{
				string sRes;
				res.GetValueWithConversion( sRes );
				return pH->EndFunction( sRes.c_str() );
			}
		}
		UIACTION_WARNING( "LUA: UIElement %s does not have function %s", elementName, functionName );
	}
	else if (IUIEventSystem* pEventSystem = GetEventSystem( elementName, IUIEventSystem::eEST_UI_TO_SYSTEM ))
	{
		uint eventid = pEventSystem->GetEventId( functionName );
		if ( eventid != ~0 )
		{
			SUIArguments res = pEventSystem->SendEvent( SUIEvent( eventid, args ) );
			SmartScriptTable table = gEnv->pScriptSystem->CreateTable();
			SUIToLuaConversationHelper::UIArgsToLuaTable(res, table);		
			return pH->EndFunction( table );
		}
		UIACTION_WARNING( "LUA: UIEventSystem %s does not have event %s", elementName, functionName );
	}
	else
	{
		UIACTION_WARNING( "LUA: UIElement or UIEventSystem %s does not exist", elementName );
	}
	return pH->EndFunction(false);
}
//------------------------------------------------------------------------
int CScriptBind_UIAction::SetVariable( IFunctionHandler *pH, const char * elementName, int instanceID, const char* varName )
{
	if (pH->GetParamCount() != 4)
	{
		UIACTION_ERROR( "LUA: UIAction.SetVariable - wrong number of arguments!");
		return pH->EndFunction(false);
	}

	IUIElement* pElement = GetElement( elementName, instanceID );
	if ( pElement )
	{
		const SUIParameterDesc* pVarDesc = pElement->GetVariableDesc( varName );
		if ( pVarDesc )
		{
			bool bRet = true;
			TUIData value;
			if (SUIToLuaConversationHelper::LuaArgToUIArg(pH, 4, value))
			{
				bool bVarOk = true;
				if ( instanceID < 0 )
				{
					IUIElementIteratorPtr elements = pElement->GetInstances();
					while ( IUIElement* pInstance = elements->Next() )
						bVarOk &= pInstance->SetVariable( pVarDesc, value );
				}
				else
				{
					bVarOk = pElement->SetVariable( pVarDesc, value );
				}

				if ( bVarOk )
					return pH->EndFunction(true);
				else
				{
					UIACTION_WARNING( "LUA: Element %s has no variable %s", elementName, varName );
				}
			}
			else
			{
				UIACTION_WARNING( "LUA: Element %s: wrong datatype for variable %s", elementName, varName );
			}
		}
		else
		{
			UIACTION_WARNING( "LUA: Element %s has no variable %s", elementName, varName );
		}
	}
	else
	{
		UIACTION_WARNING( "LUA: UIElement %s does not exist", elementName );
	}
	return pH->EndFunction(false);
}
//------------------------------------------------------------------------
void SUIElementLuaCallback::Clear()
{
	if (gEnv->pFlashUI)
	{
		const int count = gEnv->pFlashUI->GetUIElementCount();
		for (int i = 0; i < count; ++i)
		{
			IUIElementIteratorPtr elements = gEnv->pFlashUI->GetUIElement(i)->GetInstances();
			while (IUIElement* pInst = elements->Next())
				pInst->RemoveEventListener(this);
		}
	}
	ClearCallbacks();
}
//------------------------------------------------------------------------
int CScriptBind_UIAction::RequestHide( IFunctionHandler *pH, const char * elementName, int instanceID )
{
	IUIElement* pElement = GetElement( elementName, instanceID );
	if ( pElement )
	{
		if ( instanceID < 0 )
		{
			IUIElementIteratorPtr elements = pElement->GetInstances();
			while ( IUIElement* pInstance = elements->Next() )
				pInstance->RequestHide();
		}
		else
		{
			pElement->RequestHide();
		}
		return pH->EndFunction( true );
	}
	UIACTION_WARNING( "LUA: UIElement %s does not exist", elementName );
	return pH->EndFunction( false );
}
//------------------------------------------------------------------------
int CScriptBind_UIAction::SetArray( IFunctionHandler *pH, const char * elementName, int instanceID, const char* arrayName, SmartScriptTable values )
{
	IUIElement* pElement = GetElement( elementName, instanceID );
	if ( pElement )
	{
		const SUIParameterDesc* pArrayDesc = pElement->GetArrayDesc( arrayName );
		if ( pArrayDesc )
		{
			SUIArguments vals;
			if (SUIToLuaConversationHelper::LuaTableToUIArgs(values, vals))
			{
				bool bVarOk = true;
				if ( instanceID < 0 )
				{
					IUIElementIteratorPtr elements = pElement->GetInstances();
					while ( IUIElement* pInstance = elements->Next() )
						bVarOk &= pInstance->SetArray( pArrayDesc, vals );
				}
				else
				{
					bVarOk = pElement->SetArray( pArrayDesc, vals );
				}

				if ( bVarOk )
					return pH->EndFunction(true);
			}
			UIACTION_ERROR( "LUA: Failed to set array %s on Element %s: Invalid arguments", arrayName, elementName);
		}
		UIACTION_WARNING( "LUA: Element %s has no array %s", elementName, arrayName);
	}
	else
	{
		UIACTION_WARNING( "LUA: UIElement %s does not exist", elementName);
	}
	return pH->EndFunction(false);
}