/***************************************************************************
 *   Copyright (C) 2005 by Andreas Pokorny                                 *
 *   andreas.pokorny@biozentrum.uni-wuerzburg.de                           *
 *                                                                         *
 *   This file is part of profdist and cbcanalyzer                         *
 *                                                                         *
 *   Both profdist and cbcanalyzer are free software; you can redistribute * 
 *   it and/or modify it under the terms of the GNU General Public License * 
 *   as published by the Free Software Foundation; either version 2 of the * 
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   Profdist and cbcanalyzer are distributed in the hope that it will be  *
 *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty   *
 *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "ct_parser.h"
#if 0
void parse_ct( std::string const& filename, std::list<file_sequence>& sequences )
{
  using namespace boost::spirit;
  typedef char char_t;
  typedef position_iterator<file_iterator<char_t> > iterator_t;
  file_iterator<char_t> file_handle( filename );

  if (!file_handle)
    throw std::runtime_error( ("Unable to open file " + filename) );

  
  iterator_t first( file_handle, file_handle.make_end(), filename );
  iterator_t end( file_handle.make_end(), file_handle.make_end(), filename );


  ct_grammar grammar( sequences ); 
#ifdef BOOST_SPIRIT_DEBUG
  BOOST_SPIRIT_DEBUG_NODE(grammar);
#endif 
  // Define your rule

  boost::spirit::parse_info<iterator_t> info = boost::spirit::parse( first, end, grammar);
  if( !info.full )
  {
    std::ostringstream out;
    out << "Parsing failed at line " << info.stop.get_position().line << " and column " 
      << info.stop.get_position().column << " in file " << info.stop.get_position().file 
      << '\n' << sequences.size() << " Sequences were found.\nError happened near:\n[...]" 
      << std::string( std::max( first, info.stop - 20 ), info.stop) << '\n';
    throw std::runtime_error( out.str() );
  }
}
#endif


#include <iostream>
#include <fstream>

void parse_ct( std::string const& filename, std::list<file_sequence>& sequences )
{
  using namespace boost::spirit;
  typedef position_iterator<const char*> iterator_t;
  
  std::ifstream in(filename.c_str());
  
  if(!in)
	throw std::runtime_error("Unable to open file " + filename);

  in.seekg(0, std::ios::end);
  size_t size = in.tellg();
  in.seekg(0, std::ios::beg);
  
  char* data = new char[size + 1];
  in.read(data, size);
  data[size] = 0;
  
  iterator_t first( data, data + size, filename );
  iterator_t end( data + size, data + size, filename );

  
  ct_grammar grammar( sequences ); 
#ifdef BOOST_SPIRIT_DEBUG
  BOOST_SPIRIT_DEBUG_NODE(grammar);
#endif 
  // Define your rule
  
  boost::spirit::parse_info<iterator_t> info = boost::spirit::parse( first, end, grammar);
  
  if( !info.full )
  {
    std::ostringstream out;
    out << "Parsing failed at line " << info.stop.get_position().line << " and column " 
      << info.stop.get_position().column << " in file " << info.stop.get_position().file 
      << '\n' << sequences.size() << " Sequences were found.\nError happened near:\n[...]" 
      << std::string( std::max( first, info.stop - 20 ), info.stop) << '\n';
    throw std::runtime_error( out.str() );
  }
  
  delete [] data;
}

void parse_ct(const char* data_begin,
              const char* data_end,
              std::list<file_sequence>& sequences)
{
  using namespace boost::spirit;
  typedef position_iterator<const char*> iterator_t;

  iterator_t first( data_begin, data_end );
  iterator_t end( data_end, data_end );


  ct_grammar grammar( sequences );
#ifdef BOOST_SPIRIT_DEBUG
  BOOST_SPIRIT_DEBUG_NODE(grammar);
#endif
  // Define your rule

  boost::spirit::parse_info<iterator_t> info = boost::spirit::parse( first, end, grammar);

  if( !info.full )
  {
    std::ostringstream out;
    out << "Parsing failed at line " << info.stop.get_position().line << " and column "
      << info.stop.get_position().column << " in file " << info.stop.get_position().file
      << '\n' << sequences.size() << " Sequences were found.\nError happened near:\n[...]"
      << std::string( std::max( first, info.stop - 20 ), info.stop) << '\n';
    throw std::runtime_error( out.str() );
  }
}

