void CPropertiesCanvas::AddProperty(Property* p, wxPGProperty* parent_prop)
{
	switch(p->get_property_type()){
	case StringPropertyType:
		{
			wxPGProperty *new_prop = wxStringProperty(p->GetShortString(),wxPG_LABEL, ((PropertyString*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
			if(p->m_highlighted)m_pg->SetPropertyBackgroundColour(new_prop->GetId(), wxColour(71, 141, 248));
		}
		break;
	case DoublePropertyType:
	case LengthPropertyType:
		{
		    wxString initial_value;
		    initial_value << ((PropertyDouble*)p)->m_initial_value;
			// wxPGProperty *new_prop = wxFloatProperty(p->GetShortString(),wxPG_LABEL, ((PropertyDouble*)p)->m_initial_value);
			wxPGProperty *new_prop = wxStringProperty(p->GetShortString(),wxPG_LABEL, initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
		}
		break;
	case IntPropertyType:
		{
			wxPGProperty *new_prop = wxIntProperty(p->GetShortString(),wxPG_LABEL, ((PropertyInt*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
		}
		break;
	case ColorPropertyType:
		{
			HeeksColor& col = ((PropertyColor*)p)->m_initial_value;
			wxColour wcol(col.red, col.green, col.blue);
			wxPGProperty *new_prop = wxColourProperty(p->GetShortString(),wxPG_LABEL, wcol);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
		}
		break;
	case ChoicePropertyType:
		{
			wxArrayString array_string;
			std::list< wxString >::iterator It;
			for(It = ((PropertyChoice*)p)->m_choices.begin(); It != ((PropertyChoice*)p)->m_choices.end(); It++){
				array_string.Add(wxString(It->c_str()));
			}
			wxPGProperty *new_prop = wxEnumProperty(p->GetShortString(),wxPG_LABEL,array_string, ((PropertyChoice*)p)->m_initial_index);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p );
		}
		break;
	case VertexPropertyType:
		{
			wxPGProperty* new_prop = wxParentProperty(p->GetShortString(),wxPG_LABEL);
			Append( parent_prop, new_prop, p );
			double x[3];
			unsigned int number_of_axes = 3;
			if(((PropertyVertex*)p)->xyOnly())number_of_axes = 2;
			memcpy(x, ((PropertyVertex*)p)->m_x, number_of_axes*sizeof(double));
			if(((PropertyVertex*)p)->m_affected_by_view_units)
			{
				for(unsigned int i = 0; i<number_of_axes; i++)x[i] /= wxGetApp().m_view_units;
			}
            wxPGProperty* x_prop = wxFloatProperty(_("x"),wxPG_LABEL, x[0]);
            if(!p->property_editable())x_prop->SetFlag(wxPG_PROP_READONLY);
            Append( new_prop, x_prop, p );
			wxPGProperty* y_prop = wxFloatProperty(_("y"),wxPG_LABEL, x[1]);
			if(!p->property_editable())y_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, y_prop, p );
			if(!((PropertyVertex*)p)->xyOnly())
			{
				wxPGProperty* z_prop = wxFloatProperty(_("z"),wxPG_LABEL, x[2]);
				if(!p->property_editable())z_prop->SetFlag(wxPG_PROP_READONLY);
				new_prop->SetFlag(wxPG_PROP_READONLY);
				Append( new_prop, z_prop, p );
			}
		}
		break;
	case TrsfPropertyType:
		{
			double x[3];
			extract(((PropertyTrsf*)p)->m_trsf.TranslationPart(), x);

			gp_Dir xaxis(1, 0, 0);
			xaxis.Transform(((PropertyTrsf*)p)->m_trsf);
			gp_Dir yaxis(0, 1, 0);
			yaxis.Transform(((PropertyTrsf*)p)->m_trsf);

			double vertical_angle = 0;
			double horizontal_angle = 0;
			double twist_angle = 0;
			CoordinateSystem::AxesToAngles(xaxis, yaxis, vertical_angle, horizontal_angle, twist_angle);

			wxPGProperty* new_prop = wxParentProperty(p->GetShortString(),wxPG_LABEL);
			Append( parent_prop, new_prop, p );
			wxPGProperty* x_prop = wxFloatProperty(_("x"),wxPG_LABEL,x[0]);
			if(!p->property_editable())x_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, x_prop, p );
			wxPGProperty* y_prop = wxFloatProperty(_("y"),wxPG_LABEL,x[1]);
			if(!p->property_editable())y_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, y_prop, p );
			wxPGProperty* z_prop = wxFloatProperty(_("z"),wxPG_LABEL,x[2]);
			if(!p->property_editable())z_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, z_prop, p );
			wxPGProperty* v_prop = wxFloatProperty(_("vertical angle"),wxPG_LABEL,vertical_angle);
			if(!p->property_editable())v_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, v_prop, p );
			wxPGProperty* h_prop = wxFloatProperty(_("horizontal angle"),wxPG_LABEL,horizontal_angle);
			if(!p->property_editable())h_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, h_prop, p );
			wxPGProperty* t_prop = wxFloatProperty(_("twist angle"),wxPG_LABEL,twist_angle);
			if(!p->property_editable())t_prop->SetFlag(wxPG_PROP_READONLY);
			new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( new_prop, t_prop, p );
		}
		break;
	case CheckPropertyType:
		{
			wxPGProperty* new_prop = wxBoolProperty(p->GetShortString(),wxPG_LABEL, ((PropertyCheck*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p );
			m_pg->SetPropertyAttribute(new_prop, wxPG_BOOL_USE_CHECKBOX, true);
		}
		break;
	case ListOfPropertyType:
		{
			wxPGProperty* new_prop = wxParentProperty(p->GetShortString(),wxPG_LABEL);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p );
			std::list< Property* >::iterator It;
			for(It = ((PropertyList*)p)->m_list.begin(); It != ((PropertyList*)p)->m_list.end(); It++){
				Property* p2 = *It;
				AddProperty(p2, new_prop);
			}
		}
		break;
	case FilePropertyType:
		{
			wxPGProperty *new_prop = wxFileProperty(p->GetShortString(),wxPG_LABEL, ((PropertyFile*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
			if(p->m_highlighted)m_pg->SetPropertyBackgroundColour(new_prop->GetId(), wxColour(71, 141, 248));
		}
		break;
	case DirectoryPropertyType:
		{
			wxPGProperty *new_prop = wxDirProperty(p->GetShortString(),wxPG_LABEL, ((PropertyDir*)p)->m_initial_value);
			if(!p->property_editable())new_prop->SetFlag(wxPG_PROP_READONLY);
			Append( parent_prop, new_prop, p);
			if(p->m_highlighted)m_pg->SetPropertyBackgroundColour(new_prop->GetId(), wxColour(71, 141, 248));
		}
		break;
	}
}
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;
}