/*
 *  mdc_box_side_magnet.h
 */


#ifndef __MDC_BOX_SIDE_MAGNET_H__
#define __MDC_BOX_SIDE_MAGNET_H__

#include "mdc_magnet.h"

BEGIN_MDC_DECLS

class Connector;
class CanvasItem;



class MYSQLCANVAS_PUBLIC_FUNC BoxSideMagnet : public Magnet
{
public:
  enum Side
  {
    Unknown, Top, Left, Right, Bottom
  };

  BoxSideMagnet(CanvasItem *owner);

  void set_compare_slot(const sigc::slot<bool, Connector*, Connector*, Side> &compare);

  virtual double constrain_angle(double angle) const;

  virtual Point get_position_for_connector(Connector *conn, const Point &srcpos) const;

  void set_connector_side(Connector *conn, Side side);

  virtual void remove_connector(mdc::Connector *conn);

  void reorder_connector_closer_to(Connector *conn, const Point &pos);

protected:
  friend struct CompareConnectors;
  class CompareConnectors
  {
    BoxSideMagnet *_magnet;
  public:
    CompareConnectors(BoxSideMagnet *magnet) : _magnet(magnet) {}

    bool operator()(Connector *a, Connector *b)
    {
      BoxSideMagnet::Side aside= _magnet->get_connector_side(a);
      BoxSideMagnet::Side bside= _magnet->get_connector_side(b);

      if ((int)aside < (int)bside)
        return true;
      if ((int)aside == (int)bside)
        return _magnet->_compare(a, b, aside);
      return false;
    }
  };


  std::map<Connector*, Side> _connector_info;
  sigc::slot<bool, Connector*, Connector*, Side> _compare;
  short _counts[5];

  Side get_connector_side(Connector *conn) const;
  double connector_position(Side side, Connector *conn, double length) const;

  void notify_connectors(Side side);

  void reorder_connectors();
};


END_MDC_DECLS

#endif

