/*
  Copyright 2008 Intel Corporation
 
  Use, modification and distribution are subject to the Boost Software License,
  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
*/
#ifndef BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP
#define BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP
namespace boost { namespace polygon{
template <typename concept_type, typename geometry_type>
class iterator_geometry_to_set {};

template <typename rectangle_type>
class iterator_geometry_to_set<rectangle_concept, rectangle_type> {
public:
  typedef typename rectangle_traits<rectangle_type>::coordinate_type coordinate_type;
  typedef std::forward_iterator_tag iterator_category;
  typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
  typedef std::ptrdiff_t difference_type;
  typedef const value_type* pointer; //immutable
  typedef const value_type& reference; //immutable
private:
  rectangle_data<coordinate_type> rectangle_;
  mutable value_type vertex_;
  unsigned int corner_;
  orientation_2d orient_;
  bool is_hole_;
public:
  iterator_geometry_to_set() : rectangle_(), vertex_(), corner_(4), orient_(), is_hole_() {}
  iterator_geometry_to_set(const rectangle_type& rectangle, direction_1d dir, 
                           orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) : 
    rectangle_(), vertex_(), corner_(0), orient_(orient), is_hole_(is_hole) {
    assign(rectangle_, rectangle);
    if(dir == HIGH) corner_ = 4;
  }
  inline iterator_geometry_to_set& operator++() {
    ++corner_;
    return *this;
  }
  inline const iterator_geometry_to_set operator++(int) {
    iterator_geometry_to_set tmp(*this);
    ++(*this);
    return tmp;
  }
  inline bool operator==(const iterator_geometry_to_set& that) const {
    return corner_ == that.corner_;
  }
  inline bool operator!=(const iterator_geometry_to_set& that) const {
    return !(*this == that);
  }
  inline reference operator*() const {
    if(corner_ == 0) {
      vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), LOW);
      vertex_.second.first = get(get(rectangle_, orient_), LOW);
      vertex_.second.second = 1;
      if(is_hole_) vertex_.second.second *= -1;
    } else if(corner_ == 1) {
      vertex_.second.first = get(get(rectangle_, orient_), HIGH);
      vertex_.second.second = -1;
      if(is_hole_) vertex_.second.second *= -1;
    } else if(corner_ == 2) {
      vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), HIGH);
      vertex_.second.first = get(get(rectangle_, orient_), LOW);
    } else {
      vertex_.second.first = get(get(rectangle_, orient_), HIGH);
      vertex_.second.second = 1;
      if(is_hole_) vertex_.second.second *= -1;
    }
    return vertex_; 
  }
};

template <typename polygon_type>
class iterator_geometry_to_set<polygon_90_concept, polygon_type> {
public:
  typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
  typedef std::forward_iterator_tag iterator_category;
  typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
  typedef std::ptrdiff_t difference_type;
  typedef const value_type* pointer; //immutable
  typedef const value_type& reference; //immutable
  typedef typename polygon_traits<polygon_type>::iterator_type coord_iterator_type;
private:
  value_type vertex_;
  typename polygon_traits<polygon_type>::iterator_type itrb, itre;
  bool last_vertex_;
  bool is_hole_;
  int multiplier_;
  point_data<coordinate_type> first_pt, second_pt, pts[3];
  bool use_wrap;
  orientation_2d orient_;
  int polygon_index;
public:
  iterator_geometry_to_set() : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {}
  iterator_geometry_to_set(const polygon_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false, bool winding_override = false, direction_1d w = CLOCKWISE) : 
    vertex_(), itrb(), itre(), last_vertex_(), 
    is_hole_(is_hole), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), 
    orient_(orient), polygon_index(0) {
    itrb = begin_points(polygon);
    itre = end_points(polygon);
    use_wrap = false;
    if(itrb == itre || dir == HIGH || size(polygon) < 4) {
      polygon_index = -1;
    } else {
      direction_1d wdir = w;
      if(!winding_override)
        wdir = winding(polygon);
      multiplier_ = wdir == LOW ? -1 : 1;
      if(is_hole_) multiplier_ *= -1;
      first_pt = pts[0] = *itrb;
      ++itrb;
      second_pt = pts[1] = *itrb;
      ++itrb;
      pts[2] = *itrb;
      evaluate_();
    }
  }
  iterator_geometry_to_set(const iterator_geometry_to_set& that) : 
    vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(),
    second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {
    vertex_ = that.vertex_;
    itrb = that.itrb;
    itre = that.itre;
    last_vertex_ = that.last_vertex_;
    is_hole_ = that.is_hole_;
    multiplier_ = that.multiplier_;
    first_pt = that.first_pt;
    second_pt = that.second_pt;
    pts[0] = that.pts[0];
    pts[1] = that.pts[1];
    pts[2] = that.pts[2];
    use_wrap = that.use_wrap;
    orient_ = that.orient_;
    polygon_index = that.polygon_index;
  }
  inline iterator_geometry_to_set& operator++() {
    ++polygon_index;
    if(itrb == itre) {
      if(first_pt == pts[1]) polygon_index = -1;
      else {
        pts[0] = pts[1];
        pts[1] = pts[2];
        if(first_pt == pts[2]) {
          pts[2] = second_pt;
        } else {
          pts[2] = first_pt;
        }
      }
    } else {
      ++itrb;
      pts[0] = pts[1];
      pts[1] = pts[2];
      if(itrb == itre) {
        if(first_pt == pts[2]) {
          pts[2] = second_pt;
        } else {
          pts[2] = first_pt;
        }
      } else {
        pts[2] = *itrb;
      }
    }
    evaluate_();
    return *this;
  }
  inline const iterator_geometry_to_set operator++(int) {
    iterator_geometry_to_set tmp(*this);
    ++(*this);
    return tmp;
  }
  inline bool operator==(const iterator_geometry_to_set& that) const {
    return polygon_index == that.polygon_index;
  }
  inline bool operator!=(const iterator_geometry_to_set& that) const {
    return !(*this == that);
  }
  inline reference operator*() const {
    return vertex_; 
  }

  inline void evaluate_() {
    vertex_.first = pts[1].get(orient_.get_perpendicular());
    vertex_.second.first =pts[1].get(orient_);
    if(pts[1] == pts[2]) {
      vertex_.second.second = 0;
    } else if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) {
      vertex_.second.second = -1; 
    } else if(pts[0].get(VERTICAL) != pts[1].get(VERTICAL)) {
      vertex_.second.second = 1;
    } else {
      vertex_.second.second = 0;
    }
    vertex_.second.second *= multiplier_;
  }
};

