public HoudiniGeoAttribute createAttribute(HoudiniGeoAttribute.Preset preset)
    {
        HoudiniGeoAttribute new_attribute = ScriptableObject.CreateInstance <HoudiniGeoAttribute>();

        new_attribute.init(myMesh, preset);
        new_attribute.prName = getUniqueAttributeName(new_attribute.prName);
        addAttribute(new_attribute);
        return(new_attribute);
    }
    public override void OnInspectorGUI()
    {
        if (myGeoAttributeManager == null)
        {
            return;
        }

        bool is_editable = true;

        // We can only build or do anything if we can link to our libraries.
#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || (UNITY_METRO && UNITY_EDITOR))
        is_editable = false;
        HoudiniGUI.help(HoudiniConstants.HAPI_UNSUPPORTED_PLATFORM_MSG, MessageType.Info);
#else
        if (!is_editable)
        {
            HoudiniGUI.help("This mesh is not editable.", MessageType.Info);
        }
#endif // !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) )

        bool gui_enable = GUI.enabled;
        GUI.enabled = is_editable;

        myAssetInput.prShowHoudiniControls
            = HoudiniGUI.foldout("Houdini Controls", myAssetInput.prShowHoudiniControls, true);
        if (myAssetInput.prShowHoudiniControls)
        {
            if (!myAssetInput.isPrefab())
            {
                if (GUILayout.Button("Rebuild"))
                {
                    myAssetInput.buildAll();
                }

                if (GUILayout.Button("Recook"))
                {
                    myAssetInput.buildClientSide();
                }
            }
        }

        // Draw Help Pane
        myAssetInput.prShowHelp = HoudiniGUI.foldout("Asset Help", myAssetInput.prShowHelp, true);
        if (myAssetInput.prShowHelp)
        {
            drawHelpBox(myHelpText);
        }

        ///////////////////////////////////////////////////////////////////////
        // Draw Asset Settings
        // These don't affect the asset directly so they don't trigger rebuilds.

        myAssetInput.prShowAssetSettings = HoudiniGUI.foldout("Asset Settings", myAssetInput.prShowAssetSettings, true);
        if (myAssetInput.prShowAssetSettings)
        {
            // Enable Cooking Toggle
            createToggleForProperty(
                "enable_cooking", "Enable Cooking", "prEnableCooking",
                ref myUndoInfo.enableCooking, null, !HoudiniHost.isEnableCookingDefault());

            HoudiniGUI.separator();

            // Cooking Triggers Downstream Cooks Toggle
            createToggleForProperty(
                "cooking_triggers_downstream_cooks", "Cooking Triggers Downstream Cooks",
                "prCookingTriggersDownCooks", ref myUndoInfo.cookingTriggersDownCooks,
                null, !HoudiniHost.isCookingTriggersDownCooksDefault(),
                !myAssetInput.prEnableCooking, " (all cooking is disabled)");

            HoudiniGUI.separator();

            // Push Unity Transform To Houdini Engine Toggle
            createToggleForProperty(
                "push_unity_transform_to_houdini_engine", "Push Unity Transform To Houdini Engine",
                "prPushUnityTransformToHoudini", ref myUndoInfo.pushUnityTransformToHoudini,
                null, !HoudiniHost.isPushUnityTransformToHoudiniDefault());

            // Transform Change Triggers Cooks Toggle
            createToggleForProperty(
                "transform_change_triggers_cooks", "Transform Change Triggers Cooks",
                "prTransformChangeTriggersCooks", ref myUndoInfo.transformChangeTriggersCooks,
                null, !HoudiniHost.isTransformChangeTriggersCooksDefault(),
                !myAssetInput.prEnableCooking, " (all cooking is disabled)");
        }

        ///////////////////////////////////////////////////////////////////////
        // Draw Point Attributes

        myAssetInput.prShowAttributesTable = HoudiniGUI.foldout("Point Attributes", myAssetInput.prShowAttributesTable, true);
        if (myAssetInput.prShowAttributesTable)
        {
            // Draw Create Point Attributes Action Bar
            {
                string[] preset_labels = new string[] {
                    "Create Point Attribute:", "Custom", "Color", "UV", "Normal", "Bool", "Int", "Float", "String"
                };
                int[] preset_values = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

                GUIStyle style = new GUIStyle(EditorStyles.popup);
                style.fixedHeight   = 18;
                style.margin.bottom = 6;
                int preset_selected = EditorGUILayout.IntPopup(
                    0, preset_labels, preset_values, style);

                if (preset_selected == 1)
                {
                    myGeoAttributeManager.createAttribute();
                    myAssetInput.prHasAttributeChanges = true;
                }
                else if (preset_selected > 1)
                {
                    HoudiniGeoAttribute.Preset preset = (HoudiniGeoAttribute.Preset)(preset_selected - 2);
                    myGeoAttributeManager.createAttribute(preset);
                    myAssetInput.prHasAttributeChanges = true;
                }
            }

            // Draw recook notice.
            string help_msg = "There are uncommitted attribute changes. Press 'Recook' when ready.";
            if (myAssetInput.prHasError)
            {
                help_msg += "\nError: " + myAssetInput.prErrorMsg;
            }
            if (myAssetInput.prHasAttributeChanges)
            {
                HoudiniGUI.help(help_msg, MessageType.Info);
            }
            else
            {
                HoudiniGUI.help("Ready", MessageType.Info);
            }

            HoudiniGUI.separator();

            string[] type_labels = new string[] { "bool", "int", "float", "string" };
            int[]    type_values = new int[] { 0, 1, 2, 3 };

            string[] tuple_labels = new string[] { "1", "2", "3", "4", "5" };
            int[]    tuple_values = new int[] { 1, 2, 3, 4, 5 };

            // Draw table header.
            {
                EditorGUILayout.BeginHorizontal();

                GUIStyle label_style = new GUIStyle(EditorStyles.label);
                label_style.padding.right = -5;
                label_style.margin.left   = -5;
                label_style.border.right  = -10;

                EditorGUILayout.LabelField("Name", GUILayout.MinWidth(100));
                EditorGUILayout.LabelField("Type", GUILayout.Width(50));
                EditorGUILayout.LabelField("Tuple", GUILayout.Width(50));
                EditorGUILayout.LabelField("|", GUILayout.Width(8));
                EditorGUILayout.LabelField("Min", GUILayout.Width(50));
                EditorGUILayout.LabelField("Max", GUILayout.Width(50));
                EditorGUILayout.LabelField("", GUILayout.Width(27));

                EditorGUILayout.EndHorizontal();
            }

            for (int i = 0; i < myGeoAttributeManager.prAttributes.Count; ++i)
            {
                HoudiniGeoAttribute attrib = myGeoAttributeManager.prAttributes[i];

                EditorGUILayout.BeginHorizontal();

                // Attribute Name
                string new_name = EditorGUILayout.TextField(attrib.prName, GUILayout.MinWidth(100));
                if (new_name != attrib.prName)
                {
                    attrib.prName = new_name;
                    myAssetInput.prHasAttributeChanges = true;
                }

                // Attribute Type
                HoudiniGeoAttribute.Type new_attrib_type = (HoudiniGeoAttribute.Type)EditorGUILayout.IntPopup(
                    (int)attrib.prType, type_labels, type_values, GUILayout.Width(50));
                if (new_attrib_type != attrib.prType)
                {
                    attrib.prType = new_attrib_type;
                    myAssetInput.prHasAttributeChanges = true;
                }

                // Attribute Tuple Size
                int new_tuple_size = EditorGUILayout.IntPopup(
                    attrib.prTupleSize, tuple_labels, tuple_values, GUILayout.Width(50));
                if (new_tuple_size != attrib.prTupleSize)
                {
                    attrib.prTupleSize = new_tuple_size;
                    myAssetInput.prHasAttributeChanges = true;
                }

                EditorGUILayout.LabelField("|", GUILayout.Width(8));

                // Range
                if (attrib.prType == HoudiniGeoAttribute.Type.STRING)
                {
                    EditorGUILayout.LabelField("N/A", GUILayout.MinWidth(20));
                }
                else
                {
                    if (attrib.prType == HoudiniGeoAttribute.Type.BOOL || attrib.prType == HoudiniGeoAttribute.Type.INT)
                    {
                        attrib.prIntMin =
                            EditorGUILayout.IntField("", attrib.prIntMin, GUILayout.Width(50));
                    }
                    else if (attrib.prType == HoudiniGeoAttribute.Type.FLOAT)
                    {
                        attrib.prFloatMin =
                            EditorGUILayout.FloatField("", attrib.prFloatMin, GUILayout.Width(50));
                    }

                    if (attrib.prType == HoudiniGeoAttribute.Type.BOOL || attrib.prType == HoudiniGeoAttribute.Type.INT)
                    {
                        attrib.prIntMax =
                            EditorGUILayout.IntField("", attrib.prIntMax, GUILayout.Width(50));
                    }
                    else if (attrib.prType == HoudiniGeoAttribute.Type.FLOAT)
                    {
                        attrib.prFloatMax =
                            EditorGUILayout.FloatField("", attrib.prFloatMax, GUILayout.Width(50));
                    }
                }

                EditorGUILayout.LabelField("|", GUILayout.Width(8));

                GUIStyle label_style = new GUIStyle(EditorStyles.label);
                label_style.fontStyle = FontStyle.Bold;
                if (GUILayout.Button("X", label_style, GUILayout.Width(15), GUILayout.Height(15)))
                {
                    myGeoAttributeManager.deleteAttribute(attrib.prName);
                    myAssetInput.prHasAttributeChanges = true;
                }

                EditorGUILayout.EndHorizontal();
            }

            {
                EditorGUILayout.BeginHorizontal();
                GUIStyle label_style = new GUIStyle(EditorStyles.label);
                label_style.fontStyle     = FontStyle.Normal;
                label_style.alignment     = TextAnchor.MiddleRight;
                label_style.padding.left  = 0;
                label_style.margin.left   = 0;
                label_style.padding.right = 0;
                label_style.margin.right  = 0;
                EditorGUILayout.LabelField("Delete Attribute", label_style, GUILayout.MinWidth(40));

                label_style.fontStyle     = FontStyle.Bold;
                label_style.padding.left  = 0;
                label_style.margin.left   = 6;
                label_style.padding.right = 5;
                label_style.margin.right  = 5;
                EditorGUILayout.LabelField("↲", label_style, GUILayout.Width(10));

                EditorGUILayout.EndHorizontal();
            }
        }         // Show Attributes Table

        GUI.enabled = gui_enable;
    }