#ifndef __BLOP_FRAME_H__
#define __BLOP_FRAME_H__
#include "axis.h"
#include "box.h"
#include "plottable.h"
#include "dgraph.h"
#include "fgraph.h"
#include "grob.h"
#include "legendbox.h"
#include "label.h"
#include "sym.h"
namespace blop
{
class canvas;
class epad;
class frame : public container
{
private:
#ifndef __MAKECINT__
class grob_plottable
{
public:
grob *grob_;
plottable *plottable_;
grob_plottable(grob *gg, plottable *pp) : grob_(gg), plottable_(pp) {}
};
vector<grob_plottable> ordering_;
#endif
private:
void draw_grid(terminal *);
friend class canvas;
static sym::position default_legend_xalign_, default_legend_yalign_;
sym::position legend_xalign_, legend_yalign_;
bool draw_frame_;
int draw_axes_;
static bool default_draw_frame_;
static int default_draw_axes_;
int grid_;
int grid_at_minor_tics_;
static int default_grid_, default_grid_at_minor_tics_;
color gridcolor_, minor_gridcolor_;
static color default_gridcolor_, default_minor_gridcolor_;
sym::linestyle gridstyle_, minor_gridstyle_;
static sym::linestyle default_gridstyle_, default_minor_gridstyle_;
length gridwidth_, minor_gridwidth_;
static length default_gridwidth_, default_minor_gridwidth_;
length gridcut_;
length linewidth_;
static length default_linewidth_, default_gridcut_;
bool foreground_;
static bool default_foreground_;
bool grid_foreground_;
static bool default_grid_foreground_;
color framecolor_;
static color default_framecolor_;
friend class pad;
bool owns_x1axis_,owns_x2axis_,owns_y1axis_,owns_y2axis_;
axis *x1axis_, *x2axis_, *y1axis_, *y2axis_;
std::vector<blop::plottable*> graphs_;
length parent_width_, parent_height_;
static frame *current_;
legendbox *legendbox_;
bool owns_legendbox_;
bool mirror_x1_, mirror_x2_, mirror_y1_, mirror_y2_;
void draw_axes(terminal *);
void draw_frame(terminal *);
length marginobjectsep_;
static length default_marginobjectsep_;
frame(const frame &);
void operator= (const frame &);
enum {Left=0, Right=1, Bottom=2, Top=3};
epad *marginboxes_[4];
bool owns_marginboxes_[4];
label *title_;
void print_graph_(plottable *, terminal *);
bool nodistort_;
public:
static frame &mknew(container &parent = pad::current());
legendbox *legend() {return legendbox_;}
frame &legendpos(sym::position xalign,sym::position yalign);
static void default_legendpos(sym::position xalign, sym::position yalign);
frame &legend(legendbox &l);
frame &own_legend();
static frame ¤t();
static frame *check_current() { return current_; }
bool parent(container *);
const container *parent() const { return grob::parent(); }
container *parent() { return grob::parent(); }
frame &add(plottable *);
frame &remove(plottable *);
void add(grob *g);
bool remove(grob *g);
void clear();
frame &clear_graphs(bool all = false);
frame &clear_graphs_and_autosettings(bool all = false);
frame &title(const var &t);
frame &marginobjectsep(const length &l) { marginobjectsep_ = l; return *this; }
const length &marginobjectsep() const { return marginobjectsep_; }
static void default_marginobjectsep(const length &l) {default_marginobjectsep_ = l;}
frame &lmarginbox(epad *);
frame &rmarginbox(epad *);
frame &bmarginbox(epad *);
frame &tmarginbox(epad *);
epad *lmarginbox() const;
epad *rmarginbox() const;
epad *bmarginbox() const;
epad *tmarginbox() const;
frame &lmarginobject(box *);
frame &rmarginobject(box *);
frame &bmarginobject(box *);
frame &tmarginobject(box *);
frame &mirror_x1(bool i) {mirror_x1_ = i; return *this;}
frame &mirror_x2(bool i) {mirror_x2_ = i; return *this;}
frame &mirror_y1(bool i) {mirror_y1_ = i; return *this;}
frame &mirror_y2(bool i) {mirror_y2_ = i; return *this;}
frame &draw_tics(bool f);
frame &cleft(const length &l) { container::cleft(l); return *this; }
frame &cright(const length &l) { container::cright(l); return *this; }
frame &cwidth(const length &l) { container::cwidth(l); return *this; }
frame &cbottom(const length &l) { container::cbottom(l); return *this; }
frame &ctop(const length &l) { container::ctop(l); return *this; }
frame &cheight(const length &l) { container::cheight(l); return *this; }
const length &cleft () const { return container::cleft (); }
const length &cright () const { return container::cright (); }
const length &cwidth () const { return container::cwidth (); }
const length &cbottom() const { return container::cbottom(); }
const length &ctop () const { return container::ctop (); }
const length &cheight() const { return container::cheight(); }
frame &lmargin(const length &l) { container::lmargin(l); return *this; }
frame &rmargin(const length &l) { container::rmargin(l); return *this; }
frame &bmargin(const length &l) { container::bmargin(l); return *this; }
frame &tmargin(const length &l) { container::tmargin(l); return *this; }
const length &lmargin() const { return container::lmargin(); }
const length &rmargin() const { return container::rmargin(); }
const length &bmargin() const { return container::bmargin(); }
const length &tmargin() const { return container::tmargin(); }
frame &left(const length &l) { box::left(l); return *this; }
frame &right(const length &l) { box::right(l); return *this; }
frame &width(const length &l) { box::width(l); return *this; }
frame &bottom(const length &l) { box::bottom(l); return *this; }
frame &top(const length &l) { box::top(l); return *this; }
frame &height(const length &l) { box::height(l); return *this; }
const length &left() const { return box::left(); }
const length &right() const { return box::right(); }
const length &width() const { return box::width(); }
const length &bottom() const { return box::bottom(); }
const length &top() const { return box::top(); }
const length &height() const { return box::height(); }
frame &loffset(const length &);
frame &roffset(const length &);
frame &toffset(const length &);
frame &boffset(const length &);
frame &offsets(const length &);
frame &caspect(double s);
frame &cxlock(sym::position a);
frame &cylock(sym::position a);
frame &nodistort(bool f);
bool nodistort() const { return nodistort_; }
frame();
virtual ~frame();
static void default_gridwidth(const length &l) { default_gridwidth_ = l; }
frame &gridwidth(const length &);
const length &gridwidth() const { return gridwidth_; }
static void default_minor_gridwidth(const length &l) { default_minor_gridwidth_ = l; }
frame &minor_gridwidth(const length &);
const length &minor_gridwidth() const { return minor_gridwidth_; }
static void default_gridcut(const length &l) { default_gridcut_ = l; }
frame &gridcut(const length &);
const length &gridcut() const;
static void default_linewidth(const length &l) { default_linewidth_ = l; }
frame &linewidth(const length &l);
const length &linewidth() const;
frame &ticlength (const length &l);
frame &minor_ticlength(const length &l);
frame &grid(int what);
frame &grid(bool i);
int grid() const { return grid_; }
frame &grid_at_minor_tics(int what);
int grid_at_minor_tics() const { return grid_at_minor_tics_; }
static void default_grid(int);
static void default_grid(bool);
static void default_grid_at_minor_tics(int);
static void default_grid_at_minor_tics(bool);
frame &gridcolor(const color &);
frame &gridcolor(double r, double g, double b) { return gridcolor(color(r,g,b)); }
const color &gridcolor() const { return gridcolor_; }
static void default_gridcolor(const color &c) { default_gridcolor_ = c; }
static void default_gridcolor(double r, double g, double b) { default_gridcolor(color(r,g,b)); }
frame &minor_gridcolor(const color &);
frame &minor_gridcolor(double r, double g, double b) { return minor_gridcolor(color(r,g,b)); }
const color &minor_gridcolor() const { return minor_gridcolor_; }
static void default_minor_gridcolor(const color &c) { default_minor_gridcolor_ = c; }
static void default_minor_gridcolor(double r, double g, double b) { default_minor_gridcolor(color(r,g,b)); }
frame &framecolor(const color &);
frame &framecolor(double r, double g, double b) { return framecolor(color(r,g,b)); }
const color &framecolor() const;
static void default_framecolor(const color &);
static void default_framecolor(double r, double g, double b) { default_framecolor(color(r,g,b)); }
frame& gridstyle(sym::linestyle);
sym::linestyle gridstyle() const { return gridstyle_; }
static void default_gridstyle(sym::linestyle s) { default_gridstyle_ = s; }
frame &minor_gridstyle(sym::linestyle);
sym::linestyle minor_gridstyle() const { return minor_gridstyle_; }
static void default_minor_gridstyle(sym::linestyle s) { default_minor_gridstyle_ = s; }
int ngraphs() const { return graphs_.size(); }
plottable *get_graph(int n);
dgraph *lastd();
fgraph *lastf();
plottable *last();
axis *x1axis() {return x1axis_;}
axis *x2axis() {return x2axis_;}
axis *y1axis() {return y1axis_;}
axis *y2axis() {return y2axis_;}
frame &x1axis(axis *a) { x1axis_ = a; owns_x1axis_ = false; return *this;}
frame &x2axis(axis *a) { x2axis_ = a; owns_x2axis_ = false; return *this;}
frame &y1axis(axis *a) { y1axis_ = a; owns_y1axis_ = false; return *this;}
frame &y2axis(axis *a) { y2axis_ = a; owns_y2axis_ = false; return *this;}
frame &foreground(bool);
bool foreground() const;
static void default_foreground(bool);
frame &grid_foreground(bool b) { grid_foreground_ = b; return *this; }
bool grid_foreground() const { return grid_foreground_; }
static void default_grid_foreground(bool b) { default_grid_foreground_ = b; }
frame &draw_frame(bool b) {draw_frame_ = b; return *this;}
bool draw_frame() const { return draw_frame_; }
static void default_draw_frame(bool b) { default_draw_frame_ = b; }
frame &draw_axes(int b) { draw_axes_ = b; return *this; }
frame &draw_axes(bool b)
{
if(b) draw_axes_ = axis::x1|axis::x2|axis::y1|axis::y2;
else draw_axes_ = 0;
return *this;
}
bool draw_axes() const { return draw_axes_; }
static void default_draw_axes(int b) { default_draw_axes_ = b; }
static void default_draw_axes(bool b)
{
if(b) default_draw_axes_ = axis::x1|axis::x2|axis::y1|axis::y2;
else default_draw_axes_ = 0;
}
bool modified() const;
void modified(bool f);
void cd_specific();
void print(terminal *);
void prepare_for_draw();
static std::vector<blop::frame*> &all();
static void remove_from_all(plottable *);
frame &layer(const var & l) { grob::layer(l); return *this; }
};
}
#ifdef __MAKECINT__
#pragma link off function blop::frame::prepare_for_draw();
#endif
#endif