/*
         * public Stream getFile(Sims3PackFileInfo file)
         * {
         *      if (String.IsNullOrEmpty(this.filename)) return new MemoryStream();
         *
         *      FileStream s3pfile = new FileStream(this.filename, FileMode.Open, FileAccess.Read, FileShare.Read);
         *      BinaryReader readFile = new BinaryReader(s3pfile);
         *
         *      uint version = readFile.ReadUInt32();
         *      string s3pack = Encoding.ASCII.GetString(readFile.ReadBytes(7));
         *      if (s3pack != "TS3Pack")
         *      {
         *              errorMessage = "Not a Sims3Pack file";
         *              readFile.Close();
         *              s3pfile.Close();
         *              return new MemoryStream();
         *      }
         *
         *      uint unknown = readFile.ReadUInt16();
         *
         *      int xmlLength = readFile.ReadInt32();
         *      s3pfile.Seek(xmlLength + file.offset, SeekOrigin.Current);
         *
         *      MemoryStream retStream = new MemoryStream(readFile.ReadBytes(file.length));
         *
         *      readFile.Close();
         *      s3pfile.Close();
         *
         *      return retStream;
         * }
         */

        public Sims3PackFile Load(string filename)
        {
            FileStream   s3pfile  = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryReader readFile = new BinaryReader(s3pfile);

            FileInfo f = new FileInfo(filename);

            this.cleanName = f.Name.Replace(f.Extension, "");

            uint   version = readFile.ReadUInt32();
            string s3pack  = Encoding.ASCII.GetString(readFile.ReadBytes(7));

            if (s3pack != "TS3Pack")
            {
                errorMessage = "Not a Sims3Pack file";
                readFile.Close();
                s3pfile.Close();
                return(new Sims3PackFile());
            }
            this.filename = filename;

            Sims3PackFile s3p = new Sims3PackFile();

            s3p.UnknownInt = readFile.ReadUInt16();

            int xmlLength = readFile.ReadInt32();

            byte[] xmlBytes = readFile.ReadBytes(xmlLength);

            s3p.rawXml = System.Text.UTF8Encoding.UTF8.GetString(xmlBytes);

            MemoryStream  mem = new MemoryStream(xmlBytes);
            XmlTextReader xtr = new XmlTextReader(mem);

            int    level   = 0;
            string curName = "";
            string parent  = "";
            string temp    = "";

            while (xtr.Read())
            {
                if (xtr.NodeType == XmlNodeType.Element)
                {
                    curName = xtr.Name;
                    switch (curName)
                    {
                    case "Sims3Package":
                        if (xtr.HasAttributes)
                        {
                            xtr.MoveToAttribute("Type");
                            s3p.Type = xtr.Value;
                            xtr.MoveToAttribute("SubType");
                            s3p.SubType = xtr.Value;
                        }
                        break;

                    case "Dependencies":
                        if (!xtr.IsEmptyElement)
                        {
                            level++;
                        }
                        break;

                    case "LocalizedNames":
                    case "LocalizedDescriptions":
                        if (!xtr.IsEmptyElement)
                        {
                            parent = curName;
                            level++;
                        }
                        break;

                    case "LocalizedName":
                    case "LocalizedDescription":
                        xtr.MoveToAttribute("Language");
                        temp = xtr.Value;
                        break;

                    case "PackagedFile":
                        Sims3PackFile.PackagedFile packagedFile = ReadPackagedFileXml(xtr, readFile, xmlLength);
                        s3p.PackagedFiles.Add(packagedFile);
                        break;
                    }
                }
                if (xtr.NodeType == XmlNodeType.CDATA)
                {
                    switch (curName)
                    {
                    case "LocalizedName":
                        if (level == 1 && parent == "LocalizedDescriptions")
                        {
                            Sims3PackFile.LocalisedString localizedName = new Sims3PackFile.LocalisedString();
                            localizedName.Language = temp;
                            localizedName.CDATA    = xtr.Value.ToString();
                            s3p.LocalizedDescriptions.Add(localizedName);
                        }
                        if (level == 1 && parent == "LocalizedNames")
                        {
                            Sims3PackFile.LocalisedString localizedName = new Sims3PackFile.LocalisedString();
                            localizedName.Language = temp;
                            localizedName.CDATA    = xtr.Value;
                            s3p.LocalizedNames.Add(localizedName);
                        }
                        break;

                    case "LocalizedDescription":
                        if (level == 1)
                        {
                            Sims3PackFile.LocalisedString localizedDesc = new Sims3PackFile.LocalisedString();
                            localizedDesc.Language = temp;
                            localizedDesc.CDATA    = xtr.Value;
                            localizedDesc.useDesc  = true;
                            s3p.LocalizedDescriptions.Add(localizedDesc);
                        }
                        break;
                    }
                }
                if (xtr.NodeType == XmlNodeType.Text)
                {
                    switch (curName.ToLower())
                    {
                    case "archiveversion":
                        s3p.ArchiveVersion = xtr.Value;
                        break;

                    case "codeversion":
                        s3p.CodeVersion = xtr.Value;
                        break;

                    case "gameversion":
                        s3p.GameVersion = xtr.Value;
                        break;

                    case "assetversion":
                        if (!String.IsNullOrEmpty(xtr.Value))
                        {
                            s3p.AssetVersion = Convert.ToInt32(xtr.Value);
                        }
                        break;

                    case "minreqversion":
                        s3p.MinReqVersion = xtr.Value;
                        break;

                    case "displayname":
                        s3p.DisplayName = xtr.Value;
                        break;

                    case "description":
                        if (level == 0)
                        {
                            s3p.Description = xtr.Value;
                        }
                        break;

                    case "packageid":
                        s3p.PackageId = xtr.Value;
                        break;

                    case "date":
                        s3p.Date = xtr.Value;
                        break;

                    case "dependency":
                        if (level == 1)
                        {
                            string dependency = xtr.Value;
                            s3p.Dependencies.Add(dependency);
                        }
                        break;
                    }
                }
                if (xtr.NodeType == XmlNodeType.EndElement)
                {
                    switch (xtr.Name.ToLower())
                    {
                    case "dependencies":
                    case "localizednames":
                    case "localizeddescriptions":
                        level--;
                        break;
                    }
                }
            }

            s3pfile.Close();
            return(s3p);
        }
        /*
        public Stream getFile(Sims3PackFileInfo file)
        {
            if (String.IsNullOrEmpty(this.filename)) return new MemoryStream();

            FileStream s3pfile = new FileStream(this.filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryReader readFile = new BinaryReader(s3pfile);

            uint version = readFile.ReadUInt32();
            string s3pack = Encoding.ASCII.GetString(readFile.ReadBytes(7));
            if (s3pack != "TS3Pack")
            {
                errorMessage = "Not a Sims3Pack file";
                readFile.Close();
                s3pfile.Close();
                return new MemoryStream();
            }

            uint unknown = readFile.ReadUInt16();

            int xmlLength = readFile.ReadInt32();
            s3pfile.Seek(xmlLength + file.offset, SeekOrigin.Current);

            MemoryStream retStream = new MemoryStream(readFile.ReadBytes(file.length));

            readFile.Close();
            s3pfile.Close();

            return retStream;
        }
        */
        public Sims3PackFile Load(string filename)
        {
            FileStream s3pfile = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryReader readFile = new BinaryReader(s3pfile);

            FileInfo f = new FileInfo(filename);
            this.cleanName = f.Name.Replace(f.Extension, "");

            uint version = readFile.ReadUInt32();
            string s3pack = Encoding.ASCII.GetString(readFile.ReadBytes(7));
            if (s3pack != "TS3Pack")
            {
                errorMessage = "Not a Sims3Pack file";
                readFile.Close();
                s3pfile.Close();
                return new Sims3PackFile();
            }
            this.filename = filename;

            Sims3PackFile s3p = new Sims3PackFile();

            s3p.UnknownInt = readFile.ReadUInt16();

            int xmlLength = readFile.ReadInt32();

            byte[] xmlBytes = readFile.ReadBytes(xmlLength);

            s3p.rawXml = System.Text.UTF8Encoding.UTF8.GetString(xmlBytes);

            MemoryStream mem = new MemoryStream(xmlBytes);
            XmlTextReader xtr = new XmlTextReader(mem);

            int level = 0;
            string curName = "";
            string parent = "";
            string temp = "";

            while (xtr.Read())
            {
                if (xtr.NodeType == XmlNodeType.Element)
                {
                    curName = xtr.Name;
                    switch (curName)
                    {
                        case "Sims3Package":
                            if (xtr.HasAttributes)
                            {
                                xtr.MoveToAttribute("Type");
                                s3p.Type = xtr.Value;
                                xtr.MoveToAttribute("SubType");
                                s3p.SubType = xtr.Value;
                            }
                            break;
                        case "Dependencies":
                            if (!xtr.IsEmptyElement)
                            {
                                level++;
                            }
                            break;
                        case "LocalizedNames":
                        case "LocalizedDescriptions":
                            if (!xtr.IsEmptyElement)
                            {
                                parent = curName;
                                level++;
                            }
                            break;
                        case "LocalizedName":
                        case "LocalizedDescription":
                            xtr.MoveToAttribute("Language");
                            temp = xtr.Value;
                            break;
                        case "PackagedFile":
                            Sims3PackFile.PackagedFile packagedFile = ReadPackagedFileXml(xtr, readFile, xmlLength);
                            s3p.PackagedFiles.Add(packagedFile);
                            break;
                    }

                }
                if (xtr.NodeType == XmlNodeType.CDATA)
                {
                    switch (curName)
                    {
                        case "LocalizedName":
                            if (level == 1 && parent == "LocalizedDescriptions")
                            {
                                Sims3PackFile.LocalisedString localizedName = new Sims3PackFile.LocalisedString();
                                localizedName.Language = temp;
                                localizedName.CDATA = xtr.Value.ToString();
                                s3p.LocalizedDescriptions.Add(localizedName);
                            }
                            if (level == 1 && parent == "LocalizedNames")
                            {
                                Sims3PackFile.LocalisedString localizedName = new Sims3PackFile.LocalisedString();
                                localizedName.Language = temp;
                                localizedName.CDATA = xtr.Value;
                                s3p.LocalizedNames.Add(localizedName);
                            }
                            break;
                        case "LocalizedDescription":
                            if (level == 1)
                            {
                                Sims3PackFile.LocalisedString localizedDesc = new Sims3PackFile.LocalisedString();
                                localizedDesc.Language = temp;
                                localizedDesc.CDATA = xtr.Value;
                                localizedDesc.useDesc = true;
                                s3p.LocalizedDescriptions.Add(localizedDesc);
                            }
                            break;
                    }
                }
                if (xtr.NodeType == XmlNodeType.Text)
                {
                    switch (curName.ToLower())
                    {
                        case "archiveversion":
                            s3p.ArchiveVersion = xtr.Value;
                            break;
                        case "codeversion":
                            s3p.CodeVersion = xtr.Value;
                            break;
                        case "gameversion":
                            s3p.GameVersion = xtr.Value;
                            break;
                        case "assetversion":
                            if (!String.IsNullOrEmpty(xtr.Value)) s3p.AssetVersion = Convert.ToInt32(xtr.Value);
                            break;
                        case "minreqversion":
                            s3p.MinReqVersion = xtr.Value;
                            break;
                        case "displayname":
                            s3p.DisplayName = xtr.Value;
                            break;
                        case "description":
                            if (level == 0) s3p.Description = xtr.Value;
                            break;
                        case "packageid":
                            s3p.PackageId = xtr.Value;
                            break;
                        case "date":
                            s3p.Date = xtr.Value;
                            break;
                        case "dependency":
                            if (level == 1)
                            {
                                string dependency = xtr.Value;
                                s3p.Dependencies.Add(dependency);

                            }
                            break;

                    }
                }
                if (xtr.NodeType == XmlNodeType.EndElement)
                {
                    switch (xtr.Name.ToLower())
                    {
                        case "dependencies":
                        case "localizednames":
                        case "localizeddescriptions":
                            level--;
                            break;
                    }
                }
            }

            s3pfile.Close();
            return s3p;
        }