#include "arrow.h"
#include "pad.h"
#include "frame.h"
#include "container.h"
#include "exc.H"

namespace blop
{
    arrow::arrow()
    {
	head_length_ = 4*MM;
	headangle(30);
    }

    arrow &arrow::headangle(double d)
    {
	head_angle_ = d;
	head_width_ = tan(head_angle_/2*3.1415/180)  * ! head_length_;
	return *this;
    }

    void arrow::prepare_for_draw()
    {
	if(print_me_ == 0) return;
	from_x_.register_me();
	from_y_.register_me();
	to_x_.register_me();
	to_y_.register_me();
	linewidth_.register_me();
	head_length_.register_me();
	head_width_.register_me();
    }

    void arrow::print(terminal *t)
    {
	if(print_me_ != 2) return;
	t->comment("arrow::print");
	t->set_linestyle(solid);
	t->set_linewidth(linewidth_.termspecific_id());
	t->set_color(color_);
	vector<terminal::id> xx,yy;
	xx.push_back(from_x_.termspecific_id());
	yy.push_back(from_y_.termspecific_id());
	xx.push_back(to_x_.termspecific_id());
	yy.push_back(to_y_.termspecific_id());
	t->draw_lines(xx,yy);

	int dx_id = t->lincombi(1,from_x_.termspecific_id(),
				-1,to_x_.termspecific_id());
	int dy_id = t->lincombi(1,from_y_.termspecific_id(),
				-1,to_y_.termspecific_id());

	int atan_id = t->atan(dx_id,dy_id);

	int sin_id = t->sin_dbl(atan_id);
	int cos_id = t->cos_dbl(atan_id);
	int min_sin_id = t->neg_dbl(sin_id);
	int min_cos_id = t->neg_dbl(cos_id);


	t->comment("hello");

	int xx1 = t->lincombi(terminal::double_id(0,sin_id), head_width_.termspecific_id(),
			      terminal::double_id(0,cos_id), head_length_.termspecific_id());
	int yy1 = t->lincombi(terminal::double_id(0,min_cos_id), head_width_.termspecific_id(),
			      terminal::double_id(0,sin_id), head_length_.termspecific_id());

	int xx2 = t->lincombi(terminal::double_id(0,min_sin_id), head_width_.termspecific_id(),
			      terminal::double_id(0,cos_id), head_length_.termspecific_id());
	int yy2 = t->lincombi(terminal::double_id(0,cos_id), head_width_.termspecific_id(),
			      terminal::double_id(0,sin_id), head_length_.termspecific_id());

	t->move_origin(to_x_.termspecific_id(), to_y_.termspecific_id());
	xx.clear();
	yy.clear();
	xx.push_back(xx1);
	yy.push_back(yy1);
	xx.push_back(0);
	yy.push_back(0);
	xx.push_back(xx2);
	yy.push_back(yy2);
	t->draw_lines(xx,yy);
	t->move_origin(0,0);
    }

    arrow& arrow::draw(container *parent,
		       const length &x1, const length &y1,
		       const length &x2, const length &y2)
    {
	if(parent == 0) err("arrow::draw ==> parent == 0");
	arrow *a = new arrow;
	a->from(x1,y1).to(x2,y2);
	a->autodel = true;
	parent->add(a);
	return *a;
    }

    arrow& arrow::fdraw(const length &x1, const length &y1,
			const length &x2, const length &y2)
    {
	return arrow::draw(frame::current(), x1, y1, x2, y2);
    }

    arrow& arrow::pdraw(const length &x1, const length &y1,
			const length &x2, const length &y2)
    {
	return arrow::draw(pad::current(), x1, y1, x2, y2);
    }

    arrow& arrow::cdraw(const length &x1, const length &y1,
			const length &x2, const length &y2)
    {
	return arrow::draw(canvas::current(), x1, y1, x2, y2);
    }



    
}