int GUIFontManager::addFont(const TiXmlElement *fontNode)
{
  GUIFont *newFont  = new GUIFont();
  int      index    = -1;

  if(newFont->loadXMLSettings(fontNode))
  {
    index = findFontIndex(newFont);
    if(index >= 0)
    {
      deleteObject(newFont);
    }
    else
    {
      if(!newFont->build())
      {
        deleteObject(newFont);
      }
      else
      {
        if(newFont->build())
        {
          addFont(newFont);
          index = int(guiFontList.size() - 1);
        }
      }
    }
  }
  return index; 
}
int GUIFontManager::getCharacterWidth(char Char, int fontIndex)
{
  GUIFont *currentFont = getFont(fontIndex);
  currentFont          = currentFont ? currentFont : getDefaultFont();
  if(currentFont)
    return  currentFont->getFontObject()->getCharHorizontalGlyphs()[Char];  

  return 0;
}
int GUIFontManager::getCharacterWidth(char Char, GUIFont *font)
{
  GUIFont *currentFont = getDefaultFont();
  if(!font)
  {
    if(currentFont)
      return  currentFont->getFontObject()->getCharHorizontalGlyphs()[Char];  
  }
  else
    return font->getFontObject()->getCharHorizontalGlyphs()[Char];
  return 0;
}
//----[  set  ]----------------------------------------------------------------
void EvidyonGUIActionBindingDescription::set(const std::string& text,
                                             GUISize* panel_size) {
  {
    GUIFont* font = description_.getFont();
    GUISize size;
    font->getTextExtent(text.c_str(), text.length(), &size);
    size.width += 16;
    size.height += 16;
    *panel_size = size;
  }
  description_.setText(text.c_str());
  description_.setAlignment(GUIALIGN_LEFT_TOP);
}
//----- (0044D2FD) --------------------------------------------------------
void GUIFont::_44D2FD_prolly_draw_credits_entry( GUIFont *pSecondFont, int uFrameX, int uFrameY, unsigned int w, unsigned int h,
        unsigned __int16 firstColor, unsigned __int16 secondColor, const char *pString,
        unsigned __int16 *pPixels, unsigned int uPixelsWidth )
{
    char *work_string; // eax@1
    unsigned __int16 *curr_pixel_pos; // esi@1
    GUIFont *currentFont; // edi@4
    signed int start_str_pos; // ecx@4
    signed int line_w; // eax@6
    GUIWindow draw_window; // [sp+Ch] [bp-5Ch]@
    int currentColor; // [sp+74h] [bp+Ch]@4
    int half_frameX; // [sp+80h] [bp+18h]@2

    draw_window.uFrameHeight = h;
    draw_window.uFrameW = uFrameY + h - 1;
    draw_window.uFrameWidth = w;
    draw_window.uFrameZ = uFrameX + w - 1;
    ui_current_text_color = firstColor;
    draw_window.uFrameX = uFrameX;
    draw_window.uFrameY = uFrameY;

    work_string = GUIFont::FitTwoFontStringINWindow(pString, this, pSecondFont, &draw_window, 0, 1);
    work_string = strtok(work_string, "\n");
    curr_pixel_pos = &pPixels[uPixelsWidth * uFrameY];
    if ( work_string )
    {
        half_frameX = uFrameX >> 1;
        while ( 1 )
        {
            currentFont = this;
            ui_current_text_color = firstColor;
            start_str_pos = 0;
            currentColor = firstColor;
            if ( *work_string == '_' )
            {
                currentFont = pSecondFont;
                currentColor = secondColor;
                ui_current_text_color = secondColor;
                start_str_pos = 1;
            }
            line_w = (signed int)(w - currentFont->GetLineWidth(&work_string[start_str_pos]))/2;
            if ( line_w < 0 )
                line_w = 0;
            currentFont->DrawTextLineToBuff(currentColor, secondColor, &curr_pixel_pos[line_w + half_frameX], work_string, uPixelsWidth);
            curr_pixel_pos += uPixelsWidth * (currentFont->uFontHeight - 3);
            work_string = strtok(0, "\n");
            if ( !work_string )
                break;
        }
    }
}
//----[  setSpell  ]-----------------------------------------------------------
void EvidyonGUISpellDescription::setSpell(const Spell::SpellClientDescription* spell,
                                          GUISize* panel_size) {
  std::string text;
  text.append(spell->description);
  {
    GUIFont* font = description_.getFont();
    GUISize size;
    font->getTextExtent(text.c_str(), text.length(), &size);
    size.width += 16;
    size.height += 16;
    *panel_size = size;
  }
  description_.setText(text.c_str());
  description_.setAlignment(GUIALIGN_LEFT_TOP);
}
void  GUIText::print(int x, int y, int startIndex, int endIndex)
{
  if (!text.getLength())
    return;
    
  endIndex   = (endIndex  < 0) ? int(text.getLength()) : endIndex;
  startIndex = clamp(startIndex, 0, endIndex);
  
  GUIFontManager::setCurrentFont(fontIndex);
  GUIFont *currentFont = GUIFontManager::getCurrentFont();
  computeDimensions();
  
  if (!currentFont && !(currentFont = GUIFontManager::getDefaultFont()))
    return;
    
  currentFont->getFontObject()->printSubString(float(x), float(y), scales.x, scales.y,
      color.x, color.y, color.z,
      startIndex, endIndex,
      text);
}
void EvidyonGUIItemDescription::setItem(const ItemInStorage* storage_item,
                                        const ClientItemDescription* item_description,
                                        GUISize* panel_size) {
  std::string text;
  text.append(item_description->description);
  {
    GUIFont* font = description_.getFont();
    GUISize size;
    font->getTextExtent(text.c_str(), text.length(), &size);
    size.width += 40;
    size.width = max(size.width, 120);
    const int min_height = font->getCaretSize().height*3;
    size.height = max(min_height, size.height);
    size.width += 16;
    size.height += 16;
    *panel_size = size;
  }
  description_.setText(text.c_str());
  description_.setAlignment(GUIALIGN_LEFT_TOP);
}
void GUIText::computeDimensions()
{
  if (needUpdating())
  {
    GUIFontManager::setCurrentFont(fontIndex);
    GUIFont *currentFont = GUIFontManager::getCurrentFont();
    
    if (!currentFont && !(currentFont = GUIFontManager::getDefaultFont()))
      return;
      
    if (currentFont == GUIFontManager::getDefaultFont())
      fontIndex = GUIFontManager::findFontIndex(currentFont);
      
    if (text.getLength())
    {
      size = currentFont->getFontObject()->getStringDimensions(text);
      size.x = int(float(size.x)*scales.x);
    }
    size.y = int(float(currentFont->getFontObject()->getHeight())*scales.y);
    forceUpdate(false);
  }
}
void    GUITextBox::setupBlinker(int x)
{
  if (!focused || !active)
    return;
    
  GUIFont *font           = GUIFontManager::getFont(label.getFontIndex());
  const    String &string = label.getString();
  const    int    *spaces = NULL;
  blinkerPosition         = getWindowBounds().x + padding.x;
  x -= 1;
  
  if (font)
  {
    spaces = font->getFontObject()->getCharHorizontalGlyphs();
    
    for (size_t i = 0; i < string.getLength(); i++)
      if (blinkerPosition < x)
        blinkerPosition += spaces[int(string.getBytes()[i])];
  }
  
  blinkerOn = true;
}
void GUITextBox::setupText(int type, char Char)
{
  GUIFont *font           = GUIFontManager::getFont(label.getFontIndex());
  const    int    *spaces = font ? font->getFontObject()->getCharHorizontalGlyphs() : NULL,
                            length = label.getString().getLength();
  String   temp;
  int      start  = windowBounds.x + padding.x,
                    index  = 0;
                    
  if (!spaces)
    return;
    
  for (int t = 0; t < length; t++)
  {
    if (blinkerPosition > start)
    {
      index++;
      start += spaces[label.getCharString()[t]];
    }
  }
  
  if (type == INSERT_CHAR)
  {
    if (index != length && length)
    {
      String leftSide;
      leftSide.set(label.getCharString(), index);
      leftSide += Char;
      temp.set(label.getCharString() + index, length - index);
      label.setString(leftSide + temp);
    }
    else
    {
      temp  = label.getString();
      temp += Char;
      label.setString(temp);
    }
    blinkerPosition  = blinkerPosition + GUIFontManager::getCharacterWidth(Char, font);
  }
  
  if (type == BACKSPACE_DELETE && (blinkerPosition != windowBounds.x + padding.x))
  {
    if (index != length)
    {
      String leftSide;
      setupBlinker(blinkerPosition - GUIFontManager::getCharacterWidth(label.getCharString()[index -1],
                   label.getFontIndex()));
                   
      leftSide.set(label.getCharString(), index - 1);
      temp.set(label.getCharString() + index, length - index);
      label.setString(leftSide + temp);
      return;
    }
    
    setupBlinker(blinkerPosition - GUIFontManager::getCharacterWidth(label.getCharString()[length -1],
                 font));
                 
    temp.set(label.getCharString(), length - 1);
    if (temp.getLength())
      label.setString(temp);
    else
    {
      label.clear();
      blinkerPosition = windowBounds.x + padding.x;
    }
  }
  
  if (type == SIMPLE_DELETE && length)
  {
    if ((blinkerPosition == windowBounds.x + padding.x) && (length == 1))
    {
      label.clear();
      return;
    }
    
    if (index < length)
    {
      String leftSide;
      leftSide.set(label.getCharString(), index);
      temp.set(label.getCharString() + index + 1, length - index - 1);
      label.setString(leftSide + temp);
    }
  }
  if (type == PARSE_VISIBLE)
    textEndIndex = font->getFontObject()->getMaxFittingLength(label.getString(), getWidth());
}
void EvidyonGUIItemDescription::setItem(const ClientAvatarInventoryItem* inventory_item,
                                        const ClientItemDescription* item_description,
                                        GUISize* panel_size) {
  std::string text;
  /*int quantity = inventory_item->quantity;
  if (quantity > 1) {
    char num[16];
    sprintf_s(num, 16, "%i ", quantity);
    text.append(num);
  }
  text.append(item_description->name);
  text.append("\n");*/
  text.append(item_description->description);
  {
    GUIFont* font = description_.getFont();
    GUISize size;
    font->getTextExtent(text.c_str(), text.length(), &size);
    size.width += 40;
    size.width = max(size.width, 120);
    const int min_height = font->getCaretSize().height*3;
    size.height = max(min_height, size.height);
    size.width += 16;
    size.height += 16;
    *panel_size = size;
  }
  description_.setText(text.c_str());
  description_.setAlignment(GUIALIGN_LEFT_TOP);

/*
  // parse out the text to make sure it fits within the given region
  std::string description_text;
  int lines = 0;
  while (false == text.empty()) {
    size_t first_whitespace = text.find_first_of("\n");
    size_t length = first_whitespace;
    GUISize size;
    //if (!font->getTextExtent(text.substr(0, length).c_str(), -1, &size)) break;
    //if (size.width > width) {
      //length -= (int)((width-size.width) / (font->getCaretSize().height * 1.0f));
      do {
        if (!font->getTextExtent(text.substr(0, length).c_str(), -1, &size)) break;
      } while (size.width > width && ((length--) > 2));
    //}
    if (length != text.npos) {
      size_t last_length = length;
      while (length > 0 && text.at(length) != ' ') --length;
      if (length <= 1) {
        length = last_length;
      } else {
        first_whitespace = length;
      }
    }
    description_text.append(text.substr(0, length));
    description_text.append("\n");
    if (length == first_whitespace && length != text.npos) {
      ++length;
      while (text.size() > length && text.at(length) == ' ') ++length;
    }
    text.erase(0, length);
    ++lines;
  }*/

  //description_.setText(description_text.c_str());
}