/// <summary>
 /// Small function that takes a Huffman tree & a TKMK00CommandWriter and writes out the tree construction information to the writer.
 /// </summary>
 /// <param name="node"></param>
 /// <param name="writer"></param>
 private static void WriteHuffmanTree(TKMK00HuffmanTreeNode node, TKMK00CommandWriter writer)
 {
     if (!node.IsEndNode)
     {
         writer.Write(1, 1);
         WriteHuffmanTree(node.Left, writer);
         WriteHuffmanTree(node.Right, writer);
     }
     else
     {
         writer.Write(0, 1);
         writer.Write(node.Value, 5);
     }
 }
        /// <summary>
        /// Creates a Huffman-style binary tree that holds the 5-bit color data referenced in the 
        /// TKMK00 decoding process.
        /// </summary>
        private static TKMK00HuffmanTreeNode SetUpHuffmanTree(uint val, byte[] data, TKMK00CommandReader commandReader)
        {
            TKMK00HuffmanTreeNode newTree = new TKMK00HuffmanTreeNode();

            int command = commandReader.ReadBits(1);//1 - Make new branches, 0 - End current branch

            if (command != 0)
            {
                newTree.Value = (int)val; //Not used, but can't hurt to number it
                val++;
                newTree.Left = SetUpHuffmanTree(val, data,  commandReader);
                newTree.Right = SetUpHuffmanTree(val, data,  commandReader);
                return newTree;
            }

            //Else, return a node with a value
            int value = 0;
            int bitCount = 5;
            do
            {
                command = commandReader.ReadBits(1);
                value = value * 2 + command; //basically bitshifts s0 to the left and adds v0, aka it's loading 5 bytes straight from the comandReader
                bitCount -= 1;
            } while (bitCount > 0);

            newTree.Value = value;
            return newTree;
        }
 /// <summary>
 /// Uses the existing Huffman tree and the command that is being looked for, and saves the combination of bits used to
 ///  reach that command in the Huffman tree into outCommands (the value) and outBits (# of bits used)
 /// </summary>
 private static void GetHuffmanTreeTraversalCommands(TKMK00HuffmanTreeNode node, int commandTotal, int bitCount,
     int[] outCommands, int[] outBits)
 {
     if (node.IsEndNode)
     {
         outCommands[node.Value] = commandTotal;
         outBits[node.Value] = bitCount;
     }
     else
     {
         bitCount++;
         commandTotal <<= 1;
         GetHuffmanTreeTraversalCommands(node.Left, commandTotal, bitCount, outCommands, outBits);
         commandTotal++;
         GetHuffmanTreeTraversalCommands(node.Right, commandTotal, bitCount, outCommands, outBits);
     }
 }
        //Only called when creating new rgba value. Traverses the Huffman tree to return the correct value
        private static int RetrieveHuffmanTreeValue(byte[] data, TKMK00HuffmanTreeNode currentNode, TKMK00CommandReader commandReader)
        {
            while (!currentNode.IsEndNode)/*currentNode.Value >= 0x20*/
            {
                int command = commandReader.ReadBits(1); // 0 - left, 1 - right
                if (command == 0)
                    currentNode = currentNode.Left;
                else
                    currentNode = currentNode.Right;
            }

            return currentNode.Value;
        }
        /// <summary>
        /// Returns the differential code used to turn the predicted color to the actual color
        /// </summary>
        private static TKMK00HuffmanTreeNode ConstructTree(int[] colorCounts)
        {
            //Link to Huffman balancing document: https://www.siggraph.org/education/materials/HyperGraph/video/mpeg/mpegfaq/huffman_tutorial.html

            List<Tuple<int, TKMK00HuffmanTreeNode>> frequenciesAndValues = new List<Tuple<int, TKMK00HuffmanTreeNode>>();

            for (int i = 0; i < colorCounts.Length; i++)
            {
                TKMK00HuffmanTreeNode node = new TKMK00HuffmanTreeNode();
                node.Value = i;
                frequenciesAndValues.Add(new Tuple<int, TKMK00HuffmanTreeNode>(colorCounts[i], node));
            }

            while (frequenciesAndValues.Count > 1)
            {
                frequenciesAndValues.Sort((s1, s2) => s2.Item1.CompareTo(s1.Item1));

                //Merge two into a new Huffman tree (NOTE: LEFT IS LESS THAN RIGHT)
                TKMK00HuffmanTreeNode node = new TKMK00HuffmanTreeNode();
                node.Left = frequenciesAndValues[frequenciesAndValues.Count - 1].Item2;
                node.Right = frequenciesAndValues[frequenciesAndValues.Count - 2].Item2;
                node.Value = 64; //Invalid value to denote a traversal node rather than an end node

                int newCount = frequenciesAndValues[frequenciesAndValues.Count - 1].Item1 + frequenciesAndValues[frequenciesAndValues.Count - 2].Item1;
                frequenciesAndValues.RemoveAt(frequenciesAndValues.Count - 1);
                frequenciesAndValues.RemoveAt(frequenciesAndValues.Count - 1);

                frequenciesAndValues.Add(new Tuple<int, TKMK00HuffmanTreeNode>(newCount, node));
            }

            return frequenciesAndValues[0].Item2;
        }