text: #include "GetVector2LengthAction.h"
  #include <Engine/Core/AssetLibrary/AssetLibrary.h>
  #include <Engine/Core/Trigger/Trigger.h>
  
  
  GetVector2LengthAction::GetVector2LengthAction(void)
  {}
  
  
  GetVector2LengthAction::GetVector2LengthAction(int32 _type): AbstractAction(_type)
  {}
  
  
  
  GetVector2LengthAction::~GetVector2LengthAction(void)
  {
  	Destroying();
  }
  
  
  
  void GetVector2LengthAction::UpdateValid(void)
  {
  	valid = false; 
  
  	if(arg1.IsNotEmpty() && target.IsNotEmpty()) 
  	{ 
  		AssetLibrary::_GetAssets().Disconnect(AssetLibrary::CREATE_OBJECT_MESSAGE, this);
  		valid = true;
  	}
  }
  
  
  void GetVector2LengthAction::SetVariableArg(int32 _index, StringANSI _name)
  {
  	switch(_index)
  	{
  		case ARG1:
  		{
  			templateArg1.Disconnect(StringExprParserEx::STRING_EXPR_COMPLETED_MESSAGE, this);
  			templateArg1.Disconnect(StringExprParserEx::STRING_EXPR_VARIABLE_LOSS_MESSAGE, this);
  			templateArg1.Disconnect(StringExprParserEx::STRING_EXPR_CHANGE_VALUE_MESSAGE, this);
  			templateArg1.Destroy();
  			
  			SetArgMode(_index, VARIABLE);
  			state[ASSET_TYPE][_index] = AssetLibrary::VARIABLE_ASSET;
  
  			Arg1IsLost(); 
  			
  			arg1Name = _name;
  
  			AbstractObject* object = loadArgsEnable ? AssetLibrary::_LoadCommonAsset(arg1Name, state[ASSET_TYPE][_index]) : AssetLibrary::_GetAssets().FindObject(arg1Name);
  
  			if(arg1.IsEmpty())
  			{
  				if(object)
  				{
  					if(object->IsClassPropertyExist(Variable<float>::FLOAT_VARIABLE_CLASS)) 
  					{
  						if(arg1.Attach(dynamic_cast<Variable<float>*>(object)))
  						{
  							object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  							object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::Arg1IsRenamed));
  							UpdateValid();
  						}
  						return;
  					}
  				}
  			}
  			break;
  		}
  
  		case TARGET:
  		{  
  			templateTarget.Disconnect(StringExprParserEx::STRING_EXPR_COMPLETED_MESSAGE, this);
  			templateTarget.Disconnect(StringExprParserEx::STRING_EXPR_VARIABLE_LOSS_MESSAGE, this);
  			templateTarget.Disconnect(StringExprParserEx::STRING_EXPR_CHANGE_VALUE_MESSAGE, this);
  			templateTarget.Destroy();
  			
  			SetArgMode(_index, VARIABLE);  
  			state[ASSET_TYPE][_index] = AssetLibrary::VARIABLE_ASSET;
  
  			TargetIsLost();
    
  			targetName = _name;
  
  			AbstractObject* object = loadArgsEnable ? AssetLibrary::_LoadCommonAsset(targetName, state[ASSET_TYPE][_index]) : AssetLibrary::_GetAssets().FindObject(targetName);
  
  			if(target.IsEmpty())
  			{
  				if(object)
  				{
  					if(object->IsClassPropertyExist(Variable<Vector2>::VECTOR_2_VARIABLE_CLASS)) 
  					{
  						if(target.Attach(dynamic_cast<Variable<Vector2>*>(object)))
  						{
  							object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  							object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TargetIsRenamed));
  							UpdateValid();
  						}
  						return;
  					}
  				}
  			}
  			break;
  		}
  	}
  }
  
  
  void GetVector2LengthAction::SetTemplateArg(int32 _index, StringANSI _expr)
  {
  	switch(_index)
  	{
  		case ARG1:
  		{
  			templateArg1.Connect(StringExprParserEx::STRING_EXPR_COMPLETED_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TemplateArg1IsCompleted));
  			templateArg1.Connect(StringExprParserEx::STRING_EXPR_VARIABLE_LOSS_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::Arg1IsLost));
  			templateArg1.Connect(StringExprParserEx::STRING_EXPR_CHANGE_VALUE_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TemplateArg1IsChanged));
  			
  			SetArgMode(_index, TEMPLATE);
  			state[ASSET_TYPE][_index] = AssetLibrary::VARIABLE_ASSET;
  
  			Arg1IsLost(); 
  
  			if(templateArg1.Parse(_expr) == StringExprParserEx::NO_ERRORS)
  			{ 
  				TemplateArg1IsCompleted();
  			}
  			break;
  		}  
  
  		case TARGET:
  		{
  			templateTarget.Connect(StringExprParserEx::STRING_EXPR_COMPLETED_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TemplateTargetIsCompleted));
  			templateTarget.Connect(StringExprParserEx::STRING_EXPR_VARIABLE_LOSS_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TargetIsLost));
  			templateTarget.Connect(StringExprParserEx::STRING_EXPR_CHANGE_VALUE_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TemplateTargetIsChanged));
  			
  			SetArgMode(_index, TEMPLATE); 
  			state[ASSET_TYPE][_index] = AssetLibrary::VARIABLE_ASSET; 
  
  			TargetIsLost(); 
  
  			if(templateTarget.Parse(_expr) == StringExprParserEx::NO_ERRORS)
  			{
  				TemplateTargetIsCompleted();
  			}
  			break;
  		}
  	}
  }
  
  
  
  
  void GetVector2LengthAction::TemplateArg1IsCompleted(void)
  {
  	if(templateArg1.Calculate() == StringExprParserEx::NO_ERRORS)
  	{
  		AbstractObject* object = loadArgsEnable ? AssetLibrary::_LoadCommonAsset(templateArg1.GetResult(), state[ASSET_TYPE][ARG1]) : AssetLibrary::_GetAssets().FindObject(templateArg1.GetResult());
  
  		if(arg1.IsEmpty())
  		{
  			if(object)
  			{
  				if(object->IsClassPropertyExist(Variable<float>::FLOAT_VARIABLE_CLASS)) 
  				{
  					if(arg1.Attach(dynamic_cast<Variable<float>*>(object)))
  					{
  						object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  						object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::Arg1IsRenamed));
  						UpdateValid();
  					}
  					return;
  				}
  			}
  		}
  	}
  }
  
  
  void GetVector2LengthAction::Arg1IsLost(void)
  {
  	if(arg1.IsNotEmpty())
  	{ 
  		arg1.Get()->Disconnect(AbstractObject::DESTROY_OBJECT_MESSAGE, this);
  		arg1.Get()->Disconnect(AbstractObject::CHANGE_NAME_MESSAGE, this);
  		arg1.Clear();
  		
  	}
  	AssetLibrary::_GetAssets().Connect(AssetLibrary::CREATE_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsCreated));
  	valid = false;
  }
  
  
  
  
  void GetVector2LengthAction::TemplateArg1IsChanged(void)
  {
  	Arg1IsLost();
  
  	TemplateArg1IsCompleted(); 
  }
  
  
  
  void GetVector2LengthAction::TemplateTargetIsCompleted(void)
  {
  	if(templateTarget.Calculate() == StringExprParserEx::NO_ERRORS)
  	{
  		AbstractObject* object = loadArgsEnable ? AssetLibrary::_LoadCommonAsset(templateTarget.GetResult(), state[ASSET_TYPE][TARGET]) : AssetLibrary::_GetAssets().FindObject(templateTarget.GetResult());
  
  		if(target.IsEmpty())
  		{
  			if(object)
  			{
  				if(object->IsClassPropertyExist(Variable<Vector2>::VECTOR_2_VARIABLE_CLASS))
  				{
  					if(target.Attach(dynamic_cast<Variable<Vector2>*>(object)))
  					{
  						object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  						object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TargetIsRenamed));
  						UpdateValid();
  					}
  					return;
  				}
  			}
  		}
  	}
  }
  
  
  
  void GetVector2LengthAction::TargetIsLost(void)
  {
  	if(target.IsNotEmpty())
  	{
  		target.Get()->Disconnect(AbstractObject::DESTROY_OBJECT_MESSAGE, this);
  		target.Get()->Disconnect(AbstractObject::CHANGE_NAME_MESSAGE, this);
  		target.Clear();
  	}
  	AssetLibrary::_GetAssets().Connect(AssetLibrary::CREATE_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsCreated));
  	valid = false;
  }
  
  
  
  void GetVector2LengthAction::TemplateTargetIsChanged(void)
  {
  	TargetIsLost();
  
  	TemplateTargetIsCompleted(); 
  }
  
  
  
  StringANSI GetVector2LengthAction::GetTemplateArg(int32 _index)
  {
  	switch(_index)
  	{
  		case ARG1:
  		{
  			return templateArg1.GetStringExpr();
  		}
  
  		case TARGET:
  		{
  			return templateTarget.GetStringExpr();
  		}
  	}
  	return "";
  }
  
  
  
  StringANSI GetVector2LengthAction::GetVariableArg(int32 _index)
  {
  	switch(_index)
  	{
  		case ARG1:
  		{
  			return arg1Name;
  		}
  
  		case TARGET:
  		{
  			return targetName;
  		}
  	}
  	return "";
  }
  
  
  void GetVector2LengthAction::operator () (void)
  {
  	if(IsValid()) 
  	{ 
  		arg1.Get()->SetValue(Vector2::_GetLength(target.Get()->GetValue()));
  	}
  }
  
  
  
  void GetVector2LengthAction::ObjectIsDestroyed(AbstractObject* _object)
  {
  	AssetLibrary::_GetAssets().Connect(AssetLibrary::CREATE_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsCreated));
  	valid = false;
  }
  
  
  
  void GetVector2LengthAction::TargetIsRenamed(AbstractObject::NameInfo* _info)
  {
  	TargetIsLost();
  }
  
   
  
  void GetVector2LengthAction::Arg1IsRenamed(AbstractObject::NameInfo* _info)
  {
  	Arg1IsLost();
  }
  
  
  
  void GetVector2LengthAction::ObjectIsCreated(AbstractObject* _object)
  {
  	if(target.IsEmpty())
  	{
  		if(state[TEMPLATE][TARGET])
  		{
  			if(_object->IsClassPropertyExist(Variable<Vector2>::VECTOR_2_VARIABLE_CLASS))
  			{ 
  				if(templateTarget.GetCurrentError() == StringExprParserEx::NO_ERRORS && templateTarget.GetResult() == _object->GetName())
  				{
  					if(target.Attach(dynamic_cast<Variable<Vector2>*>(_object)))
  					{
  						_object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  						_object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TargetIsRenamed));
  						UpdateValid();
  					}
  					return;
  				}
  			}
  		}
  		else if(state[VARIABLE][TARGET])
  		{
  			if(_object->IsClassPropertyExist(Variable<Vector2>::VECTOR_2_VARIABLE_CLASS))
  			{
  				if(targetName == _object->GetName())
  				{
  					if(target.Attach(dynamic_cast<Variable<Vector2>*>(_object)))
  					{
  						_object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  						_object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::TargetIsRenamed));
  						UpdateValid();
  					}
  					return;
  				}
  			}
  		}
  	}
  	if(arg1.IsEmpty())
  	{ 
  		if(state[TEMPLATE][ARG1])
  		{
  			if(_object->IsClassPropertyExist(Variable<float>::FLOAT_VARIABLE_CLASS)) 
  			{
  				if(templateArg1.GetCurrentError() == StringExprParserEx::NO_ERRORS && templateArg1.GetResult() == _object->GetName())
  				{
  					if(arg1.Attach(dynamic_cast<Variable<float>*>(_object)))
  					{
  						_object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  						_object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::Arg1IsRenamed));
  						UpdateValid();
  					}
  					return;
  				}
  			}
  		} 
  		else if(state[VARIABLE][ARG1])
  		{
  			if(_object->IsClassPropertyExist(Variable<float>::FLOAT_VARIABLE_CLASS))
  			{
  				if(arg1Name == _object->GetName())
  				{
  					if(arg1.Attach(dynamic_cast<Variable<float>*>(_object)))
  					{
  						_object->Connect(AbstractObject::DESTROY_OBJECT_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::ObjectIsDestroyed));
  						_object->Connect(AbstractObject::CHANGE_NAME_MESSAGE, this, Caller<>(this, &GetVector2LengthAction::Arg1IsRenamed));
  						UpdateValid();
  					}
  					return;
  				}
  			}
  		}
  	}
  }
  
  
  
  bool GetVector2LengthAction::SaveToFile(StringANSI _path)			
  {
  	if(_path.empty())
  	{
  		_path = AssetLibrary::_GetDir() + actionsDir + GetName() + "." + actionsSuffix;
  	} 
  
  	File file(_path, File::REWRITE);
  
  	if(!SaveToFile(file))
  	{
  		file.Remove();
  		return false;
  	}
  	return true; 
  }
  
  
  bool GetVector2LengthAction::SaveToFile(File& _file)
  {
  	if(_file.IsOpened() && (_file.GetAccessMode() == File::WRITE || _file.GetAccessMode() == File::REWRITE))
  	{
  		_file.Write(type);
  		_file.Write(GetName().length());
  		_file.WriteString(GetName());
  		for(int32 i = 0; i < AbstractAction::WIDTH; i++)
  		{
  			for(int32 j = 0; j < AbstractAction::HEIGHT; j++)
  			{
  				_file.Write(state[i][j]);
  			}
  		}
  		_file.Write(activationLimit);
  		_file.Write(loadArgsEnable);
  		if(state[TEMPLATE][ARG1])
  		{
  			_file.Write(GetTemplateArg(ARG1).length());
  			_file.WriteString(GetTemplateArg(ARG1));
  		}
  		else if(state[VARIABLE][ARG1])
  		{
  			_file.Write(GetVariableArg(ARG1).length());
  			_file.WriteString(GetVariableArg(ARG1));
  		}
  		if(state[TEMPLATE][TARGET])
  		{
  			_file.Write(GetTemplateArg(TARGET).length());
  			_file.WriteString(GetTemplateArg(TARGET));
  		}
  		else if(state[VARIABLE][TARGET])
  		{
  			_file.Write(GetVariableArg(TARGET).length());
  			_file.WriteString(GetVariableArg(TARGET));
  		} 
  		return true;
  	}
  	return false;
  }
  
  
  AbstractAction* GetVector2LengthAction::_LoadFromFile(File& _file)
  {
  	GetVector2LengthAction* action = new GetVector2LengthAction(Variable<Vector2>::GET_VECTOR_2_LENGTH_MESSAGE);
  	StringANSI name;
  	int32 length;
  	_file.Read(length);
  	_file.ReadString(name, length);  
  	action->Rename(name);
  	for(int32 i = 0; i < AbstractAction::WIDTH; i++)
  	{
  		for(int32 j = 0; j < AbstractAction::HEIGHT; j++)
  		{
  			_file.Read(action->state[i][j]);
  		}
  	}
  	int32 activationLimit;
  	_file.Read(activationLimit); 
  	action->SetActivationLimit(activationLimit);
  	bool loadArgsEnable;
  	_file.Read(loadArgsEnable); 
  	action->SetLoadArgsEnable(loadArgsEnable);
  	if(action->state[TEMPLATE][ARG1])
  	{
  		StringANSI templateArg;
  		_file.Read(length);
  		_file.ReadString(templateArg, length);
  		action->SetTemplateArg(ARG1, templateArg); 
  	}
  	else if(action->state[VARIABLE][ARG1])
  	{
  		StringANSI variableArg;
  		_file.Read(length);
  		_file.ReadString(variableArg, length);
  		action->SetVariableArg(ARG1, variableArg);
  	}
  	if(action->state[TEMPLATE][TARGET])
  	{
  		StringANSI templateArg;
  		_file.Read(length);
  		_file.ReadString(templateArg, length);
  		action->SetTemplateArg(TARGET, templateArg); 
  	}
  	else if(action->state[VARIABLE][TARGET])
  	{
  		StringANSI variableArg;
  		_file.Read(length);
  		_file.ReadString(variableArg, length);
  		action->SetVariableArg(TARGET, variableArg);
  	}
  	return action;
  }