/*
$Id: Map.cc 2247 2011-04-27 05:20:41Z jisuzuki $
*/


#include "Map.hh"
#ifndef MAP_CC
#define MAP_CC
///////////////////////////////////////////////////
template< class T >
Map< T >::
Map()
{
  KeyVector   = new std::vector< std::string >;
  ValueVector = new std::vector< T >;

  KeyVector   -> clear();
  ValueVector -> clear();
}
///////////////////////////////////////////////////
template< class T >
Map< T >::
~Map()
{
  delete KeyVector;
  delete ValueVector;
}
///////////////////////////////////////////////////
template< class T >
Map< T >::
Map(const Map<T> &ob)
{
  KeyVector   = new std::vector< std::string > (*ob.KeyVector);
  ValueVector = new std::vector< T > (*ob.ValueVector);
}
///////////////////////////////////////////////////
template< class T >
Map< T > Map< T >::
operator=(const Map<T> &ob)
{
  *KeyVector   = *ob.KeyVector;
  *ValueVector = *ob.ValueVector;

  return *this;
}
///////////////////////////////////////////////////
template< class T >
UInt4 Map< T >::
Size() const
{
  return (UInt4)(KeyVector -> size());
}
///////////////////////////////////////////////////
template< class T >
void Map< T >::
Add( std::string key, T value )
{
  Int4 s = _Check( key );

  if (s > -1) {

      std::cout << "Map::Add( std::string, T )" << std::endl;
      std::cout << "Your new key has been registered in this storage. ( " << key << ")" << std::endl;
      std::cout << "Please choose another key." << std::endl;
      return;
  }

  _Add(key, value);
}
///////////////////////////////////////////////////
template< class T >
void Map< T >::
_Add( std::string key, T value )
{
    KeyVector   -> push_back( key );
    ValueVector -> push_back( value );
}
///////////////////////////////////////////////////
template< class T >
T Map< T >::
Find( std::string key )
{
  Int4 s = _Check( key );

  if (s > -1) return (*ValueVector)[s];

  std::cout << "Map::Find(std::string)" << std::endl;
  std::cout << "Because the key of " << key
       << " cannot be found in this storage," << std::endl;
  std::cout << "a value of zero is returned." << std::endl;
  //return ( T ) 0;
  T ret;
  return ret;
}
///////////////////////////////////////////////////
template< class T >
void Map< T >::
Clear()
{
  KeyVector   -> clear();
  ValueVector -> clear();
}
///////////////////////////////////////////////////
template< class T >
UInt4 Map< T >::
PutIndexNumber( std::string key )
{
  Int4 s = _Check( key );

  if (s > -1) return s;

  std::cout << "Map::PutIndexNumber(std::string)" << std::endl;
  std::cout << "Because the key of " << key
       << " cannot be found in this storage," << std::endl;
  std::cout << "anyway a value of zero is returned." << std::endl;
  return 0;

}
///////////////////////////////////////////////////
template< class T >
void Map< T >::
Remove( UInt4 IndexNumber )
{
  KeyVector   -> erase( KeyVector   -> begin()  + IndexNumber );
  ValueVector -> erase( ValueVector -> begin()  + IndexNumber );
}
///////////////////////////////////////////////////
template< class T >
void Map< T >::
Remove( std::string key )
{
  Remove( PutIndexNumber( key ) );
}
///////////////////////////////////////////////////
template< class T >
void Map< T >::
Dump()
{
  UInt4 size = (UInt4)(KeyVector -> size());

  std::cout << "Index\tKey\tValue" << std::endl;
  for( UInt4 s=0; s<size; s++ ){
    std::cout << s              << "\t"
              << *( KeyVector   -> begin() + s )   << std::endl;
  }

  /*
  UInt4 size = KeyVector -> size();

  std::cout << "Index\tKey\tValue" << std::endl;
  for( UInt4 s=0; s<size; s++ ){
    std::cout << s              << "\t"
              << *( KeyVector   -> begin() + s )   << "\t"
              << *( ValueVector -> begin() + s )   << std::endl;
  }
  */
}
///////////////////////////////////////////////////
template< class T >
UInt4 Map< T >::
Check( std::string Key )
{
  return (_Check( Key ) > -1) ? 1 : 0;
}
///////////////////////////////////////////////////
template< class T >
Int4 Map< T >::
_Check( std::string Key ) const
{
  UInt4 S = Size();

  for( UInt4 s=0; s<S; s++ ){
    if( ( *KeyVector )[s] == Key )
      return s;
  }
  return -1;
}
///////////////////////////////////////////////////
template< class T >
const T& Map< T >::
operator[]( const std::string &Key ) const
{
  Int4 i = _Check(Key);
  return (*ValueVector)[i];
}
///////////////////////////////////////////////////
template< class T >
T& Map< T >::
operator[]( const std::string &Key )
{
  Int4 i = _Check(Key);
  if (i==-1) {
    i = (Int4)(ValueVector->size());
    T t;
    KeyVector->push_back(Key);
    ValueVector->push_back(t);
  }
  return (*ValueVector)[i];
}

////////////////////////////////////
template< class T >
template <class Archive>
void Map<T>::
serialize(Archive &ar, const unsigned int ver) {
  ar & boost::serialization::
    make_nvp("KeyVector",   *KeyVector);
  ar & boost::serialization::
    make_nvp("ValueVector", *ValueVector);
}
#endif
