/**************************************************************************
 *
 * FIvfLevelInfo.cpp -- File functions for document levels
 * Copyright (C) 1999  Rodger McNab
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **************************************************************************/

#include "FIvfLevelInfo.h"


IvfLevelInfo::IvfLevelInfo () {
  Clear();
}

void IvfLevelInfo::Clear () {
  levelTag.erase (levelTag.begin(), levelTag.end());
  numEntries = 0;
  approxWeightsDiskPtr = 0;
  exactWeightsDiskPtr = 0;
  workInLevel = false;
}

bool IvfLevelInfo::Read (FILE *f) {
  workInLevel = false;
  return (ReadUCArray (f, levelTag) &&
	  ReadUL (f, numEntries) &&
	  ReadUL (f, approxWeightsDiskPtr) &&
	  ReadUL (f, exactWeightsDiskPtr));
}

bool IvfLevelInfo::Write (FILE *f) const {
  return (WriteUCArray (f, levelTag) &&
	  WriteUL (f, numEntries) &&
	  WriteUL (f, approxWeightsDiskPtr) &&
	  WriteUL (f, exactWeightsDiskPtr));
}

// stream output for debugging purposes
ostream &operator<<(ostream &s, const IvfLevelInfo &l) {
  s << "  Tag: \"" << l.levelTag << "\"\n"
    << "  numEntries: " << l.numEntries << "\n"
    << "  approxWeightsDiskPtr: " << l.approxWeightsDiskPtr << "\n"
    << "  exactWeightsDiskPtr: " << l.exactWeightsDiskPtr << "\n"
    << "  workInLevel: " << ((l.workInLevel) ? "true" : "false") << "\n\n";
  
  return s;
}



FIvfLevel::FIvfLevel () {
  Clear ();
}

void FIvfLevel::Clear () {
  docTag.erase (docTag.begin(), docTag.end());
  indexLevel.erase (indexLevel.begin(), indexLevel.end());
  levelInfo.erase (levelInfo.begin(), levelInfo.end());
}

bool FIvfLevel::Read (FILE *f) {
  if (!ReadUCArray (f, docTag) ||
      !ReadUCArray (f, indexLevel))
    return false;
  
  // read in the array size
  mg_u_long arrSize = 0;
  if (!ReadVarLenUL (f, arrSize)) return false;
  
  IvfLevelInfo thisLevel;
  while (arrSize > 0) {
    // read and insert the next level information
    if (!thisLevel.Read (f)) return false;
    levelInfo[thisLevel.levelTag] = thisLevel;
    
    --arrSize;
  }

  return true;
}

bool FIvfLevel::Write (FILE *f) const {
  if (!WriteUCArray (f, docTag) ||
      !WriteUCArray (f, indexLevel))
    return false;
  
  // write out the array size
  if (!WriteVarLenUL (f, levelInfo.size())) return false;

  // write out each level info
  IvfLevelInfoMap::const_iterator here = levelInfo.begin();
  IvfLevelInfoMap::const_iterator end = levelInfo.end();
  while (here != end) {
    if (!(*here).second.Write (f)) return false;
    
    ++here;
  }

  return true;
}

// stream output for debugging purposes
ostream &operator<<(ostream &s, const FIvfLevel &l) {
  s << "docTag: \"" << l.docTag << "\"\n"
    << "indexLevel: \"" << l.indexLevel << "\"\n";
  
  IvfLevelInfoMap::const_iterator here = l.levelInfo.begin ();
  IvfLevelInfoMap::const_iterator end = l.levelInfo.end ();
  while (here != end) {
    s << (*here).second;
    ++here;
  }
  
  return s;
}
