/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmDocumentationFormatter.h"

#include "cmDocumentationSection.h"

cmDocumentationFormatter::cmDocumentationFormatter():
  TextWidth(77), TextIndent("")
{
}

cmDocumentationFormatter::~cmDocumentationFormatter()
{
}

void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
                                              const char* text)
{
  if(!text)
    {
    return;
    }
  const char* ptr = text;
  while(*ptr)
    {
    // Any ptrs starting in a space are treated as preformatted text.
    std::string preformatted;
    while(*ptr == ' ')
      {
      for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr)
        {
        preformatted.append(1, ch);
        }
      if(*ptr)
        {
        ++ptr;
        preformatted.append(1, '\n');
        }
      }
    if(!preformatted.empty())
      {
      this->PrintPreformatted(os, preformatted.c_str());
      }

    // Other ptrs are treated as paragraphs.
    std::string paragraph;
    for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr)
      {
      paragraph.append(1, ch);
      }
    if(*ptr)
      {
      ++ptr;
      paragraph.append(1, '\n');
      }
    if(!paragraph.empty())
      {
      this->PrintParagraph(os, paragraph.c_str());
      }
    }
}

void cmDocumentationFormatter::PrintPreformatted(std::ostream& os,
                                                     const char* text)
{
  bool newline = true;
  for(const char* ptr = text; *ptr; ++ptr)
    {
    if(newline && *ptr != '\n')
      {
      os << this->TextIndent;
      newline = false;
      }
    os << *ptr;
    if(*ptr == '\n')
      {
      newline = true;
      }
    }
  os << "\n";
}

void cmDocumentationFormatter::PrintParagraph(std::ostream& os,
                                              const char* text)
{
  os << this->TextIndent;
  this->PrintColumn(os, text);
  os << "\n";
}

void cmDocumentationFormatter::SetIndent(const char* indent)
{
  this->TextIndent = indent;
}

void cmDocumentationFormatter::PrintColumn(std::ostream& os,
                                           const char* text)
{
  // Print text arranged in an indented column of fixed witdh.
  const char* l = text;
  long column = 0;
  bool newSentence = false;
  bool firstLine = true;
  int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));

  // Loop until the end of the text.
  while(*l)
    {
    // Parse the next word.
    const char* r = l;
    while(*r && (*r != '\n') && (*r != ' ')) { ++r; }

    // Does it fit on this line?
    if(r-l < (width-column-(newSentence?1:0)))
      {
      // Word fits on this line.
      if(r > l)
        {
        if(column)
          {
          // Not first word on line.  Separate from the previous word
          // by a space, or two if this is a new sentence.
          if(newSentence)
            {
            os << "  ";
            column += 2;
            }
          else
            {
            os << " ";
            column += 1;
            }
          }
        else
          {
          // First word on line.  Print indentation unless this is the
          // first line.
          os << (firstLine?"":this->TextIndent);
          }

        // Print the word.
        os.write(l, static_cast<long>(r-l));
        newSentence = (*(r-1) == '.');
        }

      if(*r == '\n')
        {
        // Text provided a newline.  Start a new line.
        os << "\n";
        ++r;
        column = 0;
        firstLine = false;
        }
      else
        {
        // No provided newline.  Continue this line.
        column += static_cast<long>(r-l);
        }
      }
    else
      {
      // Word does not fit on this line.  Start a new line.
      os << "\n";
      firstLine = false;
      if(r > l)
        {
        os << this->TextIndent;
        os.write(l, static_cast<long>(r-l));
        column = static_cast<long>(r-l);
        newSentence = (*(r-1) == '.');
        }
      else
        {
        column = 0;
        }
      }

    // Move to beginning of next word.  Skip over whitespace.
    l = r;
    while(*l && (*l == ' ')) { ++l; }
    }
}

void cmDocumentationFormatter
::PrintSection(std::ostream& os,
               cmDocumentationSection const& section)
{
  os << section.GetName() << "\n";

  const std::vector<cmDocumentationEntry> &entries =
    section.GetEntries();
  for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
      op != entries.end(); ++op)
    {
    if(!op->Name.empty())
      {
      os << "  " << op->Name;
      this->TextIndent = "                                 ";
      int align = static_cast<int>(strlen(this->TextIndent))-4;
      for(int i = static_cast<int>(op->Name.size()); i < align; ++i)
        {
        os << " ";
        }
      if (op->Name.size() > strlen(this->TextIndent)-4 )
        {
        os << "\n";
        os.write(this->TextIndent, strlen(this->TextIndent)-2);
        }
      os << "= ";
      this->PrintColumn(os, op->Brief.c_str());
      os << "\n";
      }
    else
      {
      os << "\n";
      this->TextIndent = "";
      this->PrintFormatted(os, op->Brief.c_str());
      }
    }
  os << "\n";
}
