void ParserGroup::ParseSubGroups(filesystem::FB_FILE *fp)
{
	while(!feof(fp))
	{
		std::string string = ReadLine(fp);

		int position = IsProperty(string);
		if(position != -1)
		{
			std::string group = GetProperty(string, position, true);
			std::string value = GetProperty(string, position, false);

			sub_groups[ group ] = value;
		}
		else
		{
			// End of group?
			for(int i = 0; i < (int)string.size(); ++i)
			{
				if(string[i] == '}')
					return;
			}
		}
	}
}
void Parser::Parse(const char *file_name)
{
	std::string group_name;
	std::string group_start;

	filesystem::FB_FILE *fp = filesystem::fb_fopen(file_name, "rb");
	if(!fp) 
	{ 
		//MessageBox(0,"Could not load parserfile","Error",MB_OK); 
		//exit(-1); 
		Logger::getInstance()->error("Could not load parserfile.");
		Logger::getInstance()->debug(file_name);
		return;
	}

	group_name = ReadLine(fp);
	group_start = ReadLine(fp);

	while(!feof(fp))
	{
		for(int i = 0; i < (int)group_start.size(); ++i)
		{
			int position = IsProperty(group_start);
			if(position != -1)
			{
				std::string property = GetProperty(group_start, position, true);
				std::string value = GetProperty(group_start, position, false);

				properties[ property ] = value;
			}
			
			if(group_start[i] == '{')
			{
				// Inheritance owns :)
				for(int j = 0; j < (int)group_name.size(); ++j)
				{
					if(group_name[j] == ':')
					{
						std::string new_name = GetProperty(group_name, j, true);
						std::string super_name = GetProperty(group_name, j, false);

						groups[ new_name ] = groups[ super_name ];
						group_name = new_name;
						break;
					}
				}

				groups[ group_name ].Parse(fp);
			}
		}

		group_name = group_start;
		group_start = ReadLine(fp);
	}

	fclose(fp);
}
void XPCDispJSPropertyInfo::GetReturnType(XPCCallContext& ccx, ELEMDESC & elemDesc)
{
    VARTYPE vt;
    if(IsSetter())      // if this is a setter
    {
        vt = VT_EMPTY;
    }
    else if(IsProperty())   // If this is a property
    {
        vt = XPCDispConvert::JSTypeToCOMType(ccx, mProperty);
    }
    else                    // if this is a function
    {
        vt = VT_VARIANT;
    }
    FillOutElemDesc(vt, PARAMFLAG_FRETVAL, elemDesc);
}
void ParserGroup::Parse(filesystem::FB_FILE *fp)
{
	sub_groups = string_map();
	
	while(!feof(fp))
	{
		std::string string = ReadLine(fp);

		int position = IsProperty(string);
		if(position != -1)
		{
			std::string property = GetProperty(string, position, true);
			std::string value = GetProperty(string, position, false);

			properties[ property ] = value;
		}
		else
		{
			// Branches ?
			for(int i = 0; i < (int)string.size(); ++i)
			{
				if(string[i] == '{')
				{
					ParseSubGroups(fp);
					break;
				}

				if(string[i] == '}')
				{
					// End of this group
					return;
				}
			}
		}
	}
}
UMaterial*  T3DMaterialParser::ImportMaterial()
{
	FString ClassName, Name, Value;
	UClass * Class;

	ensure(NextLine());
	ensure(IsBeginObject(ClassName));
	ensure(ClassName == TEXT("Material"));
	ensure(GetOneValueAfter(TEXT(" Name="), Name));

	FString BasePackageName = FString::Printf(TEXT("/Game/UDK/%s/Materials"), *Package);
	FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
	UMaterialFactoryNew* MaterialFactory = ConstructObject<UMaterialFactoryNew>(UMaterialFactoryNew::StaticClass());
	Material = (UMaterial*)AssetToolsModule.Get().CreateAsset(Name, BasePackageName, UMaterial::StaticClass(), MaterialFactory);
	if (Material == NULL)
	{
		return NULL;
	}

	Material->Modify();

	while (NextLine() && !IsEndObject())
	{
		if (IsBeginObject(ClassName))
		{
			if (ClassName == TEXT("MaterialExpressionFlipBookSample"))
			{
				Class = UMaterialExpressionTextureSample::StaticClass();
			}
			else
			{
				Class = (UClass*)StaticFindObject(UClass::StaticClass(), ANY_PACKAGE, *ClassName, true);
			}

			if (Class)
			{
				ensure(GetOneValueAfter(TEXT(" Name="), Name));
				FRequirement TextureRequirement;
				UMaterialExpression* MaterialExpression = ImportMaterialExpression(Class, TextureRequirement);
				UMaterialExpressionComment * MaterialExpressionComment = Cast<UMaterialExpressionComment>(MaterialExpression);
				if (MaterialExpressionComment)
				{
					Material->EditorComments.Add(MaterialExpressionComment);
					MaterialExpressionComment->MaterialExpressionEditorX -= MaterialExpressionComment->SizeX;
					FixRequirement(FString::Printf(TEXT("%s'%s'"), *ClassName, *Name), MaterialExpression);
				}
				else if (MaterialExpression)
				{
					Material->Expressions.Add(MaterialExpression);
					FixRequirement(FString::Printf(TEXT("%s'%s'"), *ClassName, *Name), MaterialExpression);
				}

				if (ClassName == TEXT("MaterialExpressionFlipBookSample"))
				{
					ImportMaterialExpressionFlipBookSample((UMaterialExpressionTextureSample *)MaterialExpression, TextureRequirement);
				}
			}
			else
			{
				JumpToEnd();
			}
		}
		else if (GetProperty(TEXT("DiffuseColor="), Value))
		{
			ImportExpression(&Material->BaseColor);
		}
		else if (GetProperty(TEXT("SpecularColor="), Value))
		{
			ImportExpression(&Material->Specular);
		}
		else if (GetProperty(TEXT("SpecularPower="), Value))
		{
			// TODO
		}
		else if (GetProperty(TEXT("Normal="), Value))
		{
			ImportExpression(&Material->Normal);
		}
		else if (GetProperty(TEXT("EmissiveColor="), Value))
		{
			ImportExpression(&Material->EmissiveColor);
		}
		else if (GetProperty(TEXT("Opacity="), Value))
		{
			ImportExpression(&Material->Opacity);
		}
		else if (GetProperty(TEXT("OpacityMask="), Value))
		{
			ImportExpression(&Material->OpacityMask);
		}
		else if (IsProperty(Name, Value))
		{
			UProperty* Property = FindField<UProperty>(UMaterial::StaticClass(), *Name);
			if (Property)
			{
				Property->ImportText(*Value, Property->ContainerPtrToValuePtr<uint8>(Material), 0, Material);
			}
		}
	}

	PrintMissingRequirements();

	return Material;
}
UMaterialExpression* T3DMaterialParser::ImportMaterialExpression(UClass * Class, FRequirement &TextureRequirement)
{
	if (!Class->IsChildOf(UMaterialExpression::StaticClass()))
		return NULL;
	UMaterialExpression* MaterialExpression = ConstructObject<UMaterialExpression>(Class, Material);

	FString Value, Name, PropertyName, Type, PackageName;
	while (NextLine() && IgnoreSubs() && !IsEndObject())
	{
		if (GetProperty(TEXT("Texture="), Value))
		{
			if (ParseRessourceUrl(Value, TextureRequirement))
			{
				LevelParser->AddRequirement(TextureRequirement, UObjectDelegate::CreateRaw(LevelParser, &T3DLevelParser::SetTexture, (UMaterialExpressionTextureBase*)MaterialExpression));
			}
			else
			{
				UE_LOG(UDKImportPluginLog, Warning, TEXT("Unable to parse ressource url : %s"), *Value);
			}
		}
		else if (IsProperty(PropertyName, Value) 
			&& PropertyName != TEXT("Material")
			&& PropertyName != TEXT("ExpressionGUID")
			&& PropertyName != TEXT("ObjectArchetype"))
		{
			if (Class->GetName() == TEXT("MaterialExpressionDesaturation") && PropertyName == TEXT("Percent"))
			{
				PropertyName = TEXT("Fraction");
			}
			else if (Class == UMaterialExpressionConstant4Vector::StaticClass())
			{
				if (PropertyName == TEXT("A"))
					((UMaterialExpressionConstant4Vector*)MaterialExpression)->Constant.A = FCString::Atof(*Value);
				else if (PropertyName == TEXT("B"))
					((UMaterialExpressionConstant4Vector*)MaterialExpression)->Constant.B = FCString::Atof(*Value);
				else if (PropertyName == TEXT("G"))
					((UMaterialExpressionConstant4Vector*)MaterialExpression)->Constant.G = FCString::Atof(*Value);
				else if (PropertyName == TEXT("R"))
					((UMaterialExpressionConstant4Vector*)MaterialExpression)->Constant.R = FCString::Atof(*Value);
			}
			else if (Class == UMaterialExpressionConstant3Vector::StaticClass())
			{
				if (PropertyName == TEXT("B"))
					((UMaterialExpressionConstant3Vector*)MaterialExpression)->Constant.B = FCString::Atof(*Value);
				else if (PropertyName == TEXT("G"))
					((UMaterialExpressionConstant3Vector*)MaterialExpression)->Constant.G = FCString::Atof(*Value);
				else if (PropertyName == TEXT("R"))
					((UMaterialExpressionConstant3Vector*)MaterialExpression)->Constant.R = FCString::Atof(*Value);
			}

			UProperty* Property = FindField<UProperty>(Class, *PropertyName);
			UStructProperty * StructProperty = Cast<UStructProperty>(Property);
			if (StructProperty && StructProperty->Struct->GetName() == TEXT("ExpressionInput"))
			{
				FExpressionInput * ExpressionInput = Property->ContainerPtrToValuePtr<FExpressionInput>(MaterialExpression);
				ImportExpression(ExpressionInput);
			}
			else if (Property)
			{
				Property->ImportText(*Value, Property->ContainerPtrToValuePtr<uint8>(MaterialExpression), 0, MaterialExpression);
			}
		}
	}
	MaterialExpression->Material = Material;
	MaterialExpression->MaterialExpressionEditorX = -MaterialExpression->MaterialExpressionEditorX;

	return MaterialExpression;
}