/*
$Id: TwoDimElementContainer.cc 1647 2006-10-20 08:39:13Z suzuki $
*/

#include "TwoDimElementContainer.hh"
////////////////////////////////////////////////////////
TwoDimElementContainer::
TwoDimElementContainer( std::vector<UInt4> Dimension ){
  header = new HeaderBase();
  Dim = Dimension;
  MakeStorage( Dim );
}
////////////////////////////////////////////////////////
TwoDimElementContainer::
TwoDimElementContainer(){
  header = new HeaderBase();
  Dim.clear();
  TwoDimStorage =
    new NeutronVector< NeutronVector< ElementContainer,HeaderBase >,
                       HeaderBase >();
}
////////////////////////////////////////////////////////
TwoDimElementContainer::
~TwoDimElementContainer(){
  delete header;
  delete TwoDimStorage;
}
/////////////////////////////////////////////////////////
TwoDimElementContainer::
TwoDimElementContainer( const TwoDimElementContainer &ob ){
  header = new HeaderBase();
  Dim = ob.Dim;
  MakeStorage( Dim );
  *TwoDimStorage = *( ob.TwoDimStorage );
}
/////////////////////////////////////////////////////////
TwoDimElementContainer
TwoDimElementContainer::
operator=( const TwoDimElementContainer ob ){
  delete header;
  delete TwoDimStorage;

  header = new HeaderBase();
  Dim = ob.Dim;
  MakeStorage( Dim );
  *TwoDimStorage = *( ob.TwoDimStorage );
  return *this;
}
/////////////////////////////////////////////////////////
void TwoDimElementContainer::
MakeStorage( std::vector<UInt4> Dimension ){
  UInt4 size = (UInt4)(Dimension.size());
  TwoDimStorage =
    new NeutronVector< NeutronVector< ElementContainer,HeaderBase >,
                       HeaderBase >();
  for( UInt4 i=0; i<size; i++ ){
    UInt4 SubSize = Dimension[ i ];
    NeutronVector< ElementContainer,HeaderBase > SubStorage;
    for( UInt4 j=0; j<SubSize; j++ ){
      ElementContainer e;
      SubStorage.Add( e );
    }
    TwoDimStorage->Add( SubStorage );
  }
}
/////////////////////////////////////////////////////////
ElementContainer *
TwoDimElementContainer::
operator()( UInt4 Xindex, UInt4 Yindex ){
  NeutronVector< ElementContainer,HeaderBase >* X =
    TwoDimStorage -> PutPointer( Xindex );
  if( X == NULL ){
    return NULL;
  }

  return X -> PutPointer( Yindex );
}
//////////////////////////////////////////////////////////
ElementContainer
TwoDimElementContainer::
Put( UInt4 Xindex, UInt4 Yindex ){
  NeutronVector< ElementContainer,HeaderBase >* X =
    TwoDimStorage -> PutPointer( Xindex );
  if( X == NULL ){
    ElementContainer e;
    return e;
  }

  ElementContainer *e = X -> PutPointer( Yindex );
  if( e != NULL ){ return *e; }

  ElementContainer TmpE;
  return TmpE;
}
//////////////////////////////////////////////////////////
void TwoDimElementContainer::
InputHeader( HeaderBase Header ){
  *header = Header;
}
//////////////////////////////////////////////////////////
std::vector<ElementContainer> TwoDimElementContainer::
PutPackedContainer(){
  std::vector<ElementContainer> cont;
  cont.clear();

  UInt4 Size = (UInt4)(Dim.size());
  for( UInt4 i=0; i<Size; i++ ){
    UInt4 SubSize = Dim[ i ];
    for( UInt4 j=0; j<SubSize; j++ ){
      cont.push_back( Put( i, j ) );
    }
  }

  return cont;
}
//////////////////////////////////////////////////////////
void TwoDimElementContainer::
InputPackedContainer( std::vector<ElementContainer> obj ){
  UInt4 Counter = 0;
  UInt4 Size = (UInt4)(Dim.size());
  for( UInt4 i=0; i<Size; i++ ){
    UInt4 SubSize = Dim[ i ];
    for( UInt4 j=0; j<SubSize; j++ ){
      ElementContainer *Target = TwoDimStorage -> PutPointer( i ) -> PutPointer( j );
      *Target = obj[ Counter++ ];
    }
  }
}
//////////////////////////////////////////////////////////
ElementContainerMatrix TwoDimElementContainer::
ConvertToMatrix(){
  ElementContainerMatrix Matrix;
  Matrix.InputHeader( PutHeader() );
  for( UInt4 i=0; i<Dim.size(); i++ ){
    UInt4 SubSize = Dim[ i ];
    ElementContainerArray array;
    for( UInt4 j=0; j<SubSize; j++ ){
      array.Add( Put( i, j ) );
    }
    Matrix.Add( array );
  }
  return Matrix;
}
//////////////////////////////////////////////////////////
