public string getLetterBitStream(Histo root, char Letter)
        {
            string Result = "";

            if (root != null)
            {
                for (int i = 0; i < root.nextstates.Count; i++)
                {
                    Result += root.Transition;
                    string Temp = getLetterBitStream((Histo)root.nextstates[i], Letter);
                    if (Temp != "")
                    {
                        Result += Temp;
                        break;
                    }
                    else
                    if (Result != "")
                    {
                        Result = Result.Substring(0, Result.Length - 1);
                    }
                }
                if (Letter == root.Key[0] && root.Key != "Node")
                {
                    return(root.Transition);
                }
                else
                {
                    return(Result);
                }
            }
            else
            {
                return("");
            }
        }
 public Histo HoffmanCompress(string Data)
 {
     GetHistogram(Data);
     Result           = HoffmanCore();
     Result.IsInitial = true;
     return(Result);
 }
        public string getStringBitStream(Histo root, string Data)
        {
            string Result = "";

            for (int i = 0; i < Data.Length; i++)
            {
                Result += getLetterBitStream(root, Data[i]);
            }
            return(Result);
        }
 private void CalculateSegments(Histo root, int StartIndex)
 {
     if (root != null)
     {
         GlobalHeightCounter[StartIndex]++;
         for (int i = 0; i < root.nextstates.Count; i++)
         {
             CalculateSegments((Histo)root.nextstates[i], StartIndex + 1);
         }
     }
 }
        private Histo HoffmanCore()
        {
            Dictionary.Sort(new Histo());

            Histo root = new Histo();
            Histo H1   = new Histo();
            Histo H2   = new Histo();

            H1 = (Histo)Dictionary[Dictionary.Count - 1];
            if (Dictionary.Count > 1)
            {
                H2 = (Histo)Dictionary[Dictionary.Count - 2];
                if (H2.Kind != "Node")
                {
                    H2.Kind = "Leaf";
                }
                H2.Transition = "0";
                root.nextstates.Add(H2);
            }
            if (H1.Kind != "Node")
            {
                H1.Kind = "Leaf";
            }
            H1.Transition = "1";
            root.nextstates.Add(H1);
            root.Value = ((Histo)Dictionary[Dictionary.Count - 1]).Value;
            if (Dictionary.Count > 1)
            {
                root.Value += ((Histo)Dictionary[Dictionary.Count - 2]).Value;
                Dictionary.RemoveAt(Dictionary.Count - 1);
            }
            Dictionary.RemoveAt(Dictionary.Count - 1);
            root.Key  = "Node  " + Counter;
            root.Kind = "Node";
            Counter++;
            if (Dictionary.Count == 0)
            {
                return(root);
            }
            Dictionary.Add(root);
            if (Dictionary.Count > 1)
            {
                return(HoffmanCore());
            }
            else
            {
                return(root);
            }
        }
 private int CalculateWidth(Histo root, int width)
 {
     try
     {
         int NewWidth = width;
         int Temp     = 0;
         if (root != null && root.nextstates.Count != 0)
         {
             NewWidth++;
         }
         for (int i = 0; i < root.nextstates.Count; i++)
         {
             Histo Te = (Histo)root.nextstates[i];
             Temp = CalculateWidth(Te, NewWidth);
         }
         if (Temp > NewWidth && Temp > maxwidth)
         {
             maxwidth = Temp;
             return(Temp);
         }
         else
         {
             if (NewWidth > maxwidth)
             {
                 maxwidth = NewWidth;
                 return(NewWidth);
             }
             else
             {
                 return(maxwidth);
             }
         }
     }
     catch (Exception ex)
     {
         return(0);
     }
 }
        private void GetHistogram(string Data)
        {
            Histogram = new int[256];
            for (int i = 0; i < 256; i++)
            {
                Histogram[i] = 0;
            }
            for (int i = 0; i < Data.Length; i++)
            {
                Histogram[Data[i]]++;
            }

            for (int i = 0; i < 256; i++)
            {
                if (Histogram[i] != 0)
                {
                    Histo H = new Histo();
                    H.Key   = Convert.ToChar(i).ToString();
                    H.Value = Histogram[i];
                    Dictionary.Add(H);
                }
            }
        }
        private void Draw(Histo Rroot, Histo root, int HeightCounter, int HeightBlock, int x, int y)
        {
            if (root != null && root.Key != "")
            {
                if (root.IsInitial)
                {
                    g.DrawEllipse(StatePen, (BlockCounter * DrawBlock + DrawBlock / 2) - Radius, panel1.Height / 2 - Radius, Radius * 2, Radius * 2);
                    g.DrawString(root.Kind, new Font(FontFamily.GenericSansSerif, 12, FontStyle.Bold), StatePen.Brush, (BlockCounter * DrawBlock + DrawBlock / 2) - 20, panel1.Height / 2 - 10);
                    if (ShowValuesCB.Checked)
                    {
                        g.DrawString(root.Kind + "," + root.Value, new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold), StatePen.Brush, (BlockCounter * DrawBlock + DrawBlock / 2) - 30, panel1.Height / 2 - 50);
                    }
                    BlockCounter++;
                    for (int i = 0; i < root.nextstates.Count; i++)
                    {
                        Histo Temp = (Histo)root.nextstates[i];
                        Draw(root, Temp, i, panel1.Size.Height / root.nextstates.Count, ((BlockCounter - 1) * DrawBlock + DrawBlock / 2) + Radius, panel1.Height / 2);
                    }
                }
                else
                {
                    g.DrawEllipse(StatePen, (BlockCounter * DrawBlock + DrawBlock / 2) - Radius, (HeightCounter * HeightBlock + HeightBlock / 2) - Radius, Radius * 2, Radius * 2);
                    g.DrawLine(TransitionPen, x, y, (BlockCounter * DrawBlock + DrawBlock / 2) - Radius, (HeightCounter * HeightBlock + HeightBlock / 2));

                    StateNumber++;

                    g.DrawString(root.Kind, new Font(FontFamily.GenericSansSerif, 12, FontStyle.Bold), StatePen.Brush, (BlockCounter * DrawBlock + DrawBlock / 2) - 20, (HeightCounter * HeightBlock + HeightBlock / 2) - 10);
                    int NewX = (((BlockCounter * DrawBlock + DrawBlock / 2) - Radius) - x) / 2 + x;
                    int OldX = NewX;
                    int NewY = y + ((HeightCounter * HeightBlock + HeightBlock / 2) - y) / 2;
                    if (y <= (HeightCounter * HeightBlock + HeightBlock / 2))
                    {
                        g.DrawString(root.Transition, new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold), StatePen.Brush, NewX, NewY);
                        NewX -= 10;
                        if (NewX < x)
                        {
                            NewY += 20;
                            NewX  = OldX;
                        }
                    }
                    else
                    {
                        g.DrawString(root.Transition, new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold), StatePen.Brush, NewX, (y - (HeightCounter * HeightBlock + HeightBlock / 2)) / 2 + (HeightCounter * HeightBlock + HeightBlock / 2));
                        NewX += 10;
                    }
                    if (ShowValuesCB.Checked)
                    {
                        g.DrawString(root.Key + "," + root.Value, new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold), StatePen.Brush, (BlockCounter * DrawBlock + DrawBlock / 2) - 30, (HeightCounter * HeightBlock + HeightBlock / 2) - 50);
                    }
                    if (root.nextstates.Count != 0)
                    {
                        BlockCounter++;
                        //GlobalHeightCounter[BlockCounter] = 0;
                        for (int i = 0; i < root.nextstates.Count; i++)
                        {
                            Histo Temp      = (Histo)root.nextstates[i];
                            int   NextLevel = 0;
                            for (int j = 0; j < Rroot.nextstates.Count; j++)
                            {
                                NextLevel += ((Histo)Rroot.nextstates[j]).nextstates.Count;
                            }
                            Draw(root, Temp, TempGlobalHeightCounter[BlockCounter], panel1.Size.Height / GlobalHeightCounter[BlockCounter], ((BlockCounter - 1) * DrawBlock + DrawBlock / 2) + Radius, (HeightCounter * HeightBlock + HeightBlock / 2));
                            TempGlobalHeightCounter[BlockCounter]++;
                        }
                        BlockCounter--;
                    }
                }
            }
        }