private MemoryStream makeVPXYfile(MadScience.Wrappers.ResourceKey headerKey)
        {
            MemoryStream mem = new MemoryStream();
            MadScience.Wrappers.VPXYFile vpxyFile = new MadScience.Wrappers.VPXYFile();
            vpxyFile.rcolHeader.internalChunks.Add(headerKey);

            vpxyFile.Save(mem);

            return mem;
        }
        public static Bitmap createHSVPattern(Stream backgroundStream, Stream maskStream, MadScience.Colours.HSVColor backgroundColor, Stream channel1Stream, Stream channel2Stream, Stream channel3Stream, MadScience.Colours.HSVColor channel1Color, MadScience.Colours.HSVColor channel2Color, MadScience.Colours.HSVColor channel3Color, bool[] channelEnabled)
        {
            Bitmap output = new Bitmap(256, 256, PixelFormat.Format32bppArgb);

            Bitmap background = LoadBitmapFromStream(backgroundStream, 256, 256);
            Bitmap mask = LoadBitmapFromStream(maskStream, 256, 256);

            if (background == null || mask == null)
                return output;

            Bitmap channel1 = LoadBitmapFromStreamOrEmpty(channel1Stream, 256, 256);
            Bitmap channel2 = LoadBitmapFromStreamOrEmpty(channel2Stream, 256, 256);
            Bitmap channel3 = LoadBitmapFromStreamOrEmpty(channel3Stream, 256, 256);

            BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData backgroundData = background.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData maskData = mask.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData channel1Data = channel1.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData channel2Data = channel2.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData channel3Data = channel3.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            Color outputColor;
            const int pixelSize = 4;
            //process every pixel
            unsafe
            {
                for (int y = 0; y < 256; y++)
                {
                    byte* outputRow = (byte*)outputData.Scan0 + (y * outputData.Stride);
                    byte* inputRow = (byte*)backgroundData.Scan0 + (y * backgroundData.Stride);
                    byte* maskRow = (byte*)maskData.Scan0 + (y * maskData.Stride);
                    byte* channel1Row = (byte*)channel1Data.Scan0 + (y * channel1Data.Stride);
                    byte* channel2Row = (byte*)channel2Data.Scan0 + (y * channel2Data.Stride);
                    byte* channel3Row = (byte*)channel3Data.Scan0 + (y * channel3Data.Stride);

                    for (int x = 0; x < 256; x++)
                    {

                        int pixelLocation = x * pixelSize;

                        Color inputcolor = Color.FromArgb(255, inputRow[pixelLocation + 2], inputRow[pixelLocation + 1], inputRow[pixelLocation]);
                        Color maskcolor = Color.FromArgb(maskRow[pixelLocation + 3], maskRow[pixelLocation + 2], maskRow[pixelLocation + 1], maskRow[pixelLocation]);

                        MadScience.Colours.HSVColor bgcolor = new MadScience.Colours.HSVColor(inputcolor);
                        bgcolor.Hue += backgroundColor.Hue;
                        bgcolor.Saturation += backgroundColor.Saturation;
                        bgcolor.Value += backgroundColor.Value;
                        outputColor = bgcolor.Color;

                        if (maskcolor.G > 0 && channelEnabled[0])
                        {
                            Color channelcolor = Color.FromArgb(1, channel1Row[pixelLocation + 2], channel1Row[pixelLocation + 1], channel1Row[pixelLocation]);
                            bgcolor = new MadScience.Colours.HSVColor(channelcolor);
                            bgcolor.Hue += channel1Color.Hue;
                            bgcolor.Saturation += channel1Color.Saturation;
                            bgcolor.Value += channel1Color.Value;
                            outputColor = ColorOverlay(maskcolor.G, outputColor, bgcolor.Color);
                        }

                        if (maskcolor.B > 0 && channelEnabled[1])
                        {
                            Color channelcolor = Color.FromArgb(1, channel2Row[pixelLocation + 2], channel2Row[pixelLocation + 1], channel2Row[pixelLocation]);
                            bgcolor = new MadScience.Colours.HSVColor(channelcolor);
                            bgcolor.Hue += channel2Color.Hue;
                            bgcolor.Saturation += channel2Color.Saturation;
                            bgcolor.Value += channel2Color.Value;
                            outputColor = ColorOverlay(maskcolor.B, outputColor, bgcolor.Color);
                        }

                        if (maskcolor.A > 0 && channelEnabled[2])
                        {
                            Color channelcolor = Color.FromArgb(1, channel3Row[pixelLocation + 2], channel3Row[pixelLocation + 1], channel3Row[pixelLocation]);
                            bgcolor = new MadScience.Colours.HSVColor(channelcolor);
                            bgcolor.Hue += channel3Color.Hue;
                            bgcolor.Saturation += channel3Color.Saturation;
                            bgcolor.Value += channel3Color.Value;
                            outputColor = ColorOverlay(maskcolor.A, outputColor, bgcolor.Color);
                        }

                        outputRow[pixelLocation] = (byte)outputColor.B;
                        outputRow[pixelLocation + 1] = (byte)outputColor.G;
                        outputRow[pixelLocation + 2] = (byte)outputColor.R;
                        outputRow[pixelLocation + 3] = (byte)outputColor.A;
                    }
                }
            }
            output.UnlockBits(outputData);
            mask.UnlockBits(maskData);
            background.UnlockBits(backgroundData);
            channel1.UnlockBits(channel1Data);
            channel2.UnlockBits(channel2Data);
            channel3.UnlockBits(channel3Data);

            return output;
        }
        public static Bitmap createHSVPattern(Stream backgroundStream, MadScience.Colours.HSVColor backgroundColor)
        {
            Bitmap output = new Bitmap(256, 256, PixelFormat.Format32bppArgb);

            Bitmap background = LoadBitmapFromStream(backgroundStream, 256, 256);
            if (background == null)
                return output;

            BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData backgroundData = background.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            Color outputColor;
            const int pixelSize = 4;
            //process every pixel
            unsafe
            {
                for (int y = 0; y < 256; y++)
                {
                    byte* outputRow = (byte*)outputData.Scan0 + (y * outputData.Stride);
                    byte* inputRow = (byte*)backgroundData.Scan0 + (y * backgroundData.Stride);

                    for (int x = 0; x < 256; x++)
                    {

                        int pixelLocation = x * pixelSize;

                        Color inputcolor = Color.FromArgb(255, inputRow[pixelLocation + 2], inputRow[pixelLocation + 1], inputRow[pixelLocation]);

                        MadScience.Colours.HSVColor bgcolor = new MadScience.Colours.HSVColor(inputcolor);
                        bgcolor.Hue += backgroundColor.Hue;
                        bgcolor.Saturation += backgroundColor.Saturation;
                        bgcolor.Value += backgroundColor.Value;
                        outputColor = bgcolor.Color;

                        outputRow[pixelLocation] = (byte)outputColor.B;
                        outputRow[pixelLocation + 1] = (byte)outputColor.G;
                        outputRow[pixelLocation + 2] = (byte)outputColor.R;
                        outputRow[pixelLocation + 3] = (byte)outputColor.A;
                    }
                }
            }
            output.UnlockBits(outputData);
            background.UnlockBits(backgroundData);

            return output;
        }
        public void SetResourceStream(MadScience.Wrappers.ResourceKey key, Stream stream)
        {
            byte[] data = new byte[stream.Length];

            long oldPosition = stream.Position;
            stream.Seek(0, SeekOrigin.Begin);
            stream.Read(data, 0, data.Length);
            stream.Seek(oldPosition, SeekOrigin.Begin);

            this.SetResource(key, data);
        }
        public void SetResource(MadScience.Wrappers.ResourceKey key, byte[] data)
        {
            if (this.Stream.CanWrite == false)
            {
                throw new NotSupportedException();
            }

            if (this._Entries.ContainsKey(key) && this._Entries[key] is StreamEntry)
            {
                this.OriginalEntries[key] = (StreamEntry)this._Entries[key];
            }

            MemoryEntry entry = new MemoryEntry();
            entry.Compressed = false;
            entry.CompressedSize = entry.DecompressedSize = (uint)data.Length;
            entry.Data = (byte[])(data.Clone());

            this._Entries[key] = entry;
        }
        public void MoveResource(MadScience.Wrappers.ResourceKey oldKey, MadScience.Wrappers.ResourceKey newKey)
        {
            if (this.Stream.CanWrite == false)
            {
                throw new NotSupportedException();
            }

            if (this._Entries.ContainsKey(oldKey) == false)
            {
                throw new KeyNotFoundException();
            }
            else if (this._Entries.ContainsKey(newKey) == true)
            {
                throw new ArgumentException("database already contains the new resource key", "newKey");
            }

            Entry entry = this._Entries[oldKey];

            if (entry is StreamEntry)
            {
                this.OriginalEntries[oldKey] = (StreamEntry)entry;
            }

            this._Entries.Remove(oldKey);
            this._Entries.Add(newKey, entry);
        }
 public Stream GetResourceStream(MadScience.Wrappers.ResourceKey key)
 {
     return new MemoryStream(this.GetResource(key));
 }
        public byte[] GetResource(MadScience.Wrappers.ResourceKey key)
        {
            if (this._Entries.ContainsKey(key) == false)
            {
                throw new KeyNotFoundException();
            }

            if (this._Entries[key] is StreamEntry)
            {
                StreamEntry entry = (StreamEntry)this._Entries[key];

                this.Stream.Seek(this.BaseOffset + entry.Offset, SeekOrigin.Begin);

                byte[] data;
                if (entry.Compressed == true)
                {
                    data = MadScience.RefPack.Decompression.Decompress(this.Stream);
                    //data = MadScience.RefPack.ByteHelpers.RefPackDecompress(this.Stream);

                    if (data.Length != entry.DecompressedSize)
                    {
                        throw new InvalidOperationException("decompressed data not same length as specified in index");
                    }
                }
                else
                {
                    data = new byte[entry.DecompressedSize];
                    this.Stream.Read(data, 0, data.Length);
                }

                return data;
            }
            else if (this._Entries[key] is MemoryEntry)
            {
                return (byte[])(((MemoryEntry)this._Entries[key]).Data.Clone());
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
        public byte[] GetRawResource(MadScience.Wrappers.ResourceKey key)
        {
            if (this._Entries.ContainsKey(key) == false || !(this._Entries[key] is StreamEntry))
            {
                throw new KeyNotFoundException();
            }

            StreamEntry entry = (StreamEntry)this._Entries[key];
            this.Stream.Seek(this.BaseOffset + entry.Offset, SeekOrigin.Begin);

            byte[] data = new byte[entry.CompressedSize];
            this.Stream.Read(data, 0, data.Length);
            return data;
        }
        public void DeleteResource(MadScience.Wrappers.ResourceKey key)
        {
            if (this.Stream.CanWrite == false)
            {
                throw new NotSupportedException();
            }

            if (this._Entries.ContainsKey(key) == false)
            {
                throw new KeyNotFoundException();
            }

            if (this._Entries[key] is StreamEntry)
            {
                this.OriginalEntries[key] = (StreamEntry)this._Entries[key];
            }

            this._Entries.Remove(key);
        }
 private void addToTGI(casPart casP, MadScience.Wrappers.ResourceKey tgiNew)
 {
     // Remove duplicates from the tgi64list (just in case)
     bool hasTGI = false;
         for (int k = 0; k < casP.tgi64list.Count; k++)
         {
             MadScience.Wrappers.ResourceKey tgi = casP.tgi64list[k];
             if (tgi.typeId == tgiNew.typeId && tgi.groupId == tgiNew.groupId && tgi.instanceId == tgiNew.instanceId)
             {
                 hasTGI = true;
                 break;
             }
         }
         if (!hasTGI)
         {
             Console.WriteLine("Adding tgi64 " + tgiNew.ToString());
             casP.tgi64list.Add(tgiNew);
         }
 }
        public static Bitmap ProcessMakeupTexture(
            List<Stream> textures,
            MadScience.tintDetail tinta,
            MadScience.tintDetail tintb,
            MadScience.tintDetail tintc,
            MadScience.tintDetail tintd
            )
        {
            Bitmap baseTexture = MadScience.Patterns.LoadBitmapFromStream(textures[0]);
            Bitmap output;

            if (baseTexture != null)
            {
                output = new Bitmap(baseTexture.Width, baseTexture.Height, PixelFormat.Format32bppArgb);

                Bitmap mask = MadScience.Patterns.LoadBitmapFromStream(textures[1], baseTexture.Width, baseTexture.Height);

                Color color1 = Color.Empty;
                Color color2 = Color.Empty;
                Color color3 = Color.Empty;
                Color color4 = Color.Empty;

                if (tinta.enabled.ToLower() == "true") color1 = MadScience.Colours.convertColour(tinta.color);
                if (tintb.enabled.ToLower() == "true") color2 = MadScience.Colours.convertColour(tintb.color);
                if (tintc.enabled.ToLower() == "true") color3 = MadScience.Colours.convertColour(tintc.color);
                if (tintd.enabled.ToLower() == "true") color4 = MadScience.Colours.convertColour(tintd.color);

                BitmapData outputData = output.LockBits(new Rectangle(0, 0, baseTexture.Width, baseTexture.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                BitmapData baseTextureData = baseTexture.LockBits(new Rectangle(0, 0, baseTexture.Width, baseTexture.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                BitmapData maskData = mask.LockBits(new Rectangle(0, 0, baseTexture.Width, baseTexture.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                Color outputColor;
                const int pixelSize = 4;
                //process every pixel
                unsafe
                {
                    for (int y = 0; y < baseTexture.Height; y++)
                    {
                        byte* outputRow = (byte*)outputData.Scan0 + (y * outputData.Stride);
                        byte* baseTextureRow = (byte*)baseTextureData.Scan0 + (y * baseTextureData.Stride);
                        byte* maskRow = (byte*)maskData.Scan0 + (y * maskData.Stride);

                        for (int x = 0; x < baseTexture.Width; x++)
                        {

                            int pixelLocation = x * pixelSize;

                            Color maskColor = Color.FromArgb(maskRow[pixelLocation + 3], maskRow[pixelLocation + 2], maskRow[pixelLocation + 1], maskRow[pixelLocation]);
                            Color baseColor = Color.FromArgb(baseTextureRow[pixelLocation + 3], baseTextureRow[pixelLocation + 2], baseTextureRow[pixelLocation + 1], baseTextureRow[pixelLocation]);
                            if (baseColor.A != 0)
                            {
                                if (color4.IsEmpty) // if color4 is disabled we ignore the alpha channel of the mask
                                {
                                    outputColor = MadScience.Patterns.ProcessMakeUpPixelRGB(baseColor, maskColor, color1, color2, color3);
                                }
                                else
                                {
                                    outputColor = MadScience.Patterns.ProcessMakeUpPixelRGBA(baseColor, maskColor, color1, color2, color3, color4);
                                }
                                outputRow[pixelLocation] = (byte)outputColor.B;
                                outputRow[pixelLocation + 1] = (byte)outputColor.G;
                                outputRow[pixelLocation + 2] = (byte)outputColor.R;
                                outputRow[pixelLocation + 3] = (byte)outputColor.A;
                                }
                        }
                    }
                }
                output.UnlockBits(outputData);
                mask.UnlockBits(maskData);
                baseTexture.UnlockBits(baseTextureData);
            }
            else
            {
                output = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
            }
            return output;
        }
        public static List<Stream> findKey(List<MadScience.Wrappers.ResourceKey> resourceKeys, int fullBuildNum, MadScience.Wrappers.Database db)
        {
            List<Stream> tempChunks = new List<Stream>();

            // Add one Stream per keyName, even if null
            for (int i = 0; i < resourceKeys.Count; i++)
            {
                tempChunks.Add(new MemoryStream());
            }

            // Check local files first
            if (Helpers.localFiles.Count > 0)
            {

                for (int i = 0; i < resourceKeys.Count; i++)
                {
                    if (Helpers.localFiles.ContainsKey(resourceKeys[i].ToString()))
                    {
                        Stream blah = File.OpenRead((string)Helpers.localFiles[resourceKeys[i].ToString()]);
                        StreamHelpers.CopyStream(blah, tempChunks[i]);
                        tempChunks[i].Seek(0, SeekOrigin.Begin);
                        blah.Close();
                    }
                }

            }

            //check current package
            if (!String.IsNullOrEmpty(Helpers.currentPackageFile))
            {
                Stream localPackage = File.Open(Helpers.currentPackageFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                MadScience.Wrappers.Database localDb = new MadScience.Wrappers.Database(localPackage, true);

                for (int i = 0; i < resourceKeys.Count; i++)
                {
                    if (tempChunks[i].Length == 0)
                    {
                        try
                        {
                            tempChunks[i] = localDb.GetResourceStream(resourceKeys[i]);
                        }
                        catch (System.Collections.Generic.KeyNotFoundException)
                        {
                            //Helpers.logMessageToFile(ex.Message);
                        }
                        catch (Exception)
                        {
                            //Helpers.logMessageToFile(ex.Message);
                        }
                    }
                }

                localPackage.Close();
            }

            //check global packages
            foreach (string filename in Helpers.globalPackageFiles)
            {
                if (!String.IsNullOrEmpty(filename))
                {
                    using (Stream localPackage = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        MadScience.Wrappers.Database localDb = new MadScience.Wrappers.Database(localPackage, true);

                        for (int i = 0; i < resourceKeys.Count; i++)
                        {
                            if (tempChunks[i].Length == 0)
                            {
                                try
                                {
                                    tempChunks[i] = localDb.GetResourceStream(resourceKeys[i]);
                                }
                                catch (System.Collections.Generic.KeyNotFoundException)
                                {
                                    //Helpers.logMessageToFile(ex.Message);
                                }
                                catch (Exception)
                                {
                                    //Helpers.logMessageToFile(ex.Message);
                                }
                            }
                        }

                        localPackage.Close();
                    }
                }
            }

            // If input stream isn't null then we use that, otherwise open the fullbuild we want...
            Stream input = Stream.Null;
            bool closeDb = false;
            if (db == null)
            {
                closeDb = true;
                try
                {
                    input = File.OpenRead(Path.Combine(Helpers.findSims3Root(), Helpers.getGameSubPath("\\GameData\\Shared\\Packages\\FullBuild" + fullBuildNum.ToString() + ".package")));
                    db = new MadScience.Wrappers.Database(input, true);
                }
                catch (Exception)
                {
                    return tempChunks;
                }
            }

            for (int i = 0; i < resourceKeys.Count; i++)
            {
                if (tempChunks[i].Length == 0)
                {

                    //keyName tKey = new keyName(resourceKeys[i]);
                    try
                    {
                        tempChunks[i] = db.GetResourceStream(resourceKeys[i]);
                    }
                    catch (System.Collections.Generic.KeyNotFoundException)
                    {
                        //Helpers.logMessageToFile(ex.Message);
                    }
                    catch (Exception)
                    {
                        //Helpers.logMessageToFile(ex.Message);
                    }
                }
            }
            if (closeDb)
            {
                input.Close();
            }

            return tempChunks;
        }
        public static Stream findKey(MadScience.Wrappers.ResourceKey resourceKey, int fullBuildNum, Wrappers.Database db)
        {
            List<MadScience.Wrappers.ResourceKey> resourceKeys = new List<MadScience.Wrappers.ResourceKey>();
            resourceKeys.Add(resourceKey);

            return findKey(resourceKeys, fullBuildNum, db)[0];
        }
 public static Stream findKey(MadScience.Wrappers.ResourceKey resourceKey)
 {
     return findKey(resourceKey, 2);
 }