/**
 * @file markdown/generate_markdown.cpp.in
 * @author Ryan Curtin
 *
 * This file is configured by CMake to generate all of the Markdown required by
 * the project.
 */
#include <mlpack/core.hpp>
#include "binding_info.hpp"
#include "print_doc_functions.hpp"

#include "generate_markdown.adaboost.hpp"
#include "generate_markdown.approx_kfn.hpp"
#include "generate_markdown.cf.hpp"
#include "generate_markdown.dbscan.hpp"
#include "generate_markdown.decision_stump.hpp"
#include "generate_markdown.decision_tree.hpp"
#include "generate_markdown.det.hpp"
#include "generate_markdown.emst.hpp"
#include "generate_markdown.fastmks.hpp"
#include "generate_markdown.gmm_train.hpp"
#include "generate_markdown.gmm_generate.hpp"
#include "generate_markdown.gmm_probability.hpp"
#include "generate_markdown.hmm_train.hpp"
#include "generate_markdown.hmm_loglik.hpp"
#include "generate_markdown.hmm_viterbi.hpp"
#include "generate_markdown.hmm_generate.hpp"
#include "generate_markdown.hoeffding_tree.hpp"
#include "generate_markdown.kde.hpp"
#include "generate_markdown.kernel_pca.hpp"
#include "generate_markdown.kmeans.hpp"
#include "generate_markdown.lars.hpp"
#include "generate_markdown.linear_regression.hpp"
#include "generate_markdown.linear_svm.hpp"
#include "generate_markdown.lmnn.hpp"
#include "generate_markdown.local_coordinate_coding.hpp"
#include "generate_markdown.logistic_regression.hpp"
#include "generate_markdown.lsh.hpp"
#include "generate_markdown.mean_shift.hpp"
#include "generate_markdown.nbc.hpp"
#include "generate_markdown.nca.hpp"
#include "generate_markdown.knn.hpp"
#include "generate_markdown.kfn.hpp"
#include "generate_markdown.nmf.hpp"
#include "generate_markdown.pca.hpp"
#include "generate_markdown.perceptron.hpp"
#include "generate_markdown.preprocess_split.hpp"
#include "generate_markdown.preprocess_binarize.hpp"
#include "generate_markdown.preprocess_describe.hpp"
#include "generate_markdown.preprocess_imputer.hpp"
#include "generate_markdown.preprocess_scale.hpp"
#include "generate_markdown.image_converter.hpp"
#include "generate_markdown.radical.hpp"
#include "generate_markdown.random_forest.hpp"
#include "generate_markdown.range_search.hpp"
#include "generate_markdown.krann.hpp"
#include "generate_markdown.softmax_regression.hpp"
#include "generate_markdown.sparse_coding.hpp"

using namespace mlpack;
using namespace mlpack::bindings;
using namespace mlpack::bindings::markdown;
using namespace std;

