
static char *sccs_id= (sccs_id, "@(#)Connection.c	3.6 7/28/92");

//$Connection$
#include "Class.h"
#include "Connection.h"

//---- Connection ---------------------------------------------------------------

MetaImpl0(Connection);

Connection::Connection(View *v, Shape* s1, Shape* s2)
{
    SetContainer(v);
    startShape= s1;
    endShape= s2;
    if (s1 && s2) {
	startShape->AddObserver(this);
	endShape->AddObserver(this);
	UpdatePoints();
    }
}

Connection::~Connection()
{
    if (startShape)
	startShape->RemoveObserver(this);
    if (endShape)
	endShape->RemoveObserver(this);
    startShape= endShape= 0;
}

void Connection::DoObserve(int, int part, void*, Object *op)
{
    if (part == cPartSenderDied) {
        startShape= endShape= 0;
        delete this;                // delete myself too
    } else {
        Shape *s= (Shape*)op;
        if (startShape == s || endShape == s) {
            SetDeleted(s->GetDeleted());
            Invalidate();
            UpdatePoints();
            // SetSpan(Rectangle(startCenter, endCenter));
        }
    }
}

void Connection::AreaChanged()
{
    UpdatePoints();
    LineShape::AreaChanged();
}

void Connection::UpdatePoints()
{
    Point e= endShape->GetConnectionPoint(0),
	  s= startShape->GetConnectionPoint(0);
    startCenter= startShape->Chop(endShape->GetConnectionPoint(s));
    endCenter= endShape->Chop(startShape->GetConnectionPoint(e));
    Invalidate();

    // We cannot call Shape::Init because the update of ShowInfo
    // causes a redraw while the connected shapes are not yet updated
    gp1= GeoPos(this, startCenter);
    gp2= GeoPos(this, endCenter);

    bbox= NormRect(startCenter, endCenter);
    bbox1= GeoPos(this, bbox.origin);
    bbox2= GeoPos(this, bbox.origin+bbox.extent);

    Invalidate();
}

void Connection::Moveby(Point delta)
{
}

Rectangle Connection::GetTextRect()
{
    return Rectangle(bbox.Center(), 0).Expand(Point(50, 0));
}

void Connection::Highlight(HighlightState h)
{
    GrSetInk(ePatGrey50);
    LineShape::Highlight(h);
    GrSetInk(ePatBlack);
}

int Connection::PointOnHandle(Point)
{
    return -1;
}

bool Connection::ContainsPoint(Point p)
{
    if (LineShape::PointOnHandle(p) != -1)
	return FALSE;
    return LineShape::ContainsPoint(p);
}

ShapeStretcher *Connection::NewStretcher(class DrawView *, int)
{
    return (ShapeStretcher*) gNoChanges;
}

#ifdef ET25
OStream& Connection::PrintOn(OStream& s)
#else
ostream& Connection::PrintOn(ostream& s)
#endif
{
    LineShape::PrintOn(s);
    s << startShape SP << endShape SP << startCenter SP << endCenter SP;
    return s;
}

#ifdef ET25
IStream& Connection::ReadFrom(IStream& s)
#else
istream& Connection::ReadFrom(istream& s)
#endif
{
    LineShape::ReadFrom(s);
    s >> startShape >> endShape >> startCenter >> endCenter;
    // Init cannot be done because the view of start/end Shapes is not set yet
    // Init(startCenter, endCenter);
    return s;
}
