/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2017 Frederik Heber. All rights reserved.
 *
 *
 *   This file is part of MoleCuilder.
 *
 *    MoleCuilder is 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.
 *
 *    MoleCuilder is 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 MoleCuilder.  If not, see .
 */
/*
 * Graph6Reader.cpp
 *
 *  Created on: Sep 26, 2017
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
//#include "CodePatterns/MemDebug.hpp"
#include "CodePatterns/Assert.hpp"
#include "CodePatterns/Log.hpp"
#include "Graph6Reader.hpp"
const int Graph6Reader::packet_size(5);
void Graph6Reader::operator()(std::istream &_graph_string)
{
  std::istream_iterator iter(_graph_string);
  scan_num_nodes(iter);
  scan_edges(iter);
}
void Graph6Reader::scan_num_nodes(std::istream_iterator &_it)
{
	//now we're one past the optional header
	//parse the number of nodes
	ASSERT(*_it >= 64, "The number of nodes is not properly encoded");
	if (*_it <126) {
		//6-bit encoding
		num_nodes = *_it-64;
	} else if (*_it++ == 126) {
		unsigned int packets = 3;
		if (*_it == 126) {
			//36-bit encoding
			packets++;
			_it++;
		}
		for(unsigned int i =0; i126."
			);
	}
	++_it;
}
void Graph6Reader::next_edge(std::istream_iterator &_it) {
  unsigned int bit = 0;
  int cur_byte = 0;
  while(!bit && !eos) {
    if (++row==column) {
      column+=1;
      row = 0;
    }
    if (column>=num_nodes) {
      eos = true;
      break;
    }
    if (bit_pos<0) {
      ASSERT((*_it >= 63) && (*_it <= 126),
          "The input contains a non-printable ascii char in the matrix encoding");
      cur_byte = (*_it) - 63;
      ++(_it);
      bit_pos = packet_size;
    }
    bit = cur_byte & (1<<(bit_pos--));
  }
}
void Graph6Reader::scan_edges(std::istream_iterator &_it)
{
  while(!eos) {
    next_edge(_it);
    if (!eos) {
      LOG(3, "DEBUG: Adding edge bit in (" << column << "," << row << ")");
      edges.push_back(std::make_pair(column,row));
    }
  }
}