int main()
{
  // These come to use from CMake separated by semicolons.
  string languageList = "cli;python;julia;go";
  vector<string> languages;
  size_t index;
  while ((index = languageList.find(';')) != string::npos)
  {
    languages.push_back(languageList.substr(0, index));
    languageList = languageList.substr(index + 1);
  }
  languages.push_back(languageList);

  cout << "<div id=\"header\" markdown=\"1\">" << endl;

  // We need to create the input form selector for the language.
  cout << "<form>" << endl;
  cout << "  <div class=\"language-select-div\">" << endl;
  cout << "  <select id=\"language-select\" onchange=\"changeLanguage()\">"
      << endl;

  // Print the first manually, because it is selected.
  cout << "    <option value=\"" << languages[0] << "\" selected>"
      << languages[0] << "</option>" << endl;
  for (size_t i = 1; i < languages.size(); ++i)
  {
    cout << "    <option value=\"" << languages[i] << "\">" << languages[i]
        << "</option>" << endl;
  }

  cout << "  </select>" << endl;
  cout << "  </div>" << endl;
  cout << "</form>" << endl;
  cout << endl;

  // The links to the data type sections get put here.
  cout << " - [mlpack overview](#mlpack-overview){: .language-link #always }"
      << endl;
  for (size_t i = 0; i < languages.size(); ++i)
  {
    cout << " - [data formats](#" << languages[i] << "_data-formats){: "
        << ".language-link #" << languages[i] << " }" << endl;
  }

    cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>classification:</h5>" << endl;

  PrintadaboostHeaders();
  Printdecision_stumpHeaders();
  Printdecision_treeHeaders();
  Printhoeffding_treeHeaders();
  Printlinear_svmHeaders();
  Printlogistic_regressionHeaders();
  PrintnbcHeaders();
  PrintperceptronHeaders();
  Printrandom_forestHeaders();
  Printsoftmax_regressionHeaders();
  cout << "</div>" << endl << endl;  cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>regression:</h5>" << endl;

  PrintlarsHeaders();
  Printlinear_regressionHeaders();
  cout << "</div>" << endl << endl;  cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>clustering:</h5>" << endl;

  PrintdbscanHeaders();
  Printgmm_trainHeaders();
  Printgmm_generateHeaders();
  Printgmm_probabilityHeaders();
  PrintkmeansHeaders();
  Printmean_shiftHeaders();
  cout << "</div>" << endl << endl;  cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>geometry:</h5>" << endl;

  Printapprox_kfnHeaders();
  PrintemstHeaders();
  PrintfastmksHeaders();
  PrintlshHeaders();
  PrintknnHeaders();
  PrintkfnHeaders();
  Printrange_searchHeaders();
  PrintkrannHeaders();
  cout << "</div>" << endl << endl;  cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>preprocessing:</h5>" << endl;

  Printpreprocess_splitHeaders();
  Printpreprocess_binarizeHeaders();
  Printpreprocess_describeHeaders();
  Printpreprocess_imputerHeaders();
  Printpreprocess_scaleHeaders();
  Printimage_converterHeaders();
  cout << "</div>" << endl << endl;  cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>misc. / other:</h5>" << endl;

  PrintcfHeaders();
  PrintdetHeaders();
  Printhmm_trainHeaders();
  Printhmm_loglikHeaders();
  Printhmm_viterbiHeaders();
  Printhmm_generateHeaders();
  PrintkdeHeaders();
  PrintnmfHeaders();
  cout << "</div>" << endl << endl;  cout << "<div class=\"category\" markdown=\"1\">" << endl;
  cout << "<h5>transformations:</h5>" << endl;

  Printkernel_pcaHeaders();
  PrintlmnnHeaders();
  Printlocal_coordinate_codingHeaders();
  PrintncaHeaders();
  PrintpcaHeaders();
  PrintradicalHeaders();
  Printsparse_codingHeaders();
  cout << "</div>" << endl << endl;

  cout << endl << "</div>" << endl << endl;

  cout << "<div id=\"docs\" markdown=\"1\">" << endl;
  cout << endl;

  // Create all the headers for each language.
  for (size_t i = 0; i < languages.size(); ++i)
  {
    cout << "<div id=\"" << languages[i] << "\" class=\"language-header\" "
        << "markdown=\"1\">" << endl;
    cout << "# " << util::GetVersion() << " " << PrintLanguage(languages[i])
        << " binding documentation" << endl;
    cout << "</div>" << endl;
  }

  /**
   * "mlpack overview" section.  This will go at the top of the page.
   */
  cout << "## mlpack overview" << endl;
  cout << endl;
  cout << "mlpack is an intuitive, fast, and flexible C++ machine learning "
      "library with bindings to other languages.  It is meant to be a machine "
      "learning analog to LAPACK, and aims to implement a wide array of machine"
      " learning methods and functions as a \"swiss army knife\" for machine "
      "learning researchers.";
  cout << endl << endl;
  cout << "This reference page details mlpack's bindings to other languages. "
      "Further useful mlpack documentation links are given below.";
  cout << endl << endl;
  cout << " - [mlpack homepage](https://www.mlpack.org/)" << endl;
  cout << " - [mlpack on Github](https://github.com/mlpack/mlpack)" << endl;
  cout << " - [mlpack main documentation page]"
      << "(https://www.mlpack.org/docs.html)" << endl;
  cout << endl;

  /**
   * Discussion of different data types section.  This goes just below the
   * overview section at the top of the page.
   */
  for (size_t i = 0; i < languages.size(); ++i)
  {
    BindingInfo::Language() = languages[i];
    cout << PrintTypeDocs() << endl;
  }

  
  PrintadaboostDocs();
  Printapprox_kfnDocs();
  PrintcfDocs();
  PrintdbscanDocs();
  Printdecision_stumpDocs();
  Printdecision_treeDocs();
  PrintdetDocs();
  PrintemstDocs();
  PrintfastmksDocs();
  Printgmm_trainDocs();
  Printgmm_generateDocs();
  Printgmm_probabilityDocs();
  Printhmm_trainDocs();
  Printhmm_loglikDocs();
  Printhmm_viterbiDocs();
  Printhmm_generateDocs();
  Printhoeffding_treeDocs();
  PrintkdeDocs();
  Printkernel_pcaDocs();
  PrintkmeansDocs();
  PrintlarsDocs();
  Printlinear_regressionDocs();
  Printlinear_svmDocs();
  PrintlmnnDocs();
  Printlocal_coordinate_codingDocs();
  Printlogistic_regressionDocs();
  PrintlshDocs();
  Printmean_shiftDocs();
  PrintnbcDocs();
  PrintncaDocs();
  PrintknnDocs();
  PrintkfnDocs();
  PrintnmfDocs();
  PrintpcaDocs();
  PrintperceptronDocs();
  Printpreprocess_splitDocs();
  Printpreprocess_binarizeDocs();
  Printpreprocess_describeDocs();
  Printpreprocess_imputerDocs();
  Printpreprocess_scaleDocs();
  Printimage_converterDocs();
  PrintradicalDocs();
  Printrandom_forestDocs();
  Printrange_searchDocs();
  PrintkrannDocs();
  Printsoftmax_regressionDocs();
  Printsparse_codingDocs();
  cout << "</div>" << endl << endl;

  // Make sure script gets included for changeLanguage().
  cout << "<script src=\"res/change_language.js\"></script>" << endl;
}
