#include "xerces_parser.h"
#include "xerces_handler.h"
#include <assert.h>


using namespace aka2;

#ifndef USE_XERCESC

xerces_parser::xerces_parser() {
  assert(!"Configuration does not include the use of Xerces-c");
}


#else

#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/StdInInputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <akaxiso/xerces/istream_inputsource.h>



xerces_parser::xerces_parser() : parser_(0), gattrs_(0) {}


xerces_parser::~xerces_parser() { 
  if (parser_)
    delete parser_;
}


document xerces_parser::parse_stdin(){
  xercesc::StdInInputSource is;
  return parse(is, "(stdin)");
}



document xerces_parser::parse(const char *buff){

  char *membuf_id = "(document on memory)";
  xercesc::MemBufInputSource membuf_is( reinterpret_cast<const XMLByte*>(buff),
			   strlen(buff),
			   membuf_id,
			   false);
  return parse(membuf_is, "(membuf)");
  
}


document xerces_parser::parse(const std::string& document){

  char *membuf_id = "(document on memory)";
  xercesc::MemBufInputSource membuf_is( reinterpret_cast<const XMLByte*>(document.c_str()),
			   document.length(),
			   membuf_id,
			   false);
  return parse(membuf_is, "(std::string)");
  
}


document xerces_parser::parse(std::istream &istm){

  IStreamInputSource istmsrc(istm);
  return parse(istmsrc, "(std::istream)");
  
}

document xerces_parser::parse_file(const std::string& filename){
  XMLCh * xch_filename = xercesc::XMLString::transcode(filename.c_str());
  xercesc::LocalFileInputSource file_is(xch_filename);
  delete [] xch_filename;
  return parse(file_is, filename);
}



document xerces_parser::parse(xercesc::InputSource &is, const std::string &source_name) {
  
  bool do_namespaces = true;
  bool do_schema = false;
  bool full_checking = false;
  xercesc::SAX2XMLReader::ValSchemes valschemes = xercesc::SAX2XMLReader::Val_Auto;

  if (!parser_)
    parser_ = xercesc::XMLReaderFactory::createXMLReader();

  xerces_handler *handler = new xerces_handler();
  handler->set_source_name(source_name);
  if (gattrs_ != 0)
    handler->set_gattrs(*gattrs_);

  xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader();
  parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpaces, do_namespaces);
  parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpacePrefixes, do_namespaces);

  parser->setFeature(xercesc::XMLUni::fgXercesSchema, do_schema);
  parser->setFeature(xercesc::XMLUni::fgXercesSchemaFullChecking, full_checking);

  if (valschemes == xercesc::SAX2XMLReader::Val_Auto)  {
      parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, true);
      parser->setFeature(xercesc::XMLUni::fgXercesDynamic, true);
  }
  if (valschemes == xercesc::SAX2XMLReader::Val_Never)  {
      parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, false);
  }
  if (valschemes == xercesc::SAX2XMLReader::Val_Always)  {
      parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, true);
      parser->setFeature(xercesc::XMLUni::fgXercesDynamic, false);
  }


  parser_->setContentHandler(handler);
  parser_->setErrorHandler(handler);
  
  parser_->parse(is);
  
  document doc = handler->get_document();
  delete handler;
  return doc;
}


void xerces_parser::set_gattrs(global_attributes &gattrs) {
  gattrs_ = &gattrs;
}


#endif