template <typename polygon_with_holes_type>
class iterator_geometry_to_set<polygon_90_with_holes_concept, polygon_with_holes_type> {
public:
  typedef typename polygon_90_traits<polygon_with_holes_type>::coordinate_type coordinate_type;
  typedef std::forward_iterator_tag iterator_category;
  typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
  typedef std::ptrdiff_t difference_type;
  typedef const value_type* pointer; //immutable
  typedef const value_type& reference; //immutable
private:
  iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type> itrb, itre;
  iterator_geometry_to_set<polygon_90_concept, typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type> itrhib, itrhie;
  typename polygon_with_holes_traits<polygon_with_holes_type>::iterator_holes_type itrhb, itrhe;
  orientation_2d orient_;
  bool is_hole_;
  bool started_holes;
public:
  iterator_geometry_to_set() : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {}
  iterator_geometry_to_set(const polygon_with_holes_type& polygon, direction_1d dir, 
                           orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) : 
    itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(orient), is_hole_(is_hole), started_holes() {
    itre = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, HIGH, orient, is_hole_);
    itrhe = end_holes(polygon);
    if(dir == HIGH) {
      itrb = itre;
      itrhb = itrhe;
      started_holes = true;
    } else {
      itrb = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, LOW, orient, is_hole_);
      itrhb = begin_holes(polygon);
      started_holes = false;
    }
  }
  iterator_geometry_to_set(const iterator_geometry_to_set& that) : 
    itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {
    itrb = that.itrb;
    itre = that.itre;
    if(that.itrhib != that.itrhie) {
      itrhib = that.itrhib;
      itrhie = that.itrhie;
    }
    itrhb = that.itrhb;
    itrhe = that.itrhe;
    orient_ = that.orient_;
    is_hole_ = that.is_hole_;
    started_holes = that.started_holes;
  }
  inline iterator_geometry_to_set& operator++() {
    //this code can be folded with flow control factoring
    if(itrb == itre) {
      if(itrhib == itrhie) {
        if(itrhb != itrhe) {
          itrhib = iterator_geometry_to_set<polygon_90_concept, 
            typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
          itrhie = iterator_geometry_to_set<polygon_90_concept, 
            typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
          ++itrhb;
        } else {
          //in this case we have no holes so we just need the iterhib == itrhie, which
          //is always true if they were default initialized in the initial case or
          //both point to end of the previous hole processed
          //no need to explicitly reset them, and it causes an stl debug assertion to use
          //the default constructed iterator this way
          //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, 
          //  typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
        }
      } else {
        ++itrhib;
        if(itrhib == itrhie) {
          if(itrhb != itrhe) {
            itrhib = iterator_geometry_to_set<polygon_90_concept, 
              typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
            itrhie = iterator_geometry_to_set<polygon_90_concept, 
              typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
            ++itrhb;
          } else {
            //this is the same case as above
            //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, 
            //  typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
          }
        }
      }
    } else {
      ++itrb;
      if(itrb == itre) {
        if(itrhb != itrhe) {
          itrhib = iterator_geometry_to_set<polygon_90_concept, 
            typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
          itrhie = iterator_geometry_to_set<polygon_90_concept, 
            typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
          ++itrhb;
        }
      }
    }
    return *this;
  }
  inline const iterator_geometry_to_set operator++(int) {
    iterator_geometry_to_set tmp(*this);
    ++(*this);
    return tmp;
  }
  inline bool operator==(const iterator_geometry_to_set& that) const {
    return itrb == that.itrb && itrhb == that.itrhb && itrhib == that.itrhib;
  }
  inline bool operator!=(const iterator_geometry_to_set& that) const {
    return !(*this == that);
  }
  inline reference operator*() const {
    if(itrb != itre) return *itrb;
    return *itrhib;
  }
};


}
}
#endif

