public void updateMaterialTags(Material material, string tag, bool tagValue)
        {
            ArrayObject MaterialFilterAllArray = "MaterialFilterAllArray";
            ArrayObject MaterialFilterUnmappedArray = "MaterialFilterUnmappedArray";
            ArrayObject MaterialFilterMappedArray = "MaterialFilterMappedArray";
            PersistenceManager MaterialSelectorPerMan = "MaterialSelectorPerMan";

            GuiDynamicCtrlArrayControl filterArray = this.FOT("filterArray");
            ArrayObject secondStaticFilter;
            string lastTagField = "";

            if (tagValue)
                {
                MaterialFilterAllArray.add(tag, material);
                if (material.mapTo == "" || material.mapTo == "unmapped_mat")
                    secondStaticFilter = MaterialFilterUnmappedArray;
                else
                    secondStaticFilter = MaterialFilterMappedArray;

                secondStaticFilter.add(tag, material);

                bool createdTag = false;
                for (int i = 0; !createdTag; i++)
                    {
                    string materialTag = material.getFieldValue("materialTag" + i, -1);
                    if (materialTag == "")
                        {
                        Util.eval(material + ".materialTag" + i + "=" + tag + ";");
                        createdTag = true;

                        for (uint j = (uint) this.staticFilterObjects; j < filterArray.getCount(); j++)
                            {
                            if (tag == ((SimObject) ((SimSet) filterArray.getObject(j)).getObject(0))["filter"])
                                {
                                int count = Util.getWord(((GuiCheckBoxCtrl) ((SimSet) filterArray.getObject(j)).getObject(0)).getText(), 2).AsInt();
                                count++;
                                ((GuiCheckBoxCtrl) ((SimSet) filterArray.getObject(j)).getObject(0)).setText(tag + " ( " + count + " )");
                                }
                            }

                        break;
                        }
                    }
                }
            else
                {
                // Remove the material from the "all" category
                for (int i = 0; i < MaterialFilterAllArray.count(); i++)
                    {
                    if (MaterialFilterAllArray.getKey(i) == tag)
                        {
                        if (MaterialFilterAllArray.getValue(i) == material)
                            {
                            MaterialFilterAllArray.erase(i);
                            break;
                            }
                        }
                    }

                // Figure out what the material's other category is
                if (material.mapTo == "" || material.mapTo == "unmapped_mat")
                    secondStaticFilter = MaterialFilterUnmappedArray;
                else
                    secondStaticFilter = MaterialFilterMappedArray;

                // Remove the material from its other category
                for (int i = 0; i < secondStaticFilter.count(); i++)
                    {
                    if (secondStaticFilter.getKey(i) == tag)
                        {
                        if (secondStaticFilter.getValue(i) == material)
                            {
                            secondStaticFilter.erase(i);
                            break;
                            }
                        }
                    }

                this.updateFilterCount(tag, false);

                string tagField = this.getTagField(material, tag);
                lastTagField = this.getLastTagField(material);
                string lastValidTagField = this.getLastValidTagField(material, tag);

                if (tagField == lastValidTagField || lastValidTagField == "")
                    MaterialSelectorPerMan.removeField(material, tagField);
                else
                    {
                    // Replace the current tagFieldValue with the last tagFieldValue
                    string lastValidTag = material.getFieldValue(lastValidTagField, -1);
                    material.setFieldValue(tagField, lastValidTag, -1);

                    // Remove the last tagFieldValue
                    MaterialSelectorPerMan.removeField(material, lastTagField);
                    }
                }

            // so were not going to save materials that dont current exist...
            // technically all the data is stored in dynamic fields if the user feels like saving
            // their auto-generated or new material
            if (material.getFilename() != "" && material.getFilename() != "tools/gui/MaterialSelector.ed.gui" && material.getFilename() != "tools/materialEditor/scripts/materialEditor.ed.cs")
                {
                MaterialSelectorPerMan.setDirty(material);
                MaterialSelectorPerMan.saveDirty();
                MaterialSelectorPerMan.removeDirty(material);

                if (!tagValue)
                    material.setFieldValue(lastTagField, "", -1);
                }
        }
        public void buildPreviewArray(Material material)
        {
            GuiDynamicCtrlArrayControl materialSelection = this.FOT("materialSelection");
            ArrayObject MatEdPreviewArray = "MatEdPreviewArray";

            string matName = "";

            // CustomMaterials are not available for selection
            if (!material.isObject() || material.isMemberOfClass("CustomMaterial"))
                return;

            string previewImage = "";

            if (material.isMemberOfClass("TerrainMaterial"))
                {
                matName = material.getInternalName();

                if (material["diffuseMap"] == "")
                    previewImage = "core/art/warnmat";
                else
                    previewImage = material["diffuseMap"];
                }
            else if (material.toneMap[0] == "" && material.diffuseMap[0] == "" && !material.cubemap.isObject())
                {
                matName = material.name;
                previewImage = "core/art/warnmat";
                }
            else
                {
                matName = material.name;

                if (material.toneMap[0] != "")
                    previewImage = material.toneMap[0].Value;
                else if (material.diffuseMap[0] != "")
                    previewImage = material.diffuseMap[0];
                else if (((SimObject) material.cubemap)["cubeFace[0]"] != "")
                    previewImage = ((SimObject) material.cubemap)["cubeFace[0]"];

                //previewImage = MaterialEditorGui.searchForTexture( material,  previewImage );

                // were going to use a couple of string commands in order to properly
                // find out what the img src path is 
                // **NEW** this needs to be updated with the above, but has some timing issues
                string materialDiffuse = previewImage;
                string materialPath = material.getFilename();

                if (Util.strchr(materialDiffuse, "/") == "")
                    {
                    int k = 0;
                    while (Util.strpos(materialPath, "/", k) != -1)
                        {
                        int foo = Util.strpos(materialPath, "/", k);
                        k = foo + 1;
                        }

                    string foobar = Util.getSubStr(materialPath, k, 99);
                    previewImage = Util.strreplace(materialPath, foobar, previewImage);
                    }
                else
                    previewImage = Util.strreplace(materialPath, materialPath, previewImage);
                }

            // it may seem goofy why the checkbox can't be instanciated inside the container
            // reason being its because we need to store the checkbox ctrl in order to make changes
            // on it later in the function. 

            #region GuiControl ()        oc_Newobject63

            ObjectCreator oc_Newobject63 = new ObjectCreator("GuiControl", "");
            oc_Newobject63["profile"] = "ToolsGuiDefaultProfile";
            oc_Newobject63["Position"] = "0 0";
            oc_Newobject63["Extent"] = "74 87";
            oc_Newobject63["HorizSizing"] = "right";
            oc_Newobject63["VertSizing"] = "bottom";
            oc_Newobject63["isContainer"] = "1";

            #region GuiTextCtrl ()        oc_Newobject62

            ObjectCreator oc_Newobject62 = new ObjectCreator("GuiTextCtrl", "");
            oc_Newobject62["position"] = "7 71";
            oc_Newobject62["profile"] = "ToolsGuiTextCenterProfile";
            oc_Newobject62["extent"] = "64 16";
            oc_Newobject62["text"] = matName;

            #endregion

            oc_Newobject63["#Newobject62"] = oc_Newobject62;

            #endregion

            GuiControl container = oc_Newobject63.Create();

            #region GuiBitmapButtonCtrl ()        oc_Newobject65

            ObjectCreator oc_Newobject65 = new ObjectCreator("GuiBitmapButtonCtrl", "");
            oc_Newobject65["internalName"] = matName;
            oc_Newobject65["HorizSizing"] = "right";
            oc_Newobject65["VertSizing"] = "bottom";
            oc_Newobject65["profile"] = "ToolsGuiButtonProfile";
            oc_Newobject65["position"] = "7 4";
            oc_Newobject65["extent"] = "64 64";
            oc_Newobject65["buttonType"] = "PushButton";
            oc_Newobject65["bitmap"] = "";
            oc_Newobject65["Command"] = "";
            oc_Newobject65["text"] = "Loading...";
            oc_Newobject65["useStates"] = new Creator.StringNoQuote("false");

            #region GuiBitmapButtonCtrl ()        oc_Newobject64

            ObjectCreator oc_Newobject64 = new ObjectCreator("GuiBitmapButtonCtrl", "");
            oc_Newobject64["HorizSizing"] = "right";
            oc_Newobject64["VertSizing"] = "bottom";
            oc_Newobject64["profile"] = "ToolsGuiButtonProfile";
            oc_Newobject64["position"] = "0 0";
            oc_Newobject64["extent"] = "64 64";
            oc_Newobject64["Variable"] = "";
            oc_Newobject64["buttonType"] = "ToggleButton";
            oc_Newobject64["bitmap"] = "tools/materialEditor/gui/cubemapBtnBorder";
            oc_Newobject64["groupNum"] = "0";
            oc_Newobject64["text"] = "";

            #endregion

            oc_Newobject65["#Newobject64"] = oc_Newobject64;

            #endregion

            GuiBitmapButtonCtrl previewButton = oc_Newobject65.Create();

            #region GuiButtonCtrl ()        oc_Newobject66

            ObjectCreator oc_Newobject66 = new ObjectCreator("GuiButtonCtrl", "");
            oc_Newobject66["internalName"] = matName + "Border";
            oc_Newobject66["HorizSizing"] = "right";
            oc_Newobject66["VertSizing"] = "bottom";
            oc_Newobject66["profile"] = "ToolsGuiThumbHighlightButtonProfile";
            oc_Newobject66["position"] = "3 0";
            oc_Newobject66["extent"] = "72 88";
            oc_Newobject66["Variable"] = "";
            oc_Newobject66["buttonType"] = "ToggleButton";
            oc_Newobject66["tooltip"] = matName;
            oc_Newobject66["Command"] = "MaterialSelector.updateSelection( $ThisControl.getParent().getObject(1).internalName, $ThisControl.getParent().getObject(1).bitmap );";
            oc_Newobject66["groupNum"] = "0";
            oc_Newobject66["text"] = "";

            #endregion

            GuiControl previewBorder = oc_Newobject66.Create();

            container.add(previewButton);
            container.add(previewBorder);
            // add to the gui control array
            materialSelection.add(container);

            // add to the array object for reference later
            MatEdPreviewArray.add(previewButton, previewImage);
        }