public Property(SurfaceTexture tex,string name){
			SurfaceProperty=tex.GetProperty(name,true);
			IsTexture=(SurfaceProperty.Value is TextureValue);
			
			// Pull the values right now:
			Prepare(null);
		}
        /// <summary>Builds or rebuilds the property map.</summary>
        public void CreateMap()
        {
            if (Properties == null)
            {
                PropertyMap = null;
                return;
            }

            // Create:
            PropertyMap = new Dictionary <string, SurfaceProperty>();

            // For each property..
            for (int i = 0; i < Properties.Length; i++)
            {
                // Get property:
                SurfaceProperty prop = Properties[i];

                // Got a name at all?
                if (string.IsNullOrEmpty(prop.Name))
                {
                    // Nope - skip.
                    continue;
                }

                // Push:
                PropertyMap[prop.Name] = prop;
            }
        }
        /// <summary>Sets the named property.</summary>
        public void SetProperty(string property, Values.PropertyValue value)
        {
            // Get or create:
            SurfaceProperty prop = GetProperty(property, true);

            // Apply value:
            prop.Value = value;
        }
		public override void Read(TextureReader reader){
			
			// Property ID:
			int index=(int)reader.ReadCompressed();
			
			// Get from the current surface being loaded:
			SurfaceProperty=reader.CurrentSurface.Properties[index];
			IsTexture=(SurfaceProperty.Value is TextureValue);
			
		}
        /// <summary>Gets the named property by nice name, optionally creating it.</summary>
        public SurfaceProperty GetProperty(string property, bool create)
        {
            property = property.ToLower();

            // Already exists?
            SurfaceProperty result = null;

            if (Properties != null)
            {
                if (PropertyMap == null)
                {
                    CreateMap();
                }

                PropertyMap.TryGetValue(property, out result);
            }

            if (result != null || !create)
            {
                return(result);
            }

            // Create now:
            result      = new SurfaceProperty();
            result.Name = property;

            // Insert:
            if (Properties == null)
            {
                Properties = new SurfaceProperty[1];
            }
            else
            {
                // Resize:
                SurfaceProperty[] set = new SurfaceProperty[Properties.Length + 1];
                Array.Copy(Properties, 0, set, 0, Properties.Length);
                Properties = set;
            }

            // Add:
            result.ID             = Properties.Length - 1;
            Properties[result.ID] = result;

            if (PropertyMap != null)
            {
                // Update map:
                PropertyMap[property] = result;
            }

            return(result);
        }
        /// <summary>Loads the set of properties from the given reader.</summary>
        public void LoadProperties(TextureReader reader)
        {
            // Note that each property has an optional name and optional default value.
            // (However, they serve as 'containers' which materials drop the current values into).

            // How many properties? Also contains 3 flags for names, defaults and unused.
            uint propertiesAndFlags = (uint)reader.ReadCompressed();

            // Chop off the 3 bits:
            int properties = (int)(propertiesAndFlags >> 3);

            if (properties == 0)
            {
                return;
            }

            // Got names?
            // Got any defaults at all?
            bool gotNames    = ((propertiesAndFlags & 1) == 1);
            bool gotDefaults = ((propertiesAndFlags & 2) == 2);

            // Create the set:
            Properties = new SurfaceProperty[properties];

            // For each one..
            for (int i = 0; i < properties; i++)
            {
                // Create:
                SurfaceProperty prop = new SurfaceProperty();

                // Apply ID:
                prop.ID = i;

                if (gotNames)
                {
                    // Read a nice name:
                    prop.Name = reader.ReadString();
                }

                if (gotDefaults)
                {
                    // Read a value:
                    prop.Value = reader.ReadPropertyValue();
                }

                // Add to set:
                Properties[i] = prop;
            }
        }
        /// <summary>Gets a property value by its nice name. Note that nice names are generally rare. Null if it doesn't exist.</summary>
        public Values.PropertyValue this[string property] {
            get{
                SurfaceProperty sp = GetProperty(property, false);

                if (sp == null)
                {
                    return(null);
                }

                return(sp.Value);
            }
            set{
                SetProperty(property, value);
            }
        }
        /// <summary>Removes the given property by its nice name.</summary>
        public void RemoveProperty(string property)
        {
            property = property.ToLower();

            // Exists?
            SurfaceProperty exists = GetProperty(property, false);

            if (exists == null || Properties == null)
            {
                return;
            }

            // One property?
            if (exists.ID == 0 && Properties.Length == 1)
            {
                Properties  = null;
                PropertyMap = null;
            }
            else
            {
                // Slice from the array at exists.ID
                SurfaceProperty[] newSet = new SurfaceProperty[Properties.Length - 1];

                int index = 0;

                for (int i = 0; i < Properties.Length; i++)
                {
                    if (i == exists.ID)
                    {
                        // Skip the one we're removing.
                        continue;
                    }

                    SurfaceProperty movingProp = Properties[i];
                    movingProp.ID = index;
                    newSet[index] = movingProp;
                    index++;
                }

                if (PropertyMap != null)
                {
                    // Update map:
                    PropertyMap.Remove(property);
                }
            }
        }
        /// <summary>Saves the property set to the given writer.</summary>
        public void SaveProperties(BinaryIO.Writer writer, bool withNiceNames, bool withValues)
        {
            // Write property count and extra flags:
            int count = Properties == null?0:Properties.Length;

            uint flags = 0;

            if (withNiceNames)
            {
                flags |= 1;
            }

            if (withValues)
            {
                flags |= 2;
            }

            // Write count and flags now:
            writer.WriteCompressed((((uint)count) << 3) | flags);

            // For each property..
            for (int i = 0; i < count; i++)
            {
                // Get:
                SurfaceProperty sp = Properties[i];

                if (withNiceNames)
                {
                    // Write the nice name:
                    // (Optional because properties ref by index in the actual graph).
                    writer.WriteString(sp.Name);
                }

                if (withValues)
                {
                    // Write the value:
                    sp.Value.Write(writer);
                }
            }
        }
        /// <summary>Convenience function. It also helps to cache the original property value and straight edit that.</summary>
        public void Set(string property, float value)
        {
            // Get the property:
            SurfaceProperty prop = GetProperty(property, true);

            // Get as float:
            Values.FloatValue v = prop.Value as Values.FloatValue;

            // Set it:
            if (v == null)
            {
                prop.Value = new Values.FloatValue(value);
            }
            else
            {
                v.Value = value;

                if (v.Changed)
                {
                    // No longer idling - changes detected.
                    Changed = true;
                }
            }
        }
		public Property(SurfaceProperty prop){
			SurfaceProperty=prop;
			
			// Pull the values right now:
			Prepare(null);
		}