#include "mpad.h"
#include <vector>
#include "warning.h"
namespace blop
{
bool mpad::modified() const
{
if(container::modified()) return true;
for(int i=1; i<=nx_; ++i)
{
for(int j=1; j<=ny_; ++j)
{
if(pads_[ind(i,j)]->modified()) return true;
}
}
return false;
}
void mpad::modified(bool f)
{
container::modified(f);
for(int i=1; i<=nx_; ++i)
{
for(int j=1; j<=ny_; ++j)
{
pads_[ind(i,j)]->modified(f);
}
}
}
int mpad::default_direction_ = mpad::right_down | mpad::jump;
length &mpad::default_gap_()
{
static length g = ZERO;
return g;
}
void mpad::default_gap(const length &l)
{
default_gap_() = l;
}
void mpad::default_direction(int i) { default_direction_ = i; }
mpad::~mpad()
{
for(int i=0; i<nx_*ny_; ++i) delete pads_[i];
delete [] pads_;
delete [] widths_;
delete [] heights_;
delete [] rwidths_;
delete [] rheights_;
}
mpad::mpad(int xdim, int ydim) : mcontainer(xdim,ydim,default_direction_)
{
name("mpad");
widths_ = new length[nx_];
heights_ = new length[ny_];
rwidths_ = new double[nx_];
rheights_ = new double[ny_];
for(int i=0; i<nx_; ++i) rwidths_[i] = 1;
for(int i=0; i<ny_; ++i) rheights_[i] = 1;
x_avail_ = !cwidth();
y_avail_ = !cheight();
gap_ = default_gap_();
pads_ = new pad*[nx_ * ny_];
left(ZERO);
right(!parent_cwidth_);
bottom(ZERO);
top(!parent_cheight_);
lmargin(ZERO);
rmargin(ZERO);
bmargin(ZERO);
tmargin(ZERO);
for(int i=1; i <= nx_; ++i)
{
for(int j=1; j<=ny_; ++j)
{
pads_[ind(i,j)] = new pad(0.0,1.0,0.0,1.0);
}
}
set_widths();
set_heights();
}
mpad::mpad(int n)
{
int xdim=0, ydim=0;
mcontainer::get_gridsize_(n,xdim,ydim);
mcontainer::init_(xdim,ydim,default_direction_);
name("mpad");
widths_ = new length[nx_];
heights_ = new length[ny_];
rwidths_ = new double[nx_];
rheights_ = new double[ny_];
for(int i=0; i<nx_; ++i) rwidths_[i] = 1;
for(int i=0; i<ny_; ++i) rheights_[i] = 1;
x_avail_ = !cwidth();
y_avail_ = !cheight();
gap_ = default_gap_();
pads_ = new pad*[nx_ * ny_];
left(ZERO);
right(!parent_cwidth_);
bottom(ZERO);
top(!parent_cheight_);
lmargin(ZERO);
rmargin(ZERO);
bmargin(ZERO);
tmargin(ZERO);
for(int i=1; i <= nx_; ++i)
{
for(int j=1; j<=ny_; ++j)
{
pads_[ind(i,j)] = new pad(0.0,1.0,0.0,1.0);
}
}
set_widths();
set_heights();
}
void mpad::set_widths()
{
x_avail_ = !cwidth() - (nx_-1)*!gap_;
double sum = 0;
for(int i=0; i<nx_; ++i)
{
if(rwidths_[i] > 0)
{
sum += rwidths_[i];
}
else
{
x_avail_ -= !widths_[i];
}
}
length l = ZERO;
for(int i=0; i<nx_; ++i)
{
if(rwidths_[i] > 0) widths_[i] = rwidths_[i]/sum * !x_avail_;
for(int j=0; j<ny_; ++j)
{
int ii = ind(i+1,j+1);
pads_[ii]->left(l);
pads_[ii]->right(l+!widths_[i]);
}
l += !widths_[i] + !gap_;
}
}
void mpad::set_heights()
{
y_avail_ = !cheight() - (ny_-1)*!gap_;
double sum = 0;
for(int i=0; i<ny_; ++i)
{
if(rheights_[i] > 0)
{
sum += rheights_[i];
}
else
{
y_avail_ -= !heights_[i];
}
}
length l = ZERO;
for(int i=0; i<ny_; ++i)
{
if(rheights_[i] > 0) heights_[i] = rheights_[i]/sum * !y_avail_;
for(int j=0; j<nx_; ++j)
{
int ii = ind(j+1,i+1);
pads_[ii]->bottom(l);
pads_[ii]->top(l+!heights_[i]);
}
l += !heights_[i] + !gap_;
}
}
mpad &mpad::width(int i, const length &l)
{
if(i <= 0 || nx_ < i)
{
warning::print(var("Index [") & i & var("] is out of range"),
"mpad::width");
return *this;
}
--i;
rwidths_[i] = -1;
widths_[i] = l;
set_widths();
return *this;
}
mpad &mpad::rwidth(int i, double d)
{
if(i <= 0 || nx_ < i)
{
warning::print(var("Index [") & i & var("] is out of range"),
"mpad::rwidth");
return *this;
}
--i;
rwidths_[i] = d;
widths_[i] = ZERO;
set_widths();
return *this;
}
mpad &mpad::height(int i, const length &l)
{
if(i <= 0 || ny_ < i)
{
warning::print(var("Index [") & i & var("] is out of range"),
"mpad::height");
return *this;
}
--i;
rheights_[i] = -1;
heights_[i] = l;
set_heights();
return *this;
}
mpad &mpad::rheight(int i, double d)
{
if(i <= 0 || ny_ < i)
{
warning::print(var("Index [") & i & var("] is out of range"),
"mpad::rheight");
return *this;
}
--i;
rheights_[i] = d;
heights_[i] = ZERO;
set_heights();
return *this;
}
mpad &mpad::gap(const length &l)
{
gap_ = l;
set_widths();
set_heights();
return *this;
}
mpad &mpad::draw_border(bool b)
{
for(int i=0; i<nx_*ny_; ++i) pads_[i]->draw_border(b);
return *this;
}
mpad &mpad::bordercolor(const color &c)
{
for(int i=0; i<nx_*ny_; ++i) pads_[i]->bordercolor(c);
return *this;
}
mpad &mpad::borderwidth(const length &l)
{
for(int i=0; i<nx_*ny_; ++i) pads_[i]->borderwidth(l);
return *this;
}
mpad &mpad::border_3D(bool b)
{
for(int i=0; i<nx_*ny_; ++i) pads_[i]->border_3D(b);
return *this;
}
mpad &mpad::fill(bool b)
{
for(int i=0; i<nx_*ny_; ++i) pads_[i]->fill(b);
return *this;
}
mpad &mpad::fillcolor(const color &c)
{
for(int i=0; i<nx_*ny_; ++i) pads_[i]->fillcolor(c);
return *this;
}
pad *mpad::operator() (int i,int j)
{
return pads_[ind(i,j)];
}
mpad &mpad::mknew(int i, int j)
{
mpad *p = new mpad(i,j);
p->autodel(true);
pad::current().add(p);
int ix, iy;
if( (p->direction_&right_up) || (p->direction_&right_down) || (p->direction_&down_right) || (p->direction_&up_right) ) ix = 1;
else ix = p->nx_;
if( (p->direction_&right_up) || (p->direction_&left_up) || (p->direction_&up_right) || (p->direction_&up_left) ) iy = 1;
else iy = p->ny_;
p->cd(ix,iy);
return *p;
}
mpad &mpad::mknew(int n)
{
int i=0,j=0;
mcontainer::get_gridsize_(n,i,j);
mpad *p = new mpad(i,j);
p->autodel(true);
pad::current().add(p);
int ix, iy;
if( (p->direction_&right_up) || (p->direction_&right_down) || (p->direction_&down_right) || (p->direction_&up_right) ) ix = 1;
else ix = p->nx_;
if( (p->direction_&right_up) || (p->direction_&left_up) || (p->direction_&up_right) || (p->direction_&up_left) ) iy = 1;
else iy = p->ny_;
p->cd(ix,iy);
return *p;
}
void mpad::prepare_for_draw()
{
container::prepare_for_draw();
for(int i=0; i<nx_*ny_; ++i) pads_[i]->prepare_for_draw();
}
void mpad::print(terminal *term)
{
if(print_me_ < 2) return;
term->set_linewidth(LW.termspecific_id());
term->set_color(black);
term->set_linestyle(sym::solid);
term->subpicture_begin(terminal::coord(cleft().termspecific_id(),
cbottom().termspecific_id()),
terminal::coord(cright().termspecific_id(),
ctop().termspecific_id()));
for(int i=0; i<nx_*ny_; ++i) pads_[i]->print(term);
for(unsigned int i=0; i<content_.size(); ++i)
{
content_[i]->print(term);
}
term->subpicture_end();
}
}