//Calculate Offsets v2.0
        private long C_offset(bool nextblock, R_MythicPackageHeader towrite, int i)
        {
            long offsettodatablock = 0;

            //BlockOffset
            offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].FileCount)).Length;
            offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].NextBlock)).Length;
            for (int j = 0; j < (towrite.Blocks[i]).FileCount; j++)
            {
                //Index Offset
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlockOffset)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].HeadLength)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].CompressedSize)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DecompressedSize)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].FileHash)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].CRC)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].Flag)).Length;

                //DataBlock
                if (towrite.Blocks[i].Files[j].DataBlock != null && nextblock)
                {
                    //calculate offset to compressed data byte[]
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlock.Flag)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlock.DataOffset)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[j].DataBlock.DateTime)).Length;
                    offsettodatablock += (towrite.Blocks[i].Files[j].DataBlock.Data).Length;
                }
            }
            return(offsettodatablock);
        }
        //K end

        #region worker
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (e.Argument is string[])
            {
                List <R_MythicPackageIndex> toblock = new List <R_MythicPackageIndex>();
                string[] files = (string[])e.Argument;
                bool     error = false;
                for (int k = 0; (k < files.Length) && !error; k++) //Should read ALL files in folder
                {
                    toblock.Add(R_MythicPackageIndex.Pack(files[k], ref error));
                    K_Setvalue(1);
                }

                if (error)
                {
                    e.Result = "An Error was encountered while working. See MessageBox";
                }
                else
                {
                    e.Result = toblock;
                }
            }
            if (e.Argument is List <R_MythicPackageIndex> )
            {
                List <R_MythicPackageIndex> indexes = (List <R_MythicPackageIndex>)e.Argument;
                //Now we should create Blocks of 100 elements
                List <R_MythicPackageBlock> blocks = new List <R_MythicPackageBlock>();
                int i = 0;
                for (int k = 0; k < indexes.Count;)
                {
                    blocks.Add(R_MythicPackageBlock.Pack(indexes, k, ref i));//Creates block struct
                    k = i;
                    K_Setvalue(1);
                }

                //Now we have all blocks, let's do the header.
                R_MythicPackageHeader package = new R_MythicPackageHeader();
                package = R_MythicPackageHeader.Create(blocks);

                e.Result = package;
            }
            else if (e.Argument is R_MythicPackageHeader)
            {
                R_MythicPackageHeader towrite = (R_MythicPackageHeader)e.Argument;
                //We should now write down .uop format using package
                string name = ((Path.GetFileName(FolderName)).Insert((Path.GetFileName(FolderName)).Length, ".uop"));           //Where to write uop
                //Choose writing method
                //write1(towrite, name);
                //write2(towrite, name);
                write3(towrite, name);
                e.Result = true;
            }
        }
        //
        private long B_offset(R_MythicPackageHeader towrite, int a, int j)
        {
            long offsettodatablock = towrite.HeaderSize;
            int  limit             = 0;

            for (int i = 0; i < a + 1; i++)
            {
                //BlockOffset
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].FileCount)).Length;
                offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].NextBlock)).Length;

                for (int k = 0; k < 100; k++)
                //for (int k = 0; k < (towrite.Blocks[i]).FileCount; k++)
                {
                    //Index Offset
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlockOffset)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].HeadLength)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].CompressedSize)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DecompressedSize)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].FileHash)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].CRC)).Length;
                    offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].Flag)).Length;
                }
                if (i < a)
                {
                    limit = (towrite.Blocks[i]).FileCount;
                }
                else if (i == a)
                {
                    limit = j;
                    if (j == 0)
                    {
                        return(offsettodatablock);
                    }
                }

                for (int k = 0; k < limit; k++)
                {
                    //DataBlock
                    if (towrite.Blocks[i].Files[k].DataBlock != null)
                    {
                        //calculate offset to compressed data byte[]
                        offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlock.Flag)).Length;
                        offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlock.DataOffset)).Length;
                        offsettodatablock += (BitConverter.GetBytes(towrite.Blocks[i].Files[k].DataBlock.DateTime)).Length;
                        offsettodatablock += (towrite.Blocks[i].Files[k].DataBlock.Data).Length;
                    }
                }
            }
            return(offsettodatablock);
        }
        //Third write method RIGHT SIZE RIGHT POSITION
        private void write3(R_MythicPackageHeader towrite, string name)
        {
            using (FileStream uop = new FileStream(name, System.IO.FileMode.Create, System.IO.FileAccess.Write))
            {
                //Declarations
                List <List <long> > offset = new List <List <long> >();

                //First, we calculate space in stream
                using (BinaryWriter writer = new BinaryWriter(uop))
                {
                    //Write first Header, then blocks.
                    writer.Write(towrite.Start);
                    writer.Write(towrite.Version);
                    writer.Write(towrite.Misc);
                    writer.Write(towrite.HeaderSize);
                    writer.Write(towrite.Zeros);
                    writer.Write(towrite.BlockSize);
                    writer.Write(towrite.FileCount);
                    byte zero = 0;
                    for (int i = 0; i < towrite.Fill; i++)
                    {
                        writer.Write(zero);
                    }
                    // Header is done, let's write Blocks
                    long nextblockoffset = towrite.HeaderSize;

                    for (int i = 0; i < towrite.Blocks.Count; i++)
                    {
                        //Need to set nextblockoffset
                        nextblockoffset += C_offset(true, towrite, i);
                        if (i == towrite.Blocks.Count - 1)
                        {
                            towrite.Blocks[i].NextBlock = 0;
                        }
                        else
                        {
                            towrite.Blocks[i].NextBlock = nextblockoffset;
                        }
                        //
                        writer.Write(towrite.Blocks[i].FileCount);  //Ok
                        writer.Write(towrite.Blocks[i].NextBlock);  //Ok

                        for (int j = 0; j < towrite.Blocks[i].Files.Count; j++)
                        {
                            //We write INDEXES
                            //need to set datablockoffset
                            if (towrite.Blocks[i].Files[j].DataBlock != null)
                            {
                                towrite.Blocks[i].Files[j].DataBlockOffset = B_offset(towrite, i, j);
                            }
                            else
                            {
                                towrite.Blocks[i].Files[j].DataBlockOffset = 0;
                            }
                            //
                            writer.Write(towrite.Blocks[i].Files[j].DataBlockOffset);   //ToDo
                            writer.Write(towrite.Blocks[i].Files[j].HeadLength);        //Fixed?
                            writer.Write(towrite.Blocks[i].Files[j].CompressedSize);    //Ok
                            writer.Write(towrite.Blocks[i].Files[j].DecompressedSize);  //Ok
                            writer.Write(towrite.Blocks[i].Files[j].FileHash);          //Wrong
                            writer.Write(towrite.Blocks[i].Files[j].CRC);               //Wrong
                            writer.Write(towrite.Blocks[i].Files[j].Flag);              //Ok
                            //
                            K_Setvalue(1);
                        }
                        for (int j = 0; j < towrite.Blocks[i].Files.Count; j++)
                        {
                            //We write DATA
                            if (towrite.Blocks[i].Files[j].DataBlock != null)
                            {
                                writer.Write(towrite.Blocks[i].Files[j].DataBlock.Flag);        //Fixed
                                writer.Write(towrite.Blocks[i].Files[j].DataBlock.DataOffset);  //Fixed
                                writer.Write(towrite.Blocks[i].Files[j].DataBlock.DateTime);    //Ok
                                writer.Write(towrite.Blocks[i].Files[j].DataBlock.Data);        //Ok
                            }
                            K_Setvalue(1);
                        }
                    }
                }
            }
        }