//-----------------------------------------------------------------------
void TextureAnimatorPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_ANIMATION_TYPE = _("Animation type");
	TAT_LOOP = _("Loop");
	TAT_UP_DOWN = _("Up - Down");
	TAT_RANDOM = _("Random");
	PRNL_TEXCOORDS_START = _("Texture coordinate start");
	PRNL_TEXCOORDS_END = _("Texture coordinate end");
	PRNL_START_RANDOM = _("Start random");
	PRNL_TIME_STEP = _("Time step");

	mHelpHtml = wxT("AffectorTextureAnimator.html");

	// Time Step Animation: ParticleUniverse::Real
	Append(wxFloatProperty(PRNL_TIME_STEP, PRNL_TIME_STEP, ParticleUniverse::TextureAnimator::DEFAULT_TIME_STEP));
	SetPropertyEditor(PRNL_TIME_STEP, wxPG_EDITOR(SpinCtrl));

	// Animation Type: List
	mAnimationTypes.Add(TAT_LOOP);
	mAnimationTypes.Add(TAT_UP_DOWN);
	mAnimationTypes.Add(TAT_RANDOM);
	wxPGId pid = Append(wxEnumProperty(PRNL_ANIMATION_TYPE, PRNL_ANIMATION_TYPE, mAnimationTypes));

	// Start Texture Coordinates: ParticleUniverse::uint16
	Append(wxUIntProperty(PRNL_TEXCOORDS_START, PRNL_TEXCOORDS_START, ParticleUniverse::TextureAnimator::DEFAULT_TEXCOORDS_START));
	SetPropertyEditor(PRNL_TEXCOORDS_START, wxPG_EDITOR(SpinCtrl));

	// End Texture Coordinates: ParticleUniverse::uint16
	Append(wxUIntProperty(PRNL_TEXCOORDS_END, PRNL_TEXCOORDS_END, ParticleUniverse::TextureAnimator::DEFAULT_TEXCOORDS_END));
	SetPropertyEditor(PRNL_TEXCOORDS_END, wxPG_EDITOR(SpinCtrl));

	// Random Start: bool
	Append(wxBoolProperty(PRNL_START_RANDOM, PRNL_START_RANDOM, ParticleUniverse::TextureAnimator::DEFAULT_START_RANDOM));
}
bool ConfigOptionsDialog::AddPropGridSelectValue(ConfigSelectValue & selectValue, wxPGId parentHeaderID, const string & parentNamePath)
{
  wxPGId addID = 0;

  // Calculate the child path
  string selectNamePath = parentNamePath + string(".") + selectValue.typeName;

  // Add a selection based on the type
  switch(selectValue.configType)
  {
    case(CT_String):
      {
        // Get the default value
        wxString defaultValue;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = selectValue.defaultValue[0].c_str();
        }

        // Add a string property
        addID = propGrid->AppendIn(parentHeaderID, wxStringProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_KeyCombination):
    case(CT_StringList):
      {
        // Get the default values
        wxArrayString defaultValues;
        for(uint i=0; i<selectValue.defaultValue.size(); i++)
        {
          defaultValues.Add(selectValue.defaultValue[i].c_str());
        }

        // Add a string-list property
        addID = propGrid->AppendIn(parentHeaderID, wxArrayStringProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValues));
      }
      break;

    case(CT_Boolean):
      {
        // Get the default value
        bool defaultValue = false;
        if(selectValue.defaultValue.size() > 0)
        {
          // If the default value is true
          if(selectValue.defaultValue[0] == CONFIG_PLUGIN_TOKEN_TRUE)
          {
            defaultValue = true;
          }
          else if(selectValue.defaultValue[0] == CONFIG_PLUGIN_TOKEN_FALSE)
          {
            defaultValue = false;
          }
          else
          {
            wxLogError("AddPropGridSelectValue - Unknown boolean value \"%s\"", selectValue.defaultValue[0].c_str());
            return false;
          }
        }

        // Add a boolean selection
        addID = propGrid->AppendIn(parentHeaderID, wxBoolProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_Int):
      {
        // Get the default value
        int defaultValue = 0;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = atoi(selectValue.defaultValue[0].c_str());
        }

        // Add a int property
        addID = propGrid->AppendIn(parentHeaderID, wxIntProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_UInt):
      {
        // Get the default value
        unsigned int defaultValue = 0;
        if(selectValue.defaultValue.size() > 0)
        {
          int testValue = atoi(selectValue.defaultValue[0].c_str());
          if(testValue >= 0)
          {
            defaultValue = testValue;
          }
        }

        // Add a uint property
        addID = propGrid->AppendIn(parentHeaderID, wxUIntProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_Float):
      {
        // Get the default value
        float defaultValue = 0.0f;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = atof(selectValue.defaultValue[0].c_str());
        }

        // Add a float property
        addID = propGrid->AppendIn(parentHeaderID, wxFloatProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_Enum):
      {
        // Get the default value
        wxArrayString enumValues;
        int defaultValue = 0;
        for(uint i=0; i<selectValue.enumValueTypes.size(); i++)
        {
          enumValues.Add(selectValue.enumValueTypes[i].c_str());

          // Check if the value is the default value
          if(selectValue.defaultValue.size() > 0 &&
             selectValue.defaultValue[0] == selectValue.enumValueTypes[i])
          {
            defaultValue = i;
          }
        }

        // Add a enum property
        addID = propGrid->AppendIn(parentHeaderID, wxEnumProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), enumValues, defaultValue));
      }
      break;


    case(CT_EnumMulti):
      {
        // Get the default value
        wxArrayString enumValues;
        wxArrayInt defaultValues;
        for(uint i=0; i<selectValue.enumValueTypes.size(); i++)
        {
          enumValues.Add(selectValue.enumValueTypes[i].c_str());

          // Check if the value is the default value
          for(uint i2=0; i2<selectValue.defaultValue.size(); i2++)
          {
            // Compare the default value to the enum value
            if(selectValue.defaultValue[i2] == selectValue.enumValueTypes[i])
            {
              defaultValues.Add(i);
              break;
            }
          }
        }

        // Add a multiselect enum property
        addID = propGrid->AppendIn(parentHeaderID, wxMultiChoiceProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), enumValues, defaultValues));
      }
      break;

    case(CT_DirSelect):
      {
        // Get the default value
        wxString defaultValue;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = selectValue.defaultValue[0].c_str();
        }

        // Add a directory select property
        addID = propGrid->AppendIn(parentHeaderID, wxDirProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    case(CT_FileSelect):
      {
        // Get the default value
        wxString defaultValue;
        if(selectValue.defaultValue.size() > 0)
        {
          defaultValue = selectValue.defaultValue[0].c_str();
        }

        // Add a file select property
        addID = propGrid->AppendIn(parentHeaderID, wxFileProperty(selectValue.typeName.c_str(), selectNamePath.c_str(), defaultValue));
      }
      break;

    default:
      wxLogError("AddPropGridSelectValue - Unknown type");
      return false;
  }

  // Assign the comment string
  wxString commentStr = selectValue.commentString.c_str();
  commentStr.Replace("\\n", "\n");
  propGrid->SetPropertyHelpString(addID, commentStr);

  return true;
}
//-----------------------------------------------------------------------
void PhysXFluidExternPropertyWindow::_initProperties(void)
{
	// Set the (internationalized) property names
	PRNL_PHYSX_REST_PARTICLE_PER_METER = _("Rest particle per meter");
	PRNL_PHYSX_REST_DENSITY = _("Rest density");
	PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER = _("Kernel radius multiplier");
	PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER = _("Motion limit multiplier");
	PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER = _("Collision dist. multiplier");
	PRNL_PHYSX_PACKET_SIZE_MULTIPLIER = _("Packet size multiplier");
	PRNL_PHYSX_STIFFNESS = _("Stiffness");
	PRNL_PHYSX_VISCOSITY = _("Viscosity");
	PRNL_PHYSX_SURFACE_TENSION = _("Surface tension");
	PRNL_PHYSX_DAMPING = _("Damping");
	PRNL_PHYSX_EXTERNAL_ACCELERATION = _("External acceleration");
	PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES = _("Restitution static shapes");
	PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES = _("Dyn. friction static shapes");
	PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES = _("Static friction static shapes");
	PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES = _("Attraction static shapes");
	PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES = _("Restitution dynamic shapes");
	PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES = _("Dyn. friction dyn. shapes");
	PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES = _("Static friction dyn. shapes");
	PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES = _("Attraction dynamic shapes");
	PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT = _("Collision response coeff.");
	PRNL_PHYSX_SIMULATION_METHOD = _("Simulation method");
	PRNL_PHYSX_COLLISION_METHOD = _("Collision method");
	PRNL_PHYSX_FLAG_VISUALIZATION = _("Visualisation");
	PRNL_PHYSX_FLAG_DISABLE_GRAVITY = _("Disable gravity");
	PRNL_PHYSX_FLAG_COLLISION_TWOWAY = _("Collision twoway");
	PRNL_PHYSX_FLAG_FLUID_ENABLED = _("Fluid enabled");
	PRNL_PHYSX_FLAG_HARDWARE = _("Hardware");
	PRNL_PHYSX_FLAG_PRIORITY_MODE = _("Priority mode");
	PRNL_PHYSX_FLAG_PROJECT_TO_PLANE = _("Project to plane");
	PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT = _("Strict cooking format");
	PHYSX_INTERCOLLISION = _("Intercollision");
	PHYSX_NOINTERCOLLISION = _("Non-intercollision");
	PHYSX_MIX_INTERCOLLISION = _("Mixed intercollision");
	PHYSX_STATIC = _("Static");
	PHYSX_DYNAMIC = _("Dynamic");

	mHelpHtml = wxT("ExternPhysXFluid.html");

	NxFluidDesc fluidDesc;
	fluidDesc.setToDefault();

	// Rest particle per meter: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_REST_PARTICLE_PER_METER, PRNL_PHYSX_REST_PARTICLE_PER_METER, fluidDesc.restParticlesPerMeter));
	SetPropertyEditor(PRNL_PHYSX_REST_PARTICLE_PER_METER, wxPG_EDITOR(SpinCtrl));

	// Rest density: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_REST_DENSITY, PRNL_PHYSX_REST_DENSITY, fluidDesc.restDensity));
	SetPropertyEditor(PRNL_PHYSX_REST_DENSITY, wxPG_EDITOR(SpinCtrl));

	// Kernel radius multiplier: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, fluidDesc.kernelRadiusMultiplier));
	SetPropertyEditor(PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Motion limit multiplier: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, fluidDesc.motionLimitMultiplier));
	SetPropertyEditor(PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Collision distance multiplier: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, fluidDesc.collisionDistanceMultiplier));
	SetPropertyEditor(PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Packet size multiplier: NxU32
	Append(wxUIntProperty(PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, fluidDesc.packetSizeMultiplier));
	SetPropertyEditor(PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, wxPG_EDITOR(SpinCtrl));

	// Stiffness: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_STIFFNESS, PRNL_PHYSX_STIFFNESS, fluidDesc.stiffness));
	SetPropertyEditor(PRNL_PHYSX_STIFFNESS, wxPG_EDITOR(SpinCtrl));

	// Viscosity: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_VISCOSITY, PRNL_PHYSX_VISCOSITY, fluidDesc.viscosity));
	SetPropertyEditor(PRNL_PHYSX_VISCOSITY, wxPG_EDITOR(SpinCtrl));

	// Surface tension: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_SURFACE_TENSION, PRNL_PHYSX_SURFACE_TENSION, fluidDesc.surfaceTension));
	SetPropertyEditor(PRNL_PHYSX_SURFACE_TENSION, wxPG_EDITOR(SpinCtrl));

	// Damping: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_DAMPING, PRNL_PHYSX_DAMPING, fluidDesc.damping));
	SetPropertyEditor(PRNL_PHYSX_DAMPING, wxPG_EDITOR(SpinCtrl));

	// External acceleration: NxVec3
	appendVector3(PRNL_PHYSX_EXTERNAL_ACCELERATION, PRNL_PHYSX_EXTERNAL_ACCELERATION, 
		ParticleUniverse::PhysXMath::convert(fluidDesc.externalAcceleration));

	// Restitution for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, fluidDesc.restitutionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Dynamic friction for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, fluidDesc.dynamicFrictionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Static friction for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, fluidDesc.staticFrictionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Attraction for static shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, fluidDesc.attractionForStaticShapes));
	SetPropertyEditor(PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Restitution for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, fluidDesc.restitutionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Dynamic friction for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, fluidDesc.dynamicFrictionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Static friction for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, fluidDesc.staticFrictionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Attraction for dynamic shapes: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, fluidDesc.attractionForDynamicShapes));
	SetPropertyEditor(PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl));

	// Collision response coefficient: NxReal
	Append(wxFloatProperty(PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, fluidDesc.collisionResponseCoefficient));
	SetPropertyEditor(PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, wxPG_EDITOR(SpinCtrl));

	// Collision group: NxCollisionGroup
	Append(wxUIntProperty(PRNL_PHYSX_COLLISION_GROUP, PRNL_PHYSX_COLLISION_GROUP, fluidDesc.collisionGroup));
	SetPropertyEditor(PRNL_PHYSX_COLLISION_GROUP, wxPG_EDITOR(SpinCtrl));

	// Simulation method: List
	wxArrayString simulationMethod;
	simulationMethod.Add(PHYSX_INTERCOLLISION);
	simulationMethod.Add(PHYSX_NOINTERCOLLISION);
	simulationMethod.Add(PHYSX_MIX_INTERCOLLISION);
	wxPGId pid = Append(wxEnumProperty(PRNL_PHYSX_SIMULATION_METHOD, PRNL_PHYSX_SIMULATION_METHOD, simulationMethod));

	// Collision method: List
	wxArrayString collisionMethod;
	collisionMethod.Add(PHYSX_STATIC);
	collisionMethod.Add(PHYSX_DYNAMIC);
	wxPGId pid2 = Append(wxEnumProperty(PRNL_PHYSX_COLLISION_METHOD, PRNL_PHYSX_COLLISION_METHOD, collisionMethod));

	// Visualisation: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_VISUALIZATION, PRNL_PHYSX_FLAG_VISUALIZATION, fluidDesc.flags & NX_FF_VISUALIZATION));

	// Disable gravity: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_DISABLE_GRAVITY, PRNL_PHYSX_FLAG_DISABLE_GRAVITY, fluidDesc.flags & NX_FF_DISABLE_GRAVITY));

	// Collision twoway: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_COLLISION_TWOWAY, PRNL_PHYSX_FLAG_COLLISION_TWOWAY, fluidDesc.flags & NX_FF_COLLISION_TWOWAY));

	// Fluid enabled: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_FLUID_ENABLED, PRNL_PHYSX_FLAG_FLUID_ENABLED, fluidDesc.flags & NX_FF_ENABLED));

	// Hardware: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_HARDWARE, PRNL_PHYSX_FLAG_HARDWARE, fluidDesc.flags & NX_FF_HARDWARE));

	// Priority mode: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_PRIORITY_MODE, PRNL_PHYSX_FLAG_PRIORITY_MODE, fluidDesc.flags & NX_FF_PRIORITY_MODE));

	// Project to plane: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_PROJECT_TO_PLANE, PRNL_PHYSX_FLAG_PROJECT_TO_PLANE, fluidDesc.flags & NX_FF_PROJECT_TO_PLANE));

	// Strict cooking format: bool
	Append(wxBoolProperty(PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT, PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT, fluidDesc.flags & NX_FF_FORCE_STRICT_COOKING_FORMAT));
}