AnyType TPTScriptInterface::tptS_set(std::deque<std::string> * words)
{
	//Arguments from stack
	StringType property = eval(words);
	AnyType selector = eval(words);
	AnyType value = eval(words);

	Simulation * sim = m->GetSimulation();
	unsigned char * partsBlock = (unsigned char*)&sim->parts[0];

	int returnValue = 0;

	FormatType propertyFormat;
	int propertyOffset = GetPropertyOffset(property.Value(), propertyFormat);

	if(propertyOffset==-1)
		throw GeneralException("Invalid property");

	//Selector
	int newValue;
	float newValuef;
	if (value.GetType() == TypeNumber)
	{
		newValue = newValuef = ((NumberType)value).Value();
	}
	else if (value.GetType() == TypeFloat)
	{
		newValue = newValuef = ((FloatType)value).Value();
	}
	else if(value.GetType() == TypeString)
	{
		if (property.Value() == "temp")
		{
			std::string newString = ((StringType)value).Value();
			if (newString.at(newString.length()-1) == 'C')
				newValuef = atof(newString.substr(0, newString.length()-1).c_str())+273.15;
			else if (newString.at(newString.length()-1) == 'F')
				newValuef = (atof(newString.substr(0, newString.length()-1).c_str())-32.0f)*5/9+273.15f;
			else
				throw GeneralException("Invalid value for assignment");
		}
		else
		{
			newValue = GetParticleType(((StringType)value).Value());
			if (newValue < 0 || newValue >= PT_NUM)
			{
				// TODO: add element CAKE to invalidate this
				if (!strcasecmp(((StringType)value).Value().c_str(),"cake"))
					throw GeneralException("Cake is a lie, not an element");
				throw GeneralException("Invalid element");
			}
		}
	}
	else
		throw GeneralException("Invalid value for assignment");
	if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM || !sim->elements[newValue].Enabled))
		throw GeneralException("Invalid element");

	if(selector.GetType() == TypePoint || selector.GetType() == TypeNumber)
	{
		int partIndex = -1;
		if(selector.GetType() == TypePoint)
		{
			ui::Point tempPoint = ((PointType)selector).Value();
			if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
				throw GeneralException("Invalid position");

		}
		else
			partIndex = ((NumberType)selector).Value();
		if(partIndex<0 || partIndex>NPART || sim->parts[partIndex].type==0)
			throw GeneralException("Invalid particle");

		switch(propertyFormat)
		{
		case FormatInt:
			*((int*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
			break;
		case FormatFloat:
			*((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValuef;
			break;
		}
		returnValue = 1;
	}
	else if(selector.GetType() == TypeString && ((StringType)selector).Value() == "all")
	{
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValuef;
					}
			}
			break;
		}
	}
	else if(selector.GetType() == TypeString || selector.GetType() == TypeNumber)
	{
		int type;
		if(selector.GetType() == TypeNumber)
			type = ((NumberType)selector).Value();
		else if(selector.GetType() == TypeString)
			type = GetParticleType(((StringType)selector).Value());

		if(type<0 || type>=PT_NUM)
			throw GeneralException("Invalid particle type");
		if(type==0)
			throw GeneralException("Cannot set properties of particles that do not exist");
		std::cout << propertyOffset << std::endl;
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValuef;
					}
			}
			break;
		}
	}
	else
		throw GeneralException("Invalid selector");
	return NumberType(returnValue);
}
AnyType TPTScriptInterface::tptS_set(std::deque<std::string> * words)
{
	//Arguments from stack
	StringType property = eval(words);
	AnyType selector = eval(words);
	AnyType value = eval(words);

	Simulation * sim = m->GetSimulation();
	unsigned char * partsBlock = (unsigned char*)&sim->parts[0];

	int returnValue = 0;

	FormatType propertyFormat;
	int propertyOffset = GetPropertyOffset(property.Value(), propertyFormat);

	if(propertyOffset==-1)
		throw GeneralException("Invalid property");

	//Selector
	int newValue;
	if(value.GetType() == TypeNumber)
		newValue = ((NumberType)value).Value();
	else if(value.GetType() == TypeString)
	{
		newValue = GetParticleType(((StringType)value).Value());
		if (newValue < 0 || newValue >= PT_NUM)
			throw GeneralException("Invalid element");
	}
	else
		throw GeneralException("Invalid value for assignment");
	if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM))
		throw GeneralException("Invalid element");

	if(selector.GetType() == TypePoint || selector.GetType() == TypeNumber)
	{
		int partIndex = -1;
		if(selector.GetType() == TypePoint)
		{
			ui::Point tempPoint = ((PointType)selector).Value();
			if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
				throw GeneralException("Invalid position");

		}
		else
			partIndex = ((NumberType)selector).Value();
		if(partIndex<0 || partIndex>NPART || sim->parts[partIndex].type==0)
			throw GeneralException("Invalid particle");

		switch(propertyFormat)
		{
		case FormatInt:
			*((int*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
			break;
		case FormatFloat:
			*((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
			break;
		}
		returnValue = 1;
	}
	else if(selector.GetType() == TypeString && ((StringType)selector).Value() == "all")
	{
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		}
	}
	else if(selector.GetType() == TypeString || selector.GetType() == TypeNumber)
	{
		int type;
		if(selector.GetType() == TypeNumber)
			type = ((NumberType)selector).Value();
		else if(selector.GetType() == TypeString)
			type = GetParticleType(((StringType)selector).Value());

		if(type<0 || type>=PT_NUM)
			throw GeneralException("Invalid particle type");
		std::cout << propertyOffset << std::endl;
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		}
	}
	else
		throw GeneralException("Invalid selector");
	return NumberType(returnValue);
}