/******************************************************************************
 *
 * Copyright (C) 1997-2015 by Dimitri van Heesch.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby
 * granted. No representations are made about the suitability of this software
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
 * Documents produced by Doxygen are derivative works derived from the
 * input used in their production; they are not affected by this license.
 *
 */
#include "eclipsehelp.h"
#include "util.h"
#include "config.h"
#include "message.h"
#include "doxygen.h"

EclipseHelp::EclipseHelp() : m_depth(0), m_endtag(FALSE), m_openTags(0)
{
}

EclipseHelp::~EclipseHelp()
{
}

void EclipseHelp::indent()
{
  int i;
  for (i=0; i<m_depth; i++)
  {
    m_tocstream << "  ";
  }
}

void EclipseHelp::closedTag()
{
  if (m_endtag)
  {
    m_tocstream << "/>\n";
    m_endtag = FALSE;
  }
}

void EclipseHelp::openedTag()
{
  if (m_endtag)
  {
    m_tocstream << ">\n";
    m_endtag = FALSE;
    ++m_openTags;
  }
}

/*!
 * \brief Initialize the Eclipse generator
 *
 * This method opens the XML TOC file and writes headers of the files.
 * \sa finalize()
 */
void EclipseHelp::initialize()
{
  // -- read path prefix from the configuration
  //m_pathprefix = Config_getString(ECLIPSE_PATHPREFIX);
  //if (m_pathprefix.isEmpty()) m_pathprefix = "html/";

  // -- open the contents file
  QCString name = Config_getString(HTML_OUTPUT) + "/toc.xml";
  m_tocstream.open(name.str(), std::ofstream::out | std::ofstream::binary);
  if (!m_tocstream.is_open())
  {
    term("Could not open file %s for writing\n", qPrint(name));
  }

  // -- write the opening tag
  QCString title = Config_getString(PROJECT_NAME);
  if (title.isEmpty())
  {
    title = "Doxygen generated documentation";
  }
  m_tocstream << "<toc label=\"" << convertToXML(title)
              << "\" topic=\"" << convertToXML(m_pathprefix)
              << "index" << Doxygen::htmlFileExtension << "\">\n";
  ++ m_depth;
}

/*!
 * \brief Finish generation of the Eclipse specific help files
 *
 * This method writes footers of the files and closes them.
 * \sa initialize()
 */
void EclipseHelp::finalize()
{
  closedTag(); // -- close previous tag

  // -- write ending tag
  --m_depth;
  m_tocstream << "</toc>\n";

  // -- close the content file
  m_tocstream.close();

  QCString name = Config_getString(HTML_OUTPUT) + "/plugin.xml";
  std::ofstream t(name.str(),std::ofstream::out | std::ofstream::binary);
  if (t.is_open())
  {
    QCString docId = Config_getString(ECLIPSE_DOC_ID);
    t << "<plugin name=\""  << docId << "\" id=\"" << docId << "\"\n";
    t << "        version=\"1.0.0\" provider-name=\"Doxygen\">\n";
    t << "  <extension point=\"org.eclipse.help.toc\">\n";
    t << "    <toc file=\"toc.xml\" primary=\"true\" />\n";
    t << "  </extension>\n";
    t << "</plugin>\n";
  }
}

/*!
 * \brief Increase the level of content hierarchy
 */
void EclipseHelp::incContentsDepth()
{
  openedTag();
  ++m_depth;
}

/*!
 * \brief Decrease the level of content hierarchy
 *
 * It closes currently opened topic tag.
 */
void EclipseHelp::decContentsDepth()
{
  // -- end of the opened topic
  closedTag();
  --m_depth;

  if (m_openTags==m_depth)
  {
    --m_openTags;
    indent();
    m_tocstream << "</topic>\n";
  }
}

/*!
 * \brief Add an item to the content
 *
 * @param isDir Flag whether the argument \a file is a directory or a file entry
 * @param name Name of the item
 * @param ref URL of the item
 * @param file Name of a file which the item is defined in (without extension)
 * @param anchor Name of an anchor of the item.
 * @param separateIndex not used.
 * @param addToNavIndex not used.
 * @param def not used.
 */
void EclipseHelp::addContentsItem(
    bool /* isDir */,
    const QCString &name,
    const QCString & /* ref */,
    const QCString &file,
    const QCString &anchor,
    bool /* separateIndex */,
    bool /* addToNavIndex */,
    const Definition * /*def*/)
{
  // -- write the topic tag
  closedTag();
  if (!file.isEmpty())
  {
    switch (file[0]) // check for special markers (user defined URLs)
    {
      case '^':
        // URL not supported by eclipse toc.xml
	break;

      case '!':
        indent();
        m_tocstream << "<topic label=\"" << convertToXML(name) << "\"";
        m_tocstream << " href=\"" << convertToXML(m_pathprefix) << &file[1] << "\"";
        m_endtag = TRUE;
	break;

      default:
        indent();
        m_tocstream << "<topic label=\"" << convertToXML(name) << "\"";
        m_tocstream << " href=\"" << convertToXML(m_pathprefix)
                    << addHtmlExtensionIfMissing(file);
        if (!anchor.isEmpty())
        {
          m_tocstream << "#" << anchor;
        }
        m_tocstream << "\"";
        m_endtag = TRUE;
	break;
    }
  }
  else
  {
    indent();
    m_tocstream << "<topic label=\"" << convertToXML(name) << "\"";
    m_endtag = TRUE;
  }
}

void EclipseHelp::addIndexItem(
    const Definition * /* context */,
    const MemberDef * /* md */,
    const QCString & /* sectionAnchor */,
    const QCString & /* title */)
{
}

void EclipseHelp::addIndexFile(const QCString & /* name */)
{
}

void EclipseHelp::addImageFile(const QCString & /* name */)
{
}

void EclipseHelp::addStyleSheetFile(const QCString & /* name */)
{
}

