#include "Teuchos_VerboseObject.hpp"
#include "Teuchos_StandardCatchMacros.hpp"
#include "Teuchos_StandardParameterEntryValidators.hpp"
#include "Teuchos_dyn_cast.hpp"
#include "Teuchos_Version.hpp"
#include "AlgorithmA.hpp"
{
  
  
  AlgorithmA algoA;
  if (algoParams)
  
  
  
  algoA.doAlgorithm();
  *algoA.getOStream() << std::endl;
}
class TestVerboseObjectBaseInitialization {
public:
  TestVerboseObjectBaseInitialization()
    {
      
      
      
        << "\n***\n*** Printing to default OStream before main() even starts!\n***\n\n"
        << std::flush;
    }
};
static TestVerboseObjectBaseInitialization testVerboseObjectBaseInitialization;
int main(int argc, char* argv[])
{
  bool success = true;
  try {
    
    CommandLineProcessor  clp;
    clp.throwExceptions(false);
    clp.addOutputSetupOptions(true);
    CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
    if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
    
    RCP<FancyOStream>
      out = VerboseObjectBase::getDefaultOStream();
    
    
    
    *out << std::endl << Teuchos::Teuchos_Version() << std::endl << std::endl;
    
    
    
    
    *out << "\n***\n*** Testing VerboseObject base class use\n***\n";
    *out << "\n*** Algorithm output with default formatting\n\n";
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with no front matter\n\n";
    out->setShowAllFrontMatter(false);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with processor ranks\n\n";
    out->setShowAllFrontMatter(false).setShowProcRank(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with line prefix names\n\n";
    out->setShowAllFrontMatter(false).setShowLinePrefix(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with tab counts\n\n";
    out->setShowAllFrontMatter(false).setShowTabCount(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with line prefix names and tab counts\n\n";
    out->setShowAllFrontMatter(false).setShowLinePrefix(true).setShowTabCount(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with processor ranks and line prefix names\n\n";
    out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with processor ranks and tab counts\n\n";
    out->setShowAllFrontMatter(false).setShowProcRank(true).setShowTabCount(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with processor ranks, line prefix names, and tab counts\n\n";
    out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true).setShowTabCount(true);
    doAlgorithmStuff();
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Algorithm output with processor ranks, line prefix names, and tab counts but no output for AlgorithmA\n\n";
    out->setShowAllFrontMatter(false).setShowProcRank(true).setShowLinePrefix(true).setShowTabCount(true);
    doAlgorithmStuff();
    *out << "\n*** Running the algorithm by setting parameters in the parameter list ...\n";
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Set AlgorithmA verbosity level to extreme through a parameter list\n\n";
    algoParams.sublist("VerboseObject").set("Verbosity Level","extreme");
    algoParams.set("Algo Type","Harry");
    algoParams.set("Algo Tol",0.3);
    doAlgorithmStuff(&algoParams);
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Set AlgorithmA verbosity level to medium and the output file \"AlgorithmA.out\" through a parameter list\n\n";
    algoParams.sublist("VerboseObject").set("Verbosity Level","medium");
    algoParams.sublist("VerboseObject").set("Output File","AlgorithmA.out");
    algoParams.set("Algo Type","John");
    algoParams.set("Algo Tol",10);
    doAlgorithmStuff(&algoParams);
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n*** Set AlgorithmA verbosity level to low and the output back to default through a parameter list\n\n";
    algoParams.sublist("VerboseObject").set("Verbosity Level","low");
    algoParams.sublist("VerboseObject").set("Output File","none");
    algoParams.set("Algo Tol","20");
    doAlgorithmStuff(&algoParams);
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1);
    *out << "\n***\n*** Do some more simple tests to make sure things work correctly\n***\n\n";
    
    
    
    
    out->setShowAllFrontMatter(false).setShowProcRank(numProcs>1).setShowTabCount(true);
    out->setProcRankAndSize(mpiSession.getRank(),mpiSession.getNProc());
    *out << "\n***\n*** Testing basic FancyOStream and OSTab classes\n***\n\n";
    *out << "\nThis is very good output\nand I like it a lot!\n";
    *out << "";
    *out << "\n";
    *out << "This should";
    *out << " all be";
    *out << " printed on";
    *out << " the same";
    *out << " line two lines below the above output!\n";
    RCP<FancyOStream>
    {
      *out << "This should be indented one tab!\n";
      {
        *out << "This should be indented two tabs!\n";
        *out2 << "This should be indented zero tabs from out2!\n";
        {
          *out << "This should be indented two tabs!\n";
          *out2 << "This should be indented one tab from out2!\n";
        }
      }
      *out << "This should be indented one tab!\n";
    }
    *out << "This should be indented zero tabs!\n";
    *out << std::endl; 
    *out << "\n***\n*** Now outputting the latent output that was sent to out2\n***\n\n"
         << 
dyn_cast<std::ostringstream>(*out2->getOStream()).str();
    if(success)
      *out << "\nEnd Result: TEST PASSED" << std::endl;
  }
  return ( success ? 0 : 1 );
}