/*
$Id: HeaderBase.cc 2310 2011-10-07 03:44:47Z jisuzuki $
*/


#include "HeaderBase.hh"
////////////////////////////////////
HeaderBase::
HeaderBase()
{
  MakeMaps();
}
///////////////////////////////////
/*
HeaderBase::
HeaderBase( std::string DumpedString )
{
  MakeMaps();
  InputString( DumpedString );
}
*/
///////////////////////////////////
HeaderBase::
HeaderBase( const HeaderBase &ob )
{
  Int4Map         = new Map< Int4 > (*ob.Int4Map);
  DoubleMap       = new Map< Double > (*ob.DoubleMap);
  StringMap       = new Map< std::string > (*ob.StringMap);
  Int4VectorMap   = new Map< std::vector< Int4 >   > (*ob.Int4VectorMap);
  DoubleVectorMap = new Map< std::vector< Double > > (*ob.DoubleVectorMap);
  StringVectorMap = new Map< std::vector< std::string > > (*ob.StringVectorMap);

  _keymap = ob._keymap;

  _keyTypeName.resize(7);
  _keyTypeName[0] = "";
  _keyTypeName[1] = "Int4";
  _keyTypeName[2] = "Double";
  _keyTypeName[3] = "std::string";
  _keyTypeName[4] = "std::vector<Int4>";
  _keyTypeName[5] = "std::vector<Double>";
  _keyTypeName[6] = "std::vector<std::string>";

}
//////////////////////////////////////////
//HeaderBase &HeaderBase :: operator=( HeaderBase &ob )
HeaderBase HeaderBase :: operator=( const HeaderBase &ob )
{
  *Int4Map         = *ob.Int4Map;
  *DoubleMap       = *ob.DoubleMap;
  *StringMap       = *ob.StringMap;
  *Int4VectorMap   = *ob.Int4VectorMap;
  *DoubleVectorMap = *ob.DoubleVectorMap;
  *StringVectorMap = *ob.StringVectorMap;

  _keymap = ob._keymap;

  return *this;
}
//////////////////////////////////////////
HeaderBase::
~HeaderBase()
{
  //for( UInt4 i=0; i<Int4VectorMap -> Size(); i++){
  //  delete Int4VectorMap -> Put( i );
  //}
  //for( UInt4 i=0; i<DoubleVectorMap -> Size(); i++){
  //  delete DoubleVectorMap -> Put( i );
  //}
  //for( UInt4 i=0; i<StringVectorMap -> Size(); i++){
  //  delete StringVectorMap -> Put( i );
  //}

  delete Int4Map;
  delete DoubleMap;
  delete StringMap;
  delete Int4VectorMap;
  delete DoubleVectorMap;
  delete StringVectorMap;

}
////////////////////////////////////
void HeaderBase::
AddInt4List( std::string Key, PyObject *List )
{
  std::vector< Int4 > vec =
    __gCppToPython.ListToInt4Vector( List );

  if( vec.size() == 0 ){
    std::cout << "HeaderBase::AddInt4List( std::string Key, PyObject *List )" << std::endl;
    std::cout << "The Python List cannot be converted from Python-List to std::vector<Int4>."
              << "Please check each content of the List-object." << std::endl;
    return;
  }

  Add( Key, vec );
}
////////////////////////////////////
void HeaderBase::
AddDoubleList( std::string Key, PyObject *List )
{
  std::vector< Double > vec =
    __gCppToPython.ListToDoubleVector( List );

  if( vec.size() == 0 ){
    std::cout << "HeaderBase::AddDoubleList( std::string Key, PyObject *List )" << std::endl;
    std::cout << "The Python List cannot be converted from Python-List to std::vector<Double>."
              << "Please check each content of the List-object." << std::endl;
    return;
  }

  Add( Key, vec );
}
////////////////////////////////////
void HeaderBase::
AddStringList( std::string Key, PyObject *List )
{
  std::vector< std::string > vec =
    __gCppToPython.ListToStringVector( List );

  if( vec.size() == 0 ){
    std::cout << "HeaderBase::AddStringList( std::string Key, PyObject *List )" << std::endl;
    std::cout << "The Python List cannot be converted from Python-List to std::vector<std::string>."
              << "Please check each content of the List-object." << std::endl;
    return;
  }

  Add( Key, vec );
}
////////////////////////////////////
void HeaderBase::
Add( std::string Key, Int4 value )
{
  if( _keymap[Key] > 0 ){
    std::cout << "\"" << Key << "\"" << " has been registered for " << _keyTypeName[_keymap[Key]] << " in this HeaderBase," << std::endl;
    std::cout << "you should choose another key." << std::endl;
    return;
  }
  Int4Map  ->_Add(Key,value);
  _keymap[Key] = 1;
}
////////////////////////////////////
void HeaderBase::
Add( std::string Key, Double value )
{
  if( _keymap[Key] > 0 ){
    std::cout << "\"" << Key << "\"" << " has been registered for " << _keyTypeName[_keymap[Key]] << " in this HeaderBase," << std::endl;
    std::cout << "you should choose another key." << std::endl;
    return;
  }
  DoubleMap->_Add(Key,value);
  _keymap[Key] = 2;
}
////////////////////////////////////
void HeaderBase::
Add( std::string Key, std::string value )
{
  if( _keymap[Key] > 0 ){
    std::cout << "\"" << Key << "\"" << " has been registered for " << _keyTypeName[_keymap[Key]] << " in this HeaderBase," << std::endl;
    std::cout << "you should choose another key." << std::endl;
    return;
  }
  StringMap->_Add(Key,value);
  _keymap[Key] = 3;
}
////////////////////////////////////
void HeaderBase::
Add( std::string Key, std::vector<Int4> value )
{
  if( _keymap[Key] > 0 ){
    std::cout << "\"" << Key << "\"" << " has been registered for " << _keyTypeName[_keymap[Key]] << " in this HeaderBase," << std::endl;
    std::cout << "you should choose another key." << std::endl;
    return;
  }
  Int4VectorMap  ->_Add( Key, value );
  _keymap[Key] = 4;
}
////////////////////////////////////
void HeaderBase::
Add( std::string Key, std::vector<Double> value )
{
  if( _keymap[Key] > 0 ){
    std::cout << "\"" << Key << "\"" << " has been registered for " << _keyTypeName[_keymap[Key]] << " in this HeaderBase," << std::endl;
    std::cout << "you should choose another key." << std::endl;
    return;
  }
  DoubleVectorMap->_Add( Key, value );
  _keymap[Key] = 5;
}
////////////////////////////////////
void HeaderBase::
Add( std::string Key, std::vector<std::string> value )
{
  if( _keymap[Key] > 0 ){
    std::cout << "\"" << Key << "\"" << " has been registered for " << _keyTypeName[_keymap[Key]] << " in this HeaderBase," << std::endl;
    std::cout << "you should choose another key." << std::endl;
    return;
  }
  StringVectorMap->_Add( Key,value );
  _keymap[Key] = 6;
}
////////////////////////////////////
std::string HeaderBase::
DumpToString()
{

  std::string str;
  str.clear();
  char buf[1024];
  UInt4 size;

  //////// Dump start for Int4Map
  size = Int4Map->Size();
  std::snprintf( buf, sizeof(buf), "%d", size );
  str = str + ( std::string( buf ) + "#,#" );

  if( size == 0 ){
    str = str + "None" + "#,#";
    str = str + "None" + "#,#";
  }
  else{
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( Int4Map->PutKey(i) + "\\," );
    }
    str = str + ( Int4Map->PutKey(size-1) + "#,#" );

    for( UInt4 i=0; i<size-1; i++ ){
      std::snprintf( buf, sizeof(buf), "%d", Int4Map->Put(i) );
      str = str + ( std::string( buf ) + "," );
    }
    std::snprintf( buf, sizeof(buf), "%d", Int4Map->Put(size-1) );
    str = str + ( std::string( buf ) + "#,#" );
  } //////// Dump end for Int4Map

  //////// Dump start for DoubleMap
  size = DoubleMap->Size();
  std::snprintf( buf, sizeof(buf), "%d", size );
  str = str + ( std::string( buf ) + "#,#" );

  if( size == 0 ){
    str = str + "None" + "#,#";
    str = str + "None" + "#,#";
  }
  else{
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( DoubleMap->PutKey(i) + "\\," );
    }
    str = str + ( DoubleMap->PutKey(size-1) + "#,#" );

    for( UInt4 i=0; i<size-1; i++ ){
      std::snprintf( buf, sizeof(buf), "%.9f", DoubleMap->Put(i) );
      str = str + ( std::string( buf ) + "," );
    }
    std::snprintf( buf, sizeof(buf), "%.9f", DoubleMap->Put(size-1) );
    str = str + ( std::string( buf ) + "#,#" );
  } //////// Dump end for DoubleMap

  //////// Dump start for StringMap
  size = StringMap->Size();
  std::snprintf( buf, sizeof(buf), "%d", size );
  str = str + ( std::string( buf ) + "#,#" );

  if( size == 0 ){
    str = str + "None" + "#,#";
    str = str + "None" + "#,#";
  }
  else{
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( StringMap->PutKey(i) + "\\," );
    }
    str = str + ( StringMap->PutKey(size-1) + "#,#" );

    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( StringMap->Put(i) + "\\," );
    }
    str = str + ( StringMap->Put(size-1) + "#,#" );
  } //////// Dump end for StringMap

  //////// Dump start for Int4VectorMap
  size = Int4VectorMap->Size();
  std::snprintf( buf, sizeof(buf), "%d", size );
  str = str + ( std::string( buf ) + "#,#" );

  if( size != 0 ){
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( Int4VectorMap->PutKey(i) + "\\," );
    }
    str = str + ( Int4VectorMap->PutKey(size-1) + "#,#" );

    std::vector<Int4> TargetVec;
    for( UInt4 i=0; i<size; i++ ){
      TargetVec = Int4VectorMap -> Put( i );
      UInt4 VecSize = (UInt4)(TargetVec . size());
      std::snprintf( buf, sizeof(buf), "%d", VecSize );
      str = str + ( std::string( buf ) + "#,#" );
      if( VecSize == 0 ){
        str = str + "None" + "#,#";
      }
      else{
        for( UInt4 s=0; s<VecSize-1; s++){
          std::snprintf( buf, sizeof(buf), "%d", TargetVec[s] );
          str = str + ( std::string( buf ) + "," );
        }
        std::snprintf( buf, sizeof(buf), "%d", TargetVec[VecSize-1] );
        str = str + ( std::string( buf ) + "#,#" );
      }
    }
  } //////// Dump end for Int4VectorMap

  //////// Dump start for DoubleVectorMap
  size = DoubleVectorMap->Size();
  std::snprintf( buf, sizeof(buf), "%d", size );
  str = str + ( std::string( buf ) + "#,#" );

  if( size != 0 ){
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( DoubleVectorMap->PutKey(i) + "\\," );
    }
    str = str + ( DoubleVectorMap->PutKey(size-1) + "#,#" );

    std::vector<Double> TargetVec;
    for( UInt4 i=0; i<size; i++ ){
      TargetVec = DoubleVectorMap -> Put( i );
      UInt4 VecSize = (UInt4)(TargetVec . size());
      std::snprintf( buf, sizeof(buf), "%d", VecSize );
      str = str + ( std::string( buf ) + "#,#" );
      if( VecSize == 0 ){
        str = str + "None" + "#,#";
      }
      else{
        for( UInt4 s=0; s<VecSize-1; s++){
          std::snprintf( buf, sizeof(buf), "%.9f", TargetVec[s] );
          str = str + ( std::string( buf ) + "," );
        }
        std::snprintf( buf, sizeof(buf), "%.9f", TargetVec[VecSize-1] );
        str = str + ( std::string( buf ) + "#,#" );
      }
    }
  } //////// Dump end for DoubleVectorMap

  //////// Dump start for StringVectorMap
  size = StringVectorMap->Size();
  std::snprintf( buf, sizeof(buf), "%d", size );
  str = str + ( std::string( buf ) + "#,#" );

  if( size != 0 ){
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( StringVectorMap->PutKey(i) + "\\," );
    }
    str = str + ( StringVectorMap->PutKey(size-1) + "#,#" );

    std::vector<std::string> TargetVec;
    for( UInt4 i=0; i<size; i++ ){
      TargetVec = StringVectorMap -> Put( i );
      UInt4 VecSize = (UInt4)(TargetVec . size());
      std::snprintf( buf, sizeof(buf), "%d", VecSize );
      str = str + ( std::string( buf ) + "#,#" );
      if( VecSize == 0 ){
        str = str + "None" + "#,#";
      }
      else{
        for( UInt4 s=0; s<VecSize-1; s++){
          str = str + ( TargetVec[s] + "\\," );
        }
        str = str + ( TargetVec[VecSize-1] + "#,#" );
      }
    }
  } //////// Dump end for StringVectorMap
  return str;


  /*
  std::string str;
  str.clear();
  char buf[1024];
  UInt4 size;

  //////// Dump start for Int4Map
  size = Int4Map->Size();
  std::sprintf( buf, "%d", size );
  str = str + ( std::string( buf ) + "\n" );

  if( size == 0 ){
    str = str + "None" + "\n";
    str = str + "None" + "\n";
  }
  else{
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( Int4Map->PutKey(i) + "," );
    }
    str = str + ( Int4Map->PutKey(size-1) + "\n" );

    for( UInt4 i=0; i<size-1; i++ ){
      std::sprintf( buf, "%d", Int4Map->Put(i) );
      str = str + ( std::string( buf ) + "," );
    }
    std::sprintf( buf, "%d", Int4Map->Put(size-1) );
    str = str + ( std::string( buf ) + "\n" );
  } //////// Dump end for Int4Map

  //////// Dump start for DoubleMap
  size = DoubleMap->Size();
  std::sprintf( buf, "%d", size );
  str = str + ( std::string( buf ) + "\n" );

  if( size == 0 ){
    str = str + "None" + "\n";
    str = str + "None" + "\n";
  }
  else{
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( DoubleMap->PutKey(i) + "," );
    }
    str = str + ( DoubleMap->PutKey(size-1) + "\n" );

    for( UInt4 i=0; i<size-1; i++ ){
      std::sprintf( buf, "%.9f", DoubleMap->Put(i) );
      str = str + ( std::string( buf ) + "," );
    }
    std::sprintf( buf, "%.9f", DoubleMap->Put(size-1) );
    str = str + ( std::string( buf ) + "\n" );
  } //////// Dump end for DoubleMap

  //////// Dump start for StringMap
  size = StringMap->Size();
  std::sprintf( buf, "%d", size );
  str = str + ( std::string( buf ) + "\n" );

  if( size == 0 ){
    str = str + "None" + "\n";
    str = str + "None" + "\n";
  }
  else{
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( StringMap->PutKey(i) + "," );
    }
    str = str + ( StringMap->PutKey(size-1) + "\n" );

    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( StringMap->Put(i) + "," );
    }
    str = str + ( StringMap->Put(size-1) + "\n" );
  } //////// Dump end for StringMap

  //////// Dump start for Int4VectorMap
  size = Int4VectorMap->Size();
  std::sprintf( buf, "%d", size );
  str = str + ( std::string( buf ) + "\n" );

  if( size != 0 ){
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( Int4VectorMap->PutKey(i) + "," );
    }
    str = str + ( Int4VectorMap->PutKey(size-1) + "\n" );

    std::vector<Int4> TargetVec;
    for( UInt4 i=0; i<size; i++ ){
      TargetVec = Int4VectorMap -> Put( i );
      UInt4 VecSize = TargetVec . size();
      std::sprintf( buf, "%d", VecSize );
      str = str + ( std::string( buf ) + "\n" );
      if( VecSize == 0 ){
        str = str + "None" + "\n";
      }
      else{
        for( UInt4 s=0; s<VecSize-1; s++){
          std::sprintf( buf, "%d", TargetVec[s] );
          str = str + ( std::string( buf ) + "," );
        }
        std::sprintf( buf, "%d", TargetVec[VecSize-1] );
        str = str + ( std::string( buf ) + "\n" );
      }
    }
  } //////// Dump end for Int4VectorMap

  //////// Dump start for DoubleVectorMap
  size = DoubleVectorMap->Size();
  std::sprintf( buf, "%d", size );
  str = str + ( std::string( buf ) + "\n" );

  if( size != 0 ){
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( DoubleVectorMap->PutKey(i) + "," );
    }
    str = str + ( DoubleVectorMap->PutKey(size-1) + "\n" );

    std::vector<Double> TargetVec;
    for( UInt4 i=0; i<size; i++ ){
      TargetVec = DoubleVectorMap -> Put( i );
      UInt4 VecSize = TargetVec . size();
      std::sprintf( buf, "%d", VecSize );
      str = str + ( std::string( buf ) + "\n" );
      if( VecSize == 0 ){
        str = str + "None" + "\n";
      }
      else{
        for( UInt4 s=0; s<VecSize-1; s++){
          std::sprintf( buf, "%.9f", TargetVec[s] );
          str = str + ( std::string( buf ) + "," );
        }
        std::sprintf( buf, "%.9f", TargetVec[VecSize-1] );
        str = str + ( std::string( buf ) + "\n" );
      }
    }
  } //////// Dump end for DoubleVectorMap

  //////// Dump start for StringVectorMap
  size = StringVectorMap->Size();
  std::sprintf( buf, "%d", size );
  str = str + ( std::string( buf ) + "\n" );

  if( size != 0 ){
    for( UInt4 i=0; i<size-1; i++ ){
      str = str + ( StringVectorMap->PutKey(i) + "," );
    }
    str = str + ( StringVectorMap->PutKey(size-1) + "\n" );

    std::vector<std::string> TargetVec;
    for( UInt4 i=0; i<size; i++ ){
      TargetVec = StringVectorMap -> Put( i );
      UInt4 VecSize = TargetVec . size();
      std::sprintf( buf, "%d", VecSize );
      str = str + ( std::string( buf ) + "\n" );
      if( VecSize == 0 ){
        str = str + "None" + "\n";
      }
      else{
        for( UInt4 s=0; s<VecSize-1; s++){
          str = str + ( TargetVec[s] + "," );
        }
        str = str + ( TargetVec[VecSize-1] + "\n" );
      }
    }
  } //////// Dump end for StringVectorMap
  return str;
  */
}
////////////////////////////////////
void HeaderBase::
InputFile( std::string FileName )
{
  ReadWriteTextFile *r = new ReadWriteTextFile( FileName );
  r -> Read();
  std::vector<std::string> s = r -> Put();
  UInt4 size = (UInt4)(s.size());
  std::string ss;
  for( UInt4 i=0; i<size; i++ ){
    ss = ss + "\n" + s[i];
  }
  InputString( ss );
  delete r;
}
////////////////////////////////////
void HeaderBase::
InputString( std::string s )
{
  SplitString *split = new SplitString();
  std::vector<std::string> v = split -> PutStringArray( s, "#,#" );

  if (v.size()<12) return; //[inamura 200516]

  UInt4 Current = 0;

  // Receive Int4 start
  UInt4 size = atoi( v[Current++].c_str() );
  if( size == 0 ){
    Current = Current + 2;
  }
  else{
    std::string tmp=v[Current++];
    std::vector<std::string> key = split->PutStringArray( tmp, "\\," );
    std::vector<Int4>   IntVector = split->PutInt4Array( v[Current++],"," );
    if (key.size()!=size)
        key = split->PutStringArray( tmp, "," );
    for( UInt4 i=0; i<size; i++ ){
      Add( key[i], IntVector[i] );
    }
  }
  // Receive Int4 end


  // Receive Double start
  size = atoi( v[Current++].c_str() );
  if( size == 0 ){
    Current = Current + 2;
  }
  else{
    std::string tmp=v[Current++];
    std::vector<std::string> key = split->PutStringArray( tmp, "\\," );
    std::vector<Double> DoubleVector = split->PutDoubleArray( v[Current++],"," );
    if (key.size()!=size)
        key = split->PutStringArray( tmp, "," );
    for( UInt4 i=0; i<size; i++ ){
      Add( key[i], DoubleVector[i] );
    }
  }
  // Receive Double end


  // Receive String start
  size = atoi( v[Current++].c_str() );
  if( size == 0 ){
    Current = Current + 2;
  }
  else{
    std::string tmp=v[Current++];
    std::vector<std::string> key = split->PutStringArray( tmp, "\\," );
    if (key.size()!=size)
        key = split->PutStringArray( tmp, "," );
    std::vector<std::string> StringVector = split->PutStringArray( v[Current++],"\\," );
    if (StringVector.size()!=size){
        Current--;
        StringVector = split->PutStringArray( v[Current++],"," );
    }
    for( UInt4 i=0; i<size; i++ ){
      Add( key[i], StringVector[i] );
    }
  }
  // Receive String end


  // Receive Int4 std::vector start
  size = atoi( v[Current++].c_str() );
  if( size != 0 ){
    std::string tmp=v[Current++];
    std::vector<std::string> key = split->PutStringArray( tmp, "\\," );
    if (key.size()!=size)
      key = split->PutStringArray( tmp, "," );

    for( UInt4 i=0; i<size; i++ ){

      UInt4 VecSize = atoi( v[Current++].c_str() );
      if( VecSize == 0){
        Current++;
        //std::vector<Int4> *Vemp = new std::vector<Int4>;
        //Int4VectorMap -> Add( key[i], Vemp );
        std::vector<Int4> Vemp;
        Vemp.clear();
        Add( key[i], Vemp );
      }
      else{
        std::vector<Int4> Vec = split -> PutInt4Array( v[Current++].c_str(), "," );
        //std::vector<Int4> *V = new std::vector<Int4>( Vec.size() );
        //for( UInt4 t=0; t<Vec.size(); t++ ){
        //  ( *V )[t] = Vec[t];
        //}
        //Int4VectorMap -> Add( key[i], V );

        std::vector<Int4> V( Vec.size() );
        for( UInt4 t=0; t<Vec.size(); t++ ){
          V[t] = Vec[t];
        }
        Add( key[i], V );
      }
    }
  }
  // Receive Int4 std::vector end

  // Receive Double std::vector start
  size = atoi( v[Current++].c_str() );
  if( size != 0 ){
    std::string tmp=v[Current++];
    std::vector<std::string> key = split->PutStringArray( tmp, "\\," );
    if (key.size()!=size)
      key = split->PutStringArray( tmp, "," );

    for( UInt4 i=0; i<size; i++ ){

      UInt4 VecSize = atoi( v[Current++].c_str() );
      if( VecSize == 0){
        Current++;
        //std::vector<Double> *Vemp = new std::vector<Double>;
        //DoubleVectorMap -> Add( key[i], Vemp );
        std::vector<Double> Vemp;
        Vemp.clear();
        Add( key[i], Vemp );
      }
      else{
        std::vector<Double> Vec = split -> PutDoubleArray( v[Current++].c_str(), "," );
        //std::vector<Double> *V = new std::vector<Double>( Vec.size() );
        //for( UInt4 t=0; t<Vec.size(); t++ ){
        //  ( *V )[t] = Vec[t];
        //}
        //DoubleVectorMap -> Add( key[i], V );
        std::vector<Double> V( Vec.size() );
        for( UInt4 t=0; t<Vec.size(); t++ ){
          V[t] = Vec[t];
        }
        Add( key[i], V );
      }
    }
  }
  // Receive Double std::vector end

  // Receive String std::vector start
  size = atoi( v[Current++].c_str() );
  if( size != 0 ){
    std::string tmp=v[Current++];
    std::vector<std::string> key = split->PutStringArray( tmp, "\\," );
    if (key.size()!=size)
      key = split->PutStringArray( tmp, "," );

    for( UInt4 i=0; i<size; i++ ){

      UInt4 VecSize = atoi( v[Current++].c_str() );
      if( VecSize == 0){
        Current++;
        //std::vector<std::string> *Vemp = new std::vector<std::string>;
        //StringVectorMap -> Add( key[i], Vemp );

        std::vector<std::string> Vemp;
        Vemp.clear();
        Add( key[i], Vemp );
      }
      else{
        std::string tmp=v[Current++];
        std::vector<std::string> Vec = split -> PutStringArray( tmp.c_str(), "\\," );
        if (Vec.size()!=VecSize)
          Vec = split -> PutStringArray( tmp.c_str(), "," );
        //std::vector<std::string> *V = new std::vector<std::string>( Vec.size() );
        //for( UInt4 t=0; t<Vec.size(); t++ ){
        //  ( *V )[t] = Vec[t];
        //}
        //StringVectorMap -> Add( key[i], V );

        std::vector<std::string> V( Vec.size() );
        for( UInt4 t=0; t<Vec.size(); t++ ){
          V[t] = Vec[t];
        }
        Add( key[i], V );
      }
    }
  }
  delete split;
}
////////////////////////////////////
void HeaderBase::
MakeMaps() // private
{
  Int4Map         = new Map< Int4 >;
  DoubleMap       = new Map< Double >;
  StringMap       = new Map< std::string >;
  Int4VectorMap   = new Map< std::vector< Int4 >   >;
  DoubleVectorMap = new Map< std::vector< Double > >;
  StringVectorMap = new Map< std::vector< std::string > >;

  Int4Map         -> Clear();
  DoubleMap       -> Clear();
  StringMap       -> Clear();
  Int4VectorMap   -> Clear();
  DoubleVectorMap -> Clear();
  StringVectorMap -> Clear();

  _keyTypeName.resize(7);
  _keyTypeName[0] = "";
  _keyTypeName[1] = "Int4";
  _keyTypeName[2] = "Double";
  _keyTypeName[3] = "std::string";
  _keyTypeName[4] = "std::vector<Int4>";
  _keyTypeName[5] = "std::vector<Double>";
  _keyTypeName[6] = "std::vector<std::string>";

}
////////////////////////////////////
////////////////////////////////////
PyObject* HeaderBase::
PyDump()
{
  std::vector<std::string> vs;
  vs.clear();
  std::string ss;
  StringTools *st = new StringTools();


  /*****************************************************/
  vs.push_back( "***Int4Map***" );
  vs.push_back( "Index\tKey\tValue" );
  UInt4 s = Int4Map -> Size();
  for( UInt4 i=0; i<s; i++ ){
    vs.push_back( st->UInt4ToString(i) + "\t" + Int4Map -> PutKey( i )
         + "\t" + st->Int4ToString( Int4Map -> Put( i ) ) );
  }

  vs.push_back( "***DoubleMap***" );
  vs.push_back( "Index\tKey\tValue" );
  s = DoubleMap -> Size();
  for( UInt4 i=0; i<s; i++ ){
    vs.push_back(
                 st->UInt4ToString(i) + "\t" + DoubleMap -> PutKey( i )
                 +"\t" +  st->DoubleToString(DoubleMap -> Put( i ) ) );
  }

  vs.push_back( "***StringMap***" );
  vs.push_back( "Index\tKey\tValue" );
  s = StringMap -> Size();
  for( UInt4 i=0; i<s; i++ ){
    vs.push_back(
                 st->UInt4ToString(i) + "\t" + StringMap -> PutKey( i )
                 + "\t" +  StringMap -> Put( i ) );
  }

  UInt4 size;

  vs.push_back( "***Int4VectorMap***" );
  vs.push_back( "Index\tKey\tSize\tValue" );
  size = Int4VectorMap -> Size();
  UInt4 DumpSize = 22;

  for( UInt4 s=0; s<size; s++ ){
    ss = st->UInt4ToString(s) + "\t"
         + Int4VectorMap -> PutKey( s ) + "\t";

    std::vector<Int4> Vec = Int4VectorMap -> Put( s );
    UInt4 VecSize = (UInt4)(Vec . size());
    ss = ss + st->UInt4ToString(VecSize) + "\t";

    if( VecSize ==0 ){
      ss = ss + "[ None ]";
    }
    else if( VecSize <= DumpSize ){
      ss = ss + "[ ";
      for( UInt4 vs=0; vs<VecSize-1; vs++ ){
        ss = ss + st->UInt4ToString(Vec[vs]) + ",";
      }
      ss = ss + st->UInt4ToString(Vec[VecSize-1]) + " ]";
    }
    else{
      ss = ss + "[";
      for( UInt4 vs=0; vs<DumpSize-2; vs++ ){
        ss = ss + st->UInt4ToString(Vec[vs]) + ",";
      }
      ss = ss + st->UInt4ToString(Vec[DumpSize-2]) + " ......]";
    }
    vs.push_back( ss );
  }
  //vs.push_back( ss );

  vs.push_back( "***DoubleVectorMap***" );
  vs.push_back( "Index\tKey\tSize\tValue" );
  size = DoubleVectorMap -> Size();

  for( UInt4 s=0; s<size; s++ ){
    ss = st->UInt4ToString(s) + "\t"
         + DoubleVectorMap -> PutKey( s ) + "\t";

    std::vector<Double> Vec = DoubleVectorMap -> Put( s );
    UInt4 VecSize = (UInt4)(Vec . size());
    ss = ss + st->UInt4ToString(VecSize) + "\t";

    if( VecSize ==0 ){
      ss = ss + "[ None ]";
    }
    else if( VecSize <= DumpSize ){
      ss = ss + "[ ";
      for( UInt4 vs=0; vs<VecSize-1; vs++ ){
        ss = ss + st->DoubleToString(Vec[vs]) + ",";
      }
      ss = ss + st->DoubleToString(Vec[VecSize-1]) + " ]";
    }
    else{
      ss = ss + "[";
      for( UInt4 vs=0; vs<DumpSize-2; vs++ ){
        ss = ss +  st->DoubleToString(Vec[vs]) + ",";
      }
      ss = ss + st->DoubleToString(Vec[DumpSize-2]) + " ......]";
    }
    vs.push_back( ss );
  }
  //vs.push_back( ss );

  vs.push_back( "***StringVectorMap***" );
  vs.push_back( "Index\tKey\tSize\tValue" );
  size = StringVectorMap -> Size();

  for( UInt4 s=0; s<size; s++ ){
    ss = st->UInt4ToString(s) + "\t"
         + StringVectorMap -> PutKey( s ) + "\t";

    std::vector<std::string> Vec = StringVectorMap -> Put( s );
    UInt4 VecSize = (UInt4)(Vec . size());
    ss = ss + st->UInt4ToString(VecSize) + "\t";

    if( VecSize ==0 ){
      ss = ss + "[ None ]";
    }
    else if( VecSize <= DumpSize ){
      ss = ss + "[ ";
      for( UInt4 vs=0; vs<VecSize-1; vs++ ){
        ss = ss + "'" + Vec[vs] + "'" + ",";
      }
      ss = ss + "'" + Vec[VecSize-1] + "'" + " ]";
    }
    else{
      ss = ss + "[";
      for( UInt4 vs=0; vs<DumpSize-2; vs++ ){
        ss = ss + "'" + Vec[vs] + "'" + ",";
      }
      ss = ss + "'" + Vec[DumpSize-2] + "'" + " ......]";
    }
    vs.push_back( ss );
  }
  //vs.push_back(ss);
  /*****************************/


  CppToPython *cp = new CppToPython();
  PyObject *r = cp -> VectorStringToList( vs );
  delete cp;
  delete st;
  return r;
}
////////////////////////////////////
void HeaderBase::
Dump()
{
  std::cout << "***Int4Map***" << std::endl;
  std::cout << "Index\tKey\tValue"   << std::endl;
  UInt4 s = Int4Map -> Size();
  for( UInt4 i=0; i<s; i++ ){
    std::cout << i << "\t" << Int4Map -> PutKey( i )
              << "\t" <<  Int4Map -> Put( i ) << std::endl;
  }
  std::cout << std::endl;

  std::cout << "***DoubleMap***" << std::endl;
  std::cout << "Index\tKey\tValue"   << std::endl;
  s = DoubleMap -> Size();
  for( UInt4 i=0; i<s; i++ ){
    std::cout << i << "\t" << DoubleMap -> PutKey( i )
              << "\t" <<  DoubleMap -> Put( i ) << std::endl;
  }
  std::cout << std::endl;

  std::cout << "***StringMap***" << std::endl;
  std::cout << "Index\tKey\tValue"   << std::endl;
  s = StringMap -> Size();
  for( UInt4 i=0; i<s; i++ ){
    std::cout << i << "\t" << StringMap -> PutKey( i )
              << "\t" <<  StringMap -> Put( i ) << std::endl;
  }
  std::cout << std::endl;

  UInt4 size;

  std::cout << "***Int4VectorMap***" << std::endl;
  std::cout << "Index\tKey\tSize\tValue"   << std::endl;
  size = Int4VectorMap -> Size();
  UInt4 DumpSize = 22;

  for( UInt4 s=0; s<size; s++ ){
    std::cout << s << "\t"
              << Int4VectorMap -> PutKey( s ) << "\t";

    std::vector<Int4> Vec = Int4VectorMap -> Put( s );
    UInt4 VecSize = (UInt4)(Vec . size());
    std::cout << VecSize << "\t";

    if( VecSize ==0 ){
      std::cout << "[ None ]" << std::endl;
    }
    else if( VecSize <= DumpSize ){
      std::cout << "[ ";
      for( UInt4 vs=0; vs<VecSize-1; vs++ ){
        std::cout << Vec[vs] << ",";
      }
      std::cout << Vec[VecSize-1] << " ]" << std::endl;
    }
    else{
      std::cout << "[";
      for( UInt4 vs=0; vs<DumpSize-2; vs++ ){
        std::cout << Vec[vs] << ",";
      }
      std::cout << Vec[DumpSize-2] << " ......]" << std::endl;
    }
  }
  std::cout << std::endl;

  std::cout << "***DoubleVectorMap***" << std::endl;
  std::cout << "Index\tKey\tSize\tValue"   << std::endl;
  size = DoubleVectorMap -> Size();

  for( UInt4 s=0; s<size; s++ ){
    std::cout << s << "\t"
              << DoubleVectorMap -> PutKey( s ) << "\t";

    std::vector<Double> Vec = DoubleVectorMap -> Put( s );
    UInt4 VecSize = (UInt4)(Vec . size());
    std::cout << VecSize << "\t";

    if( VecSize ==0 ){
      std::cout << "[ None ]" << std::endl;
    }
    else if( VecSize <= DumpSize ){
      std::cout << "[ ";
      for( UInt4 vs=0; vs<VecSize-1; vs++ ){
        std::cout << Vec[vs] << ",";
      }
      std::cout << Vec[VecSize-1] << " ]" << std::endl;
    }
    else{
      std::cout << "[";
      for( UInt4 vs=0; vs<DumpSize-2; vs++ ){
        std::cout << Vec[vs] << ",";
      }
      std::cout << Vec[DumpSize-2] << " ......]" << std::endl;
    }
  }
  std::cout << std::endl;

  std::cout << "***StringVectorMap***" << std::endl;
  std::cout << "Index\tKey\tSize\tValue"   << std::endl;
  size = StringVectorMap -> Size();

  for( UInt4 s=0; s<size; s++ ){
    std::cout << s << "\t"
              << StringVectorMap -> PutKey( s ) << "\t";

    std::vector<std::string> Vec = StringVectorMap -> Put( s );
    UInt4 VecSize = (UInt4)(Vec . size());
    std::cout << VecSize << "\t";

    if( VecSize ==0 ){
      std::cout << "[ None ]" << std::endl;
    }
    else if( VecSize <= DumpSize ){
      std::cout << "[ ";
      for( UInt4 vs=0; vs<VecSize-1; vs++ ){
        std::cout << "'" << Vec[vs] << "'" << ",";
      }
      std::cout << "'" << Vec[VecSize-1] << "'" << " ]" << std::endl;
    }
    else{
      std::cout << "[";
      for( UInt4 vs=0; vs<DumpSize-2; vs++ ){
        std::cout << "'" << Vec[vs] << "'" << ",";
      }
      std::cout << "'" << Vec[DumpSize-2] << "'" << " ......]" << std::endl;
    }
  }
  std::cout << std::endl;
}
////////////////////////////////////
Int4 HeaderBase::
PutInt4( std::string Key )
{
  UInt4 N = _keymap[Key];
  if( N == 1 ){
    return Int4Map->Put( Key );
  }

  else if( N == 2 ){
    return ( (Int4)( DoubleMap->Find( Key ) ) );
  }

  else if( N == 3 ){
    std::string s = StringMap->Find( Key );
    Char *c = new Char[ s.size()+1 ];
    strcpy( c, s.c_str() );
    c[ s.size() ] = '\0';

    if( strncmp( c, "0", 1 ) != 0 && atoi( c ) == 0 ){
      std::cout << "HeaderBase::PutInt4(std::string)" << std::endl;
      std::cout << "Failed in converting the variable "
                << "from std::string to Int4." << std::endl;
      std::cout << "Anyway, returns zero." << std::endl;
    }

    Int4 r = atoi( c );
    delete [] c ;
    return r;
    //return atoi( c );
  }

  else{
    std::cout << "HeaderBase::PutInt4(std::string)"<< std::endl;
    std::cout << "\"" << Key << "\"" << " is not contained "
              << "in this storage. Returns zero." << std::endl;
    return 0;
  }

  return 0;
}
////////////////////////////////////
Double HeaderBase::
PutDouble( std::string Key )
{
  UInt4 N = _keymap[Key];
  if( N == 2 ){
    return DoubleMap->Find( Key );
  }

  else if( N == 1 ){
    return (Double)( Int4Map->Put( Key ) );
  }

  else if( N == 3 ){
    std::string s = StringMap->Find( Key );
    Char *c = new Char[ s.size()+1 ];
    strcpy( c, s.c_str() );
    c[ s.size() ] = '\0';

    if( strncmp( c, "0", 1 ) != 0 && atof( c ) == 0.0 ){
      std::cout << "HeaderBase::PutDouble(std::string)" << std::endl;
      std::cout << "Failed in converting the variable "
                << "from std::string to double." << std::endl;
      std::cout << "Anyway, returns zero." << std::endl;
    }

    Double r = atof( c );
    delete [] c ;
    return r;
    //return atof( c );
  }

  else{
    std::cout << "HeaderBase::PutDouble(std::string)"<< std::endl;
    std::cout << "\"" << Key << "\"" << " is not contained "
              << "in this storage. Returns zero." << std::endl;
    return 0.0;
  }

  return 0.0;
}
////////////////////////////////////
std::string HeaderBase::
PutString( std::string Key )
{
  UInt4 N = _keymap[Key];
  if( N != 3 ){
    if( N == 1 ){
      Char buf[256];
      std::snprintf( buf, sizeof(buf), "%d", Int4Map->Put( Key ) );
      return ( std::string( buf ) );
    }
    if( N == 2 ){
      Char buf[256];
      std::snprintf( buf, sizeof(buf), "%.9f", DoubleMap->Put( Key ) );
      return ( std::string( buf ) );
    }
    if( N == 0 ) return "";
  }
  return StringMap->Put( Key );
}
////////////////////////////////////
std::vector<Int4> HeaderBase::
PutInt4Vector( std::string Key )
{
  Int4 N = Int4VectorMap->_Check( Key );
  if( N == -1 ){
    std::cout << "HeaderBase::PutInt4Vector(std::string)" << std::endl;
    std::cout << "Cannot find your key ! [" << Key << "]" << std::endl;
    std::cout << "Returns an empty std::vector." << std::endl;

    std::vector<Int4> vec;
    vec.clear();
    return vec;
  }
  return Int4VectorMap->Put( N );
}
////////////////////////////////////
std::vector<Double> HeaderBase::
PutDoubleVector( std::string Key )
{
  Int4 N = DoubleVectorMap->_Check( Key );
  if( N == -1 ){
    std::cout << "HeaderBase::PutDoubleVector(std::string)" << std::endl;
    std::cout << "Cannot find your key ! [" << Key << "]" << std::endl;
    std::cout << "Returns an empty std::vector." << std::endl;

    std::vector<Double> vec;
    vec.clear();
    return vec;
  }
  return DoubleVectorMap->Put( N );
}
////////////////////////////////////
std::vector<std::string> HeaderBase::
PutStringVector( std::string Key )
{
  Int4 N = StringVectorMap->_Check( Key );
  if( N == -1 ){
    std::cout << "HeaderBase::PutStringVector(std::string)" << std::endl;
    std::cout << "Cannot find your key ! [" << Key << "]" << std::endl;
    std::cout << "Returns an empty std::vector." << std::endl;

    std::vector<std::string> vec;
    vec.clear();
    return vec;
  }
  return StringVectorMap->Put( N );
}
////////////////////////////////////
void HeaderBase::
Search( std::string Key )
{
  switch(_keymap[Key]) {
  case 1:
    std::cout << Key << " is Int4." << std::endl;
    break;
  case 2:
    std::cout << Key << " is Double." << std::endl;
    break;
  case 3:
    std::cout << Key << " is String." << std::endl;
    break;
  case 4:
    std::cout << Key << " is Int4Vector." << std::endl;
    break;
  case 5:
    std::cout << Key << " is DoubleVector." << std::endl;
    break;
  case 6:
    std::cout << Key << " is StringVector." << std::endl;
    break;
  default:
    std::cout << Key << " is not found in this storage." << std::endl;
  }
}
////////////////////////////////////
void HeaderBase::
Erase( std::string Key )
{
  switch(_keymap[Key]) {
  case 1:
    Int4Map -> Remove( Key );
    break;
  case 2:
    DoubleMap -> Remove( Key );
    break;
  case 3:
    StringMap -> Remove( Key );
    break;
  case 4:
    Int4VectorMap -> Remove( Key );
    break;
  case 5:
    DoubleVectorMap -> Remove( Key );
    break;
  case 6:
    StringVectorMap -> Remove( Key );
    break;
  default:
    std::cout << "\"" << Key << "\""
              << " cannot be found in the Maps," << std::endl;
    std::cout << "you should choose correct keys." << std::endl;
  }
  _keymap.erase(Key);
}
////////////////////////////////////
void HeaderBase::
clear()
{
  Int4Map   -> Clear();
  DoubleMap -> Clear();
  StringMap -> Clear();

  // Delete dynamically objects.
  // These functionality are not provided in "Map".

  //UInt4 size = Int4VectorMap -> Size();
  //for( UInt4 s=0; s<size; s++ ) delete Int4VectorMap->Put( s );
  //size = DoubleVectorMap -> Size();
  //for( UInt4 s=0; s<size; s++ ) delete DoubleVectorMap->Put( s );
  //size = StringVectorMap -> Size();
  //for( UInt4 s=0; s<size; s++ ) delete StringVectorMap->Put( s );

  Int4VectorMap   -> Clear();
  DoubleVectorMap -> Clear();
  StringVectorMap -> Clear();
}
