#include "mcontainer.h"
#include "warning.h"
namespace blop
{
int mcontainer::ind(int i, int j) const
{
--i;
--j;
if(i < 0) i = 0;
if(i >= nx_) i = nx_-1;
if(j < 0) j = 0;
if(j >= ny_) j = ny_-1;
int result = i * ny_ + j;
return result;
}
mcontainer &mcontainer::direction(int i)
{
direction_ = i;
cd_first();
return *this;
}
void mcontainer::init_(int xdim, int ydim, int dir)
{
direction_ = dir;
nx_ = xdim;
ny_ = ydim;
current_ix_ = 1;
current_iy_ = 1;
}
mcontainer::mcontainer(int xdim, int ydim, int dir)
{
init_(xdim,ydim,dir);
}
mcontainer::mcontainer() : direction_(0), nx_(0), ny_(0), current_ix_(0), current_iy_(0)
{
}
void mcontainer::get_gridsize_(int n, int &xdim, int &ydim)
{
xdim = ydim = std::floor(std::sqrt((double)n));
while(xdim*ydim<n)
{
++ydim;
if(xdim*ydim>=n) break;
++xdim;
}
}
mcontainer &mcontainer::cd_first()
{
if (direction_&right_down) cd(1, ny_);
else if(direction_&right_up ) cd(1, 1 );
else if(direction_&left_down ) cd(nx_,ny_);
else if(direction_&left_up ) cd(nx_,1 );
else
{
warning::print("No direction is set (should not happen)","mcontainer::cd_first()");
cd(1, 1 );
}
return *this;
}
bool mcontainer::cd_next()
{
int cur_ix = current_ix_;
int cur_iy = current_iy_;
if( (direction_ & right_down) || (direction_ & right_up) )
{
if(++cur_ix > nx_)
{
cur_ix = 1;
if(direction_ & right_down)
{
if(--cur_iy <= 0)
{
if( (direction_&jump) == 0) return false;
cur_iy = ny_;
}
}
else
{
if(++cur_iy > ny_)
{
if( (direction_&jump) == 0) return false;
cur_iy = 1;
}
}
}
}
else if( (direction_ & left_down) || (direction_ & left_up) )
{
if(--cur_ix <= 0)
{
cur_ix = nx_;
if(direction_ & left_down)
{
if(--cur_iy <= 0)
{
if( (direction_&jump) == 0) return false;
cur_iy = ny_;
}
}
else
{
if(++cur_iy > ny_)
{
if( (direction_&jump) == 0) return false;
cur_iy = 1;
}
}
}
}
else if( (direction_ & down_left) || (direction_ & down_right) )
{
if(--cur_iy <= 0)
{
cur_iy = ny_;
if(direction_ & down_left)
{
if(--cur_ix <= 0)
{
if( (direction_&jump) == 0) return false;
cur_ix = nx_;
}
}
else
{
if(++cur_ix > nx_)
{
if( (direction_&jump) == 0) return false;
cur_ix = 1;
}
}
}
}
else if( (direction_ & up_left) || (direction_ & up_right) )
{
if(++cur_iy > ny_)
{
cur_iy = 1;
if(direction_ & up_left)
{
if(--cur_ix <= 0)
{
if( (direction_&jump) == 0) return false;
cur_ix = nx_;
}
}
else
{
if(++cur_ix > nx_)
{
if( (direction_&jump) == 0) return false;
cur_ix = 1;
}
}
}
}
else
{
warning::print("Bad direction","mcontainer::cd_next()");
return false;
}
cd(cur_ix, cur_iy);
return true;
}
mcontainer &mcontainer::cd(int i, int j)
{
current_ix_ = i;
current_iy_ = j;
cd_to_sub_(ind(i,j));
return *this;
}
mcontainer &mcontainer::cd(int i)
{
if(i<1 || nx_*ny_<i)
{
warning::print("Subcontainer number is out of range",
"mcontainer::cd(" & var(i) & ")");
return *this;
}
--i;
if (direction_&right_down ) cd(1+i%nx_, ny_-i/nx_);
else if(direction_&down_right ) cd(1+i/ny_, ny_-i%ny_);
else if(direction_&right_up ) cd(1+i%nx_, 1+i/nx_ );
else if(direction_&up_right ) cd(1+i/ny_, 1+i%ny_ );
else if(direction_&left_down ) cd(nx_-i%ny_, ny_-i/ny_);
else if(direction_&down_left ) cd(nx_-i/ny_, ny_-i%ny_);
else if(direction_&left_up ) cd(nx_-i%ny_, 1+i/ny_ );
else if(direction_&up_left ) cd(nx_-i/ny_, 1+i%ny_ );
else warning::print("Bad direction of mcontainer, this should not happen");
return *this;
}
}