text: #include "Circles.h"
  
  void CircleDoc::Update(const Rect& r)
  {
  	bound.Clear();
  	for(int i = 0; i < data.GetCount(); i++)
  		bound.Union(data[i].GetRect());
  	for(int i = 0; i < view.GetCount(); i++)
  		view[i].UpdateView(r);
  }
  
  void CircleDoc::UpdateFull()
  {
  	Rect r(-INT_MAX, -INT_MAX, INT_MAX, INT_MAX);
  	Update(r);
  }
  
  void CircleDoc::AddCircle(Point p, int radius)
  {
  	redo.Clear();
  	CircleUndo& u = undo.Add();
  	u.insert = false;
  	u.index = data.GetCount();
  	CircleShape& c = data.Add();
  	c.point = p;
  	c.radius = radius;
  	Update(c.GetRect());
  }
  
  void CircleDoc::RemoveCircle(int i)
  {
  	redo.Clear();
  	CircleUndo& u = undo.Add();
  	u.insert = true;
  	u.index = i;
  	u.shape = data[i];
  	data.Remove(i);
  	Update(u.shape.GetRect());
  }
  
  void CircleDoc::UndoRedo(Array<CircleUndo>& src, Array<CircleUndo>& dst)
  {
  	if(src.GetCount() == 0)
  		return;
  	CircleUndo& u = src.Top();
  	CircleUndo& r = dst.Add();
  	r.index = u.index;
  	Rect ur;
  	if(u.insert) {
  		r.insert = false;
  		data.Insert(u.index, u.shape);
  		ur = u.shape.GetRect();
  	}
  	else {
  		r.insert = true;
  		r.shape = data[u.index];
  		data.Remove(u.index);
  		ur = r.shape.GetRect();
  	}
  	src.Drop();
  	Update(ur);
  }
  
  void CircleDoc::NewView()
  {
  	view.Add(new CircleView(*this)).OpenMain();
  }
  
  void CircleDoc::RemoveView(CircleView *v)
  {
  	view.Remove(view.GetIndex(*v));
  	if(view.GetCount() == 0)
  		delete this;
  }
  
  void CircleDoc::Clear()
  {
  	data.Clear();
  	undo.Clear();
  	redo.Clear();
  	UpdateFull();
  	AddCircle(Point(100, 20), 10 );
  	AddCircle(Point(20, 120), 10 );
  	AddCircle(Point(160, 120), 10 );
  }
  
  bool   CircleDoc::LoadText(const char *text)
  {
  	CParser p(text);
  	Clear();
  	try {
  		p.PassId("circle");
  		CircleShape& c = data.Add();
  		c.point.x = p.ReadNumber();
  		p.PassChar(',');
  		c.point.y = p.ReadNumber();
  		p.PassChar(',');
  		c.radius = p.ReadNumber();
  		p.PassChar(';');
  	}
  	catch(...) {
  		Clear();
  		return false;
  	}
  	return true;
  }
  
  String CircleDoc::SaveText() const
  {
  	String r;
  	for(int i = 0; i < data.GetCount(); i++) {
  		const CircleShape& c = data[i];
  		r << "circle " << c.point.x << ", " << c.point.y << ", " << c.radius << ";";
  	}
  	return r;
  }
  
  void   CircleDoc::Serialize(Stream& s)
  {
  	int version = 0;
  	s / version;
  	for(int i = 0; i < data.GetCount(); i++) {
  		CircleShape& c = data[i];
  		s % c.point.x % c.point.y % c.radius;
  	}
  }
  
  bool   CircleDoc::LoadBinary(const String& data)
  {
  	StringStream ss(data);
  	if(Load(*this, ss))
  		return true;
  	Clear();
  	return false;
  }
  
  String CircleDoc::SaveBinary() const
  {
  	StringStream ss;
  	Store(*this, ss);
  	return ss.GetResult();
  }
  