//compressing pdf file

        //Writng Compress File
        public void PDFCompressFile(string content)
        {
            //string fileName = "compressed.cmu";

            // Create a new file
            writeBitByBit bit = new writeBitByBit(CompName);  //creating an instance of bit write

            //writing tree info
            PQueue.cNode top = root;
            printHeaderTree(top, bit);

            int    c;
            string code = "0";                       //initializing

            for (int i = 0; i < content.Length; ++i) //reading char from string containg input
            {
                Console.WriteLine(content[i]);
                if (HuffmanCode.ContainsKey(content[i]))
                {
                    code = HuffmanCode[content[i]];   //reading character's huffman code from th Code table
                }
                else
                {
                    //if not fount in table do nothing
                }
                for (int j = 0; j < code.Length; ++j)    //reading each character from the Huffman code  like if code for A = 011 the first 0 then 1 and then 1
                {
                    if (code[j] == '0')
                    {
                        bit.BitWrite(0);                //calling writing function with 0
                    }
                    else
                    {
                        bit.BitWrite(1);               //calling writing function with 1
                    }
                }
            }
            //now we need to write psedu_EOF so that we don't reed extra bytes from the file
            code = HuffmanCode[(char)Pseudo_EOF];
            for (int i = 0; i < code.Length; ++i)    //reading each character from the Huffman code  like if code for A = 011 the first 0 then 1 and then 1
            {
                if (code[i] == '0')
                {
                    bit.BitWrite(0);                //calling writing function with 0
                }
                else
                {
                    bit.BitWrite(1);               //calling writing function with 1
                }
            }
            bit.close();
        }
        //entering values in map inside nodes and arranging those nodes in Priority queue with smallest frequencies in front

        public PQueue.PriorityQueue nodesinQueue(Dictionary <char, int> Dic)
        {
            PQueue.cNode         node   = new PQueue.cNode();         //node created
            PQueue.PriorityQueue pQueue = new PQueue.PriorityQueue(); //queue created
            foreach (KeyValuePair <char, int> kvp in Dic)             //reading from frequency dictionary
            {
                node.value     = kvp.Key;
                node.frequency = kvp.Value;      //setting the values of node
                pQueue.insertWithPriority(node); //entering the node
                node = new PQueue.cNode();
            }
            return(pQueue);
        }
        //calculating codes making tree

        public PQueue.cNode HuffmanEncoding(PQueue.PriorityQueue pQueue)
        {
            int n = pQueue.count;

            while (n != 1)
            {
                PQueue.cNode node = new PQueue.cNode();

                node.leftZero  = pQueue.remove();
                node.rightOne  = pQueue.remove();
                node.frequency = node.leftZero.frequency + node.rightOne.frequency;
                node.value     = '~';                           //just adding a temp value to middle nodes
                pQueue.insertWithPriority(node);
                n = pQueue.count;
            }
            return(pQueue.Top());
        }
 //writing tree
 public void printHeaderTree(PQueue.cNode top, writeBitByBit bit)
 {
     if (top == null)
     {
         return;
     }
     if (top.leftZero == null && top.rightOne == null)
     {
         bit.ByteWrite('1');
         bit.ByteWrite(top.value);
     }
     else
     {
         bit.ByteWrite('0');
         printHeaderTree(top.leftZero, bit);
         printHeaderTree(top.rightOne, bit);
     }
 }
        public void printPreorder(PQueue.cNode node)
        {
            if (node == null)
            {
                return;
            }

            /* first print data of node */
            if (node.leftZero == null && node.rightOne == null)
            {
                Console.Write(node.value + " ");
            }

            /* then recur on left sutree */
            printPreorder(node.leftZero);

            /* now recur on right subtree */
            printPreorder(node.rightOne);
        }
        public string fileExten;   // file extension stoing var


        //decompress the file

        public void decompress(string fileName, FileStream fs2)
        {
            readBitByBit bit = new readBitByBit(fileName);

            FileTreeroot = ReadTreeHeader(bit);
            program.printPreorder(FileTreeroot);
            var  output    = new StreamWriter(fs2);
            int  returnbit = -1;
            char leaf      = '1'; //checking if we reached the end of file

            // PQueue.cNode top = root;
            PQueue.cNode top = FileTreeroot;

            while (true)                                          //will run until we found the pseduo_EOF
            {
                if (top.leftZero == null && top.rightOne == null) //if leaf node is reached
                {
                    leaf = top.value;
                    if (leaf == (char)program.Pseudo_EOF)   //if it is last letter close the file
                    {
                        output.Close();
                        break;
                    }
                    else
                    {
                        output.Write(leaf);  //else write in file
                        top = FileTreeroot;  //again start from root
                    }
                }
                returnbit = bit.bitRead();
                if (returnbit == 0)  //if not leaf keep on reading the file
                {
                    top = top.leftZero;
                }
                else if (returnbit == 1)
                {
                    top = top.rightOne;
                }
            }
            output.Close();
            bit.close();
        }
        public PQueue.cNode ReadTreeHeader(readBitByBit bit)
        {
            char c = bit.ByteRead();

            PQueue.cNode node = new PQueue.cNode();

            if (c == '1')
            {
                node       = new PQueue.cNode();
                node.value = bit.ByteRead();
                return(node);
            }

            else
            {
                PQueue.cNode leftChild  = ReadTreeHeader(bit);
                PQueue.cNode rightChild = ReadTreeHeader(bit);
                node = new PQueue.cNode('0', leftChild, rightChild);
                return(node);
            }
        }
        //to calculate code from tree
        public void HuffCode(PQueue.cNode root, string str)
        {
            if (root == null)   //base case
            {
                return;
            }

            if (root.leftZero == null && root.rightOne == null)    //if we reached at leaf node
            {
                try
                {
                    HuffmanCode.Add(root.value, str);     //if it is not already in the Dictionary As i haven't added pseduEOF in Code before it will be added here
                }
                catch
                {
                    HuffmanCode[root.value] = str;   //if it is in the dictionary just edit 2nd value
                }
            }
            else
            {
                HuffCode(root.leftZero, str + "0");   //concatination to form the code
                HuffCode(root.rightOne, str + "1");
            }
        }
        private void Compression_Click(object sender, RoutedEventArgs e)
        {
            string filename = fileName;

            //myObj.comleteFlag = 0;


            if (fileExt == ".pdf" || fileExt == ".docx")
            {
                if (fileExt == ".docx")
                {
                    try
                    {
                        // Open a doc file.
                        Application app = new Application();
                        Microsoft.Office.Interop.Word.Document document = app.Documents.Open(fileName);

                        // Select all words from word file
                        int total = document.Words.Count;
                        for (int i = 1; i <= total; i++)
                        {
                            // Reading from word document into a string
                            content += document.Words[i].Text;
                        }
                        // Close word.
                        Console.WriteLine(content);
                        app.Quit();
                    }
                    catch
                    {
                        MessageBox.Show("File is used by another Process");
                        throw new ArgumentException("File is used by another Process.");
                    }
                }
                if (fileExt == ".pdf")
                {
                    try
                    {
                        StringBuilder fileContent = new StringBuilder();
                        using (PdfReader pdfReader = new PdfReader(filename))
                        {
                            for (int k = 1; k <= pdfReader.NumberOfPages; k++)
                            {
                                fileContent.Append(PdfTextExtractor.GetTextFromPage(pdfReader, k));
                            }
                        }
                        content = fileContent.ToString();
                    }
                    catch
                    {
                        MessageBox.Show("File is used by another Process");
                        throw new ArgumentException("File is used by another Process.");
                    }
                }
                //string content;

                Dictionary <char, int> Dic = new Dictionary <char, int>();
                Dic = myObj.frequencyPDF(content);
                //  myObj.printMap(Dic);

                //getting frequency


                //entering data in nodes then storing them in queue
                PQueue.PriorityQueue pQueue = new PQueue.PriorityQueue();
                pQueue = myObj.nodesinQueue(Dic);

                //  pQueue.print();

                //creating encooding tree
                myObj.root = myObj.HuffmanEncoding(pQueue);

                PQueue.cNode top = myObj.root; //temporary storing the value

                // Console.WriteLine(top.getValue());
                myObj.HuffCode(top, "");
                // myObj.printCodes(myObj.HuffmanCode);
            }
            else
            {
                FileStream fs;
                try
                {
                    fs = File.OpenRead(fileName);
                }
                catch
                {
                    MessageBox.Show("No File has been Uploaded");
                    throw new ArgumentException("A file should be uploaded.");
                }
                //String fs = File.ReadAllText(fileName);

                Dictionary <char, int> Dic = new Dictionary <char, int>();
                //Dic = myObj.frequency(fs);
                Dic = myObj.frequency(fs);
                // myObj.printMap(Dic);

                //getting frequency
                //entering data in nodes then storing them in queue
                PQueue.PriorityQueue pQueue = new PQueue.PriorityQueue();
                pQueue = myObj.nodesinQueue(Dic);

                // pQueue.print();

                //creating encooding tree
                myObj.root = myObj.HuffmanEncoding(pQueue);

                PQueue.cNode top = myObj.root; //temporary storing the value

                // Console.WriteLine(top.getValue());
                myObj.HuffCode(top, "");
                // myObj.printCodes(myObj.HuffmanCode);

                top = myObj.root; //temporary storing the value
            }

            MessageBox.Show("Compress Done Save File.");
        }
        //decompress the file

        public void pdfDecompress(string fileName)
        {
            readBitByBit bit = new readBitByBit(fileName);

            FileTreeroot = ReadTreeHeader(bit);
            program.printPreorder(FileTreeroot);


            int    returnbit = -1;   //initializing
            char   leaf      = '1';  //checking if we reached the end of file
            string content   = null; //initializing

            PQueue.cNode top = FileTreeroot;

            while (true)                                          //will run until we found the pseduo_EOF
            {
                if (top.leftZero == null && top.rightOne == null) //if leaf node is reached
                {
                    leaf = top.value;
                    if (leaf == (char)program.Pseudo_EOF)   //if it is last letter close the file
                    {
                        break;
                    }
                    else
                    {
                        content = content + leaf.ToString();
                    }
                    top = FileTreeroot;   //again start from root
                }

                returnbit = bit.bitRead();
                if (returnbit == 0)  //if not leaf keep on reading the file
                {
                    top = top.leftZero;
                }
                else if (returnbit == 1)
                {
                    top = top.rightOne;
                }
            }
            bit.close();

            string newC = null;

            try
            {
                newC = content.Substring(3);   // in case of empty file
            }
            catch
            {
            }

            //create pdf
            if (fileExten == ".pdf")
            {
                Document  document  = new Document(PageSize.A4, 50, 35, 50, 35);
                PdfWriter pdfWriter = PdfWriter.GetInstance(document, new FileStream(decmpFile, FileMode.Create));
                document.Open();
                Paragraph p = new Paragraph();
                p.Font = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 12f, BaseColor.BLACK);
                p.Add(newC);
                document.Add(p);
                document.Close();
            }


            if (fileExten == ".docx")
            {
                var doc = DocX.Create(decmpFile);
                doc.InsertParagraph(newC).Font("Times New Roman").FontSize(12d);  //inserting paragraph
                doc.Save();
            }
        }
        //Writng Compress File
        public void WriteCompressFile(FileStream fs)
        {
            // Create a new file
            writeBitByBit bit = new writeBitByBit(CompName);  //creating an instance of bit write

            //writing tree info
            PQueue.cNode top = root;
            printHeaderTree(top, bit);
            string code = "0";

            if (fileExten1 == ".csv")                      //code for csv is different because that code cause problem with csv files
            {
                var sr = new StreamReader(fs);             //opeining input file to be compreesed so to read from it and compare and store
                int c;
                while ((c = sr.Read()) != -1)              //reading char from input file
                {
                    if (frequencyMap.ContainsKey((char)c)) //while calculating frequencies we don't calculate 10 which is LF so we use try to avoid exception when 10 comes as it is not present in the HuffmanCode directory
                    {
                        code = HuffmanCode[(char)c];       //reading character's huffman code from th Code table
                    }

                    for (int i = 0; i < code.Length; ++i)    //reading each character from the Huffman code  like if code for A = 011 the first 0 then 1 and then 1
                    {
                        if (code[i] == '0')
                        {
                            bit.BitWrite(0);                //calling writing function with 0
                        }
                        else
                        {
                            bit.BitWrite(1);               //calling writing function with 1
                        }
                    }
                }
            }

            else   //code for .txt and .cpp .c .cs
            {
                using (var sr1 = new StreamReader(fs))
                {
                    while (!sr1.EndOfStream)
                    {
                        string s = sr1.ReadLine();
                        foreach (char ch in s)
                        {
                            if (frequencyMap.ContainsKey(ch))
                            {
                                code = HuffmanCode[ch];           //reading character's huffman code from th Code table
                            }
                            for (int i = 0; i < code.Length; ++i) //reading each character from the Huffman code  like if code for A = 011 the first 0 then 1 and then 1
                            {
                                if (code[i] == '0')
                                {
                                    bit.BitWrite(0);                //calling writing function with 0
                                }
                                else
                                {
                                    bit.BitWrite(1);               //calling writing function with 1
                                }
                            }
                        }
                    }
                }
            }


            //now we need to write psedu_EOF so that we don't reed extra bytes from the file
            code = HuffmanCode[(char)Pseudo_EOF];
            for (int i = 0; i < code.Length; ++i)    //reading each character from the Huffman code  like if code for A = 011 the first 0 then 1 and then 1
            {
                if (code[i] == '0')
                {
                    bit.BitWrite(0);                //calling writing function with 0
                }
                else
                {
                    bit.BitWrite(1);               //calling writing function with 1
                }
            }

            bit.close();
            fs.Close();
        }