/**********************************************************************
 *
 * maptools.cpp -- 
 * Copyright (C) 1999  The New Zealand Digital Library Project
 *
 * A component of the Greenstone digital library software
 * from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * 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 "maptools.h"



void stringmap::clear () {
  fromorder.erase (fromorder.begin(), fromorder.end());
  mapfrom.erase (mapfrom.begin(), mapfrom.end());
}

void stringmap::importmap (const text_tarray &maparray) {
  importmap(maparray, false);
}

void stringmap::importmap (const text_tarray &maparray, bool keepold) {
  if (!keepold) {
    clear ();
  }
  
  text_tarray::const_iterator here = maparray.begin();
  text_tarray::const_iterator end = maparray.end();
  text_t from;
  text_t to;

  while (here != end) {
    splitmapentry (*here, from, to);
    fromorder.push_back (from);
    mapfrom[from] = to;
    ++here;
  }
}

void stringmap::exportmap (text_tarray &maparray) const {
  maparray.erase (maparray.begin(), maparray.end());

  text_tarray::const_iterator here = fromorder.begin();
  text_tarray::const_iterator end = fromorder.end();
  text_tmap::const_iterator toptr;
  text_t tempmap;

  while (here != end) {
    toptr = mapfrom.find (*here);
    if (toptr != mapfrom.end()) {
      joinmapentry ((*toptr).first, (*toptr).second, tempmap);
      maparray.push_back (tempmap);
    }

    ++here;
  }
}

void stringmap::getfromarray (text_tarray &fromarray) const {
  fromarray = fromorder;
}

void stringmap::gettoarray (text_tarray &toarray) const {
  toarray.erase(toarray.begin(), toarray.end());

  text_tarray::const_iterator here = fromorder.begin();
  text_tarray::const_iterator end = fromorder.end();
  text_tmap::const_iterator toptr;

  while (here != end) {
    toptr = mapfrom.find (*here);
    if (toptr != mapfrom.end()) {
      toarray.push_back((*toptr).second);
    }
    ++here;
  }
}

bool stringmap::fromexists (const text_t &from) const {
  return (mapfrom.find (from) != mapfrom.end ());
}

bool stringmap::toexists (const text_t &to) const {
  text_tarray::const_iterator here = fromorder.begin();
  text_tarray::const_iterator end = fromorder.end();
  text_tmap::const_iterator toptr;

  while (here != end) {
    toptr = mapfrom.find (*here);
    if (toptr != mapfrom.end() && (*toptr).second == to) return true;
    ++here;
  }
  
  // it was not found
  return false;
}

bool stringmap::from2to (const text_t &from, text_t &to) const {
  text_tmap::const_iterator toptr = mapfrom.find (from);
  if (toptr == mapfrom.end()) {
    to.clear();
    return false;
  }

  to = (*toptr).second;
  return true;
}

bool stringmap::to2from (const text_t &to, text_t &from) const {
  text_tarray::const_iterator here = fromorder.begin();
  text_tarray::const_iterator end = fromorder.end();
  text_tmap::const_iterator toptr;

  while (here != end) {
    toptr = mapfrom.find (*here);
    if (toptr != mapfrom.end() && (*toptr).second == to) {
      from = (*toptr).first;
      return true;
    }
    ++here;
  }
  
  // it was not found
  from.clear();
  return false;
}



void splitmapentry (const text_t &mapentry, text_t &from, text_t &to) {
  from.clear ();
  to.clear();

  text_t::const_iterator here = mapentry.begin();
  text_t::const_iterator end = mapentry.end();

  // get the "from" part of the map
  while (here != end) {
    if (*here == '-') {
      ++here;
      if (here != end && *here == '>') {
	++here;
	break; // found "->"
      }

      // didn't find "->"
      from.push_back('-');

    } else {
      from.push_back(*here);
      ++here;
    }
  }

  // get the "to" part of the map
  while (here != end) {
    to.push_back(*here);
    ++here;
  }
}

void joinmapentry (const text_t &from, const text_t &to, text_t &mapentry) {
  mapentry = from;
  mapentry += "->";
  mapentry += to;
}
