/*============================================================================
  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";
}
