/*
  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_POLYGON_90_SET_DATA_HPP
#define BOOST_POLYGON_POLYGON_90_SET_DATA_HPP
#include "isotropy.hpp"
#include "point_concept.hpp"
#include "point_3d_concept.hpp"
#include "transform.hpp"
#include "interval_concept.hpp"
#include "rectangle_concept.hpp"
#include "detail/iterator_points_to_compact.hpp"
#include "detail/iterator_compact_to_points.hpp"
#include "polygon_traits.hpp"

//manhattan boolean algorithms
#include "detail/boolean_op.hpp"
#include "detail/polygon_formation.hpp"
#include "detail/rectangle_formation.hpp"
#include "detail/max_cover.hpp"
#include "detail/property_merge.hpp"
#include "detail/polygon_90_touch.hpp"
#include "detail/iterator_geometry_to_set.hpp"

namespace boost { namespace polygon{
  template <typename ltype, typename rtype, typename op_type>
  class polygon_90_set_view;

  template <typename T>
  class polygon_90_set_data {
  public:
    typedef T coordinate_type;
    typedef std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > > value_type;
    typedef typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::const_iterator iterator_type;
    typedef polygon_90_set_data operator_arg_type;

    // default constructor
    inline polygon_90_set_data() : orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) {}

    // constructor
    inline polygon_90_set_data(orientation_2d orient) : orient_(orient), data_(), dirty_(false), unsorted_(false) {}

    // constructor from an iterator pair over vertex data
    template <typename iT>
    inline polygon_90_set_data(orientation_2d orient, iT input_begin, iT input_end) : 
      orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) {
      dirty_ = true;
      unsorted_ = true;
      for( ; input_begin != input_end; ++input_begin) { insert(*input_begin); }
    }

    // copy constructor
    inline polygon_90_set_data(const polygon_90_set_data& that) : 
      orient_(that.orient_), data_(that.data_), dirty_(that.dirty_), unsorted_(that.unsorted_) {}

    template <typename ltype, typename rtype, typename op_type>
    inline polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that);

    // copy with orientation change constructor
    inline polygon_90_set_data(orientation_2d orient, const polygon_90_set_data& that) : 
      orient_(orient), data_(), dirty_(false), unsorted_(false) {
      insert(that, false, that.orient_);
    }

    // destructor
    inline ~polygon_90_set_data() {}

    // assignement operator
    inline polygon_90_set_data& operator=(const polygon_90_set_data& that) {
      if(this == &that) return *this;
      orient_ = that.orient_;
      data_ = that.data_;
      dirty_ = that.dirty_;
      unsorted_ = that.unsorted_;
      return *this;
    }

    template <typename ltype, typename rtype, typename op_type>
    inline polygon_90_set_data& operator=(const polygon_90_set_view<ltype, rtype, op_type>& that);

    template <typename geometry_object>
    inline polygon_90_set_data& operator=(const geometry_object& geometry) {
      data_.clear();
      insert(geometry);
      return *this;
    }

    // insert iterator range
    inline void insert(iterator_type input_begin, iterator_type input_end, orientation_2d orient = HORIZONTAL) {
      if(input_begin == input_end || (!data_.empty() && &(*input_begin) == &(*(data_.begin())))) return;
      dirty_ = true;
      unsorted_ = true;
      if(orient == orient_)
        data_.insert(data_.end(), input_begin, input_end);
      else {
        for( ; input_begin != input_end; ++input_begin) {
          insert(*input_begin, false, orient);
        }
      }
    }

    // insert iterator range
    template <typename iT>
    inline void insert(iT input_begin, iT input_end, orientation_2d orient = HORIZONTAL) {
      if(input_begin == input_end) return;
      dirty_ = true;
      unsorted_ = true;
      for( ; input_begin != input_end; ++input_begin) {
        insert(*input_begin, false, orient);
      }
    }

    inline void insert(const polygon_90_set_data& polygon_set) {
      insert(polygon_set.begin(), polygon_set.end(), polygon_set.orient());
    }

    inline void insert(const std::pair<std::pair<point_data<coordinate_type>, point_data<coordinate_type> >, int>& edge, bool is_hole = false,
                       orientation_2d orient = HORIZONTAL) {
      std::pair<coordinate_type, std::pair<coordinate_type, int> > vertex;
      vertex.first = edge.first.first.x();
      vertex.second.first = edge.first.first.y();
      vertex.second.second = edge.second * (is_hole ? -1 : 1);
      insert(vertex, false, VERTICAL);
      vertex.first = edge.first.second.x();
      vertex.second.first = edge.first.second.y();
      vertex.second.second *= -1;
      insert(vertex, false, VERTICAL);
    }

    template <typename geometry_type>
    inline void insert(const geometry_type& geometry_object, bool is_hole = false, orientation_2d = HORIZONTAL) {
      iterator_geometry_to_set<typename geometry_concept<geometry_type>::type, geometry_type>
        begin_input(geometry_object, LOW, orient_, is_hole), end_input(geometry_object, HIGH, orient_, is_hole);
      insert(begin_input, end_input, orient_);
    }

    inline void insert(const std::pair<coordinate_type, std::pair<coordinate_type, int> >& vertex, bool is_hole = false, 
                       orientation_2d orient = HORIZONTAL) {
      data_.push_back(vertex);
      if(orient != orient_) std::swap(data_.back().first, data_.back().second.first);
      if(is_hole) data_.back().second.second *= -1;
      dirty_ = true;
      unsorted_ = true;
    }

    inline void insert(coordinate_type major_coordinate, const std::pair<interval_data<coordinate_type>, int>& edge) {
      std::pair<coordinate_type, std::pair<coordinate_type, int> > vertex;
      vertex.first = major_coordinate;
      vertex.second.first = edge.first.get(LOW);
      vertex.second.second = edge.second;
      insert(vertex, false, orient_);
      vertex.second.first = edge.first.get(HIGH);
      vertex.second.second *= -1;
      insert(vertex, false, orient_);
    }

    template <typename output_container>
    inline void get(output_container& output) const {
      get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type());
    }

    template <typename output_container>
    inline void get_polygons(output_container& output) const {
      get_dispatch(output, polygon_90_concept());
    }

    template <typename output_container>
    inline void get_rectangles(output_container& output) const {
      clean();
      form_rectangles(output, data_.begin(), data_.end(), orient_, rectangle_concept());
    }

    template <typename output_container>
    inline void get_rectangles(output_container& output, orientation_2d slicing_orientation) const {
      if(slicing_orientation == orient_) {
        get_rectangles(output);
      } else {
        polygon_90_set_data<coordinate_type> ps(*this);
        ps.transform(axis_transformation(axis_transformation::SWAP_XY));
        output_container result;
        ps.get_rectangles(result);
        for(typename output_container::iterator itr = result.begin(); itr != result.end(); ++itr) {
          ::boost::polygon::transform(*itr, axis_transformation(axis_transformation::SWAP_XY));
        }
        output.insert(output.end(), result.begin(), result.end());
      }
    }

    // equivalence operator 
    inline bool operator==(const polygon_90_set_data& p) const {
      if(orient_ == p.orient()) {
        clean();
        p.clean();
        return data_ == p.data_;
      } else {
        return false;
      }
    }

    // inequivalence operator 
    inline bool operator!=(const polygon_90_set_data& p) const {
      return !((*this) == p);
    }

    // get iterator to begin vertex data
    inline iterator_type begin() const {
      return data_.begin();
    }

    // get iterator to end vertex data
    inline iterator_type end() const {
      return data_.end();
    }

    const value_type& value() const {
      return data_;
    }

    // clear the contents of the polygon_90_set_data
    inline void clear() { data_.clear(); dirty_ = unsorted_ = false; }

    // find out if Polygon set is empty
    inline bool empty() const { clean(); return data_.empty(); }

    // get the Polygon set size in vertices
    inline std::size_t size() const { clean(); return data_.size(); }

    // get the current Polygon set capacity in vertices
    inline std::size_t capacity() const { return data_.capacity(); }

    // reserve size of polygon set in vertices
    inline void reserve(std::size_t size) { return data_.reserve(size); }

    // find out if Polygon set is sorted
    inline bool sorted() const { return !unsorted_; }

    // find out if Polygon set is clean
    inline bool dirty() const { return dirty_; }

    // get the scanline orientation of the polygon set
    inline orientation_2d orient() const { return orient_; }

    // Start BM
    // The problem: If we have two polygon sets with two different scanline orientations:
    // I tried changing the orientation of one to coincide with other (If not, resulting boolean operation
    // produces spurious results).
    // First I tried copying polygon data from one of the sets into another set with corrected orientation
    // using one of the copy constructor that takes in orientation (see somewhere above in this file) --> copy constructor throws error
    // Then I tried another approach:(see below). This approach also fails to produce the desired results when test case is run.
    // Here is the part that beats me: If I comment out the whole section, I can do all the operations (^=, -=, &= )these commented out
    // operations perform. So then why do we need them?. Hence, I commented out this whole section.
    // End BM
    // polygon_90_set_data<coordinate_type>& operator-=(const polygon_90_set_data& that) {
    //   sort();
    //   that.sort();
    //   value_type data;
    //   std::swap(data, data_);
    //   applyBooleanBinaryOp(data.begin(), data.end(),
    //                        that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryNot>()); 
    //   return *this;
    // }
    // polygon_90_set_data<coordinate_type>& operator^=(const polygon_90_set_data& that) {
    //   sort();
    //   that.sort();
    //   value_type data;
    //   std::swap(data, data_);
    //   applyBooleanBinaryOp(data.begin(), data.end(),
    //                        that.begin(), that.end(),  boolean_op::BinaryCount<boolean_op::BinaryXor>()); 
    //   return *this;
    // }
    // polygon_90_set_data<coordinate_type>& operator&=(const polygon_90_set_data& that) {
    //   sort();
    //   that.sort();
    //   value_type data;
    //   std::swap(data, data_);
    //   applyBooleanBinaryOp(data.begin(), data.end(),
    //                        that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryAnd>()); 
    //   return *this;
    // }
    // polygon_90_set_data<coordinate_type>& operator|=(const polygon_90_set_data& that) {
    //   insert(that);
    //   return *this;
    // }

    void clean() const {
      sort();
      if(dirty_) {
        boolean_op::default_arg_workaround<int>::applyBooleanOr(data_);
        dirty_ = false;
      }
    }

    void sort() const{
      if(unsorted_) {
        gtlsort(data_.begin(), data_.end());
        unsorted_ = false;
      }
    }

    template <typename input_iterator_type>
    void set(input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) {
      data_.clear();
      data_.insert(data_.end(), input_begin, input_end);
      orient_ = orient;
      dirty_ = true;
      unsorted_ = true;
    }

    void set(const value_type& value, orientation_2d orient) {
      data_ = value; 
      orient_ = orient;
      dirty_ = true;
      unsorted_ = true;
    }

    //extents
    template <typename rectangle_type>
    bool
    extents(rectangle_type& extents_rectangle) const {
      clean();
      if(data_.empty()) return false;
      if(orient_ == HORIZONTAL)
        set_points(extents_rectangle, point_data<coordinate_type>(data_[0].second.first, data_[0].first),
                   point_data<coordinate_type>(data_[data_.size() - 1].second.first, data_[data_.size() - 1].first));
      else
        set_points(extents_rectangle, point_data<coordinate_type>(data_[0].first, data_[0].second.first),
                   point_data<coordinate_type>(data_[data_.size() - 1].first, data_[data_.size() - 1].second.first));
      for(std::size_t i = 1; i < data_.size() - 1; ++i) {
        if(orient_ == HORIZONTAL)
          encompass(extents_rectangle, point_data<coordinate_type>(data_[i].second.first, data_[i].first));
        else
          encompass(extents_rectangle, point_data<coordinate_type>(data_[i].first, data_[i].second.first));
      }
      return true;
    }

    polygon_90_set_data&
    bloat2(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating,
          typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating,
          typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating,
          typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) {
      std::vector<rectangle_data<coordinate_type> > rects;
      clean();
      rects.reserve(data_.size() / 2); 
      get(rects);
      rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)west_bloating), 
                                                                                          (coordinate_type)east_bloating),
                                                           interval_data<coordinate_type>(-((coordinate_type)south_bloating), 
                                                                                          (coordinate_type)north_bloating));
      for(typename std::vector<rectangle_data<coordinate_type> >::iterator itr = rects.begin();
          itr != rects.end(); ++itr) {
        convolve(*itr, convolutionRectangle);
      }
      clear();
      insert(rects.begin(), rects.end());
      return *this;
    }

    static void modify_pt(point_data<coordinate_type>& pt, const point_data<coordinate_type>&  prev_pt,
                          const point_data<coordinate_type>&  current_pt,  const point_data<coordinate_type>&  next_pt,
                          coordinate_type west_bloating,
                          coordinate_type east_bloating,
                          coordinate_type south_bloating,
                          coordinate_type north_bloating) {
      bool pxl = prev_pt.x() < current_pt.x();
      bool pyl = prev_pt.y() < current_pt.y();
      bool nxl = next_pt.x() < current_pt.x();
      bool nyl = next_pt.y() < current_pt.y();
      bool pxg = prev_pt.x() > current_pt.x();
      bool pyg = prev_pt.y() > current_pt.y();
      bool nxg = next_pt.x() > current_pt.x();
      bool nyg = next_pt.y() > current_pt.y();
      //two of the four if statements will execute
      if(pxl)
        pt.y(current_pt.y() - south_bloating);
      if(pxg)
        pt.y(current_pt.y() + north_bloating);
      if(nxl)
        pt.y(current_pt.y() + north_bloating);
      if(nxg)
        pt.y(current_pt.y() - south_bloating);
      if(pyl)
        pt.x(current_pt.x() + east_bloating);
      if(pyg)
        pt.x(current_pt.x() - west_bloating);
      if(nyl)
        pt.x(current_pt.x() - west_bloating);
      if(nyg)
        pt.x(current_pt.x() + east_bloating);
    }
    static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly, 
                               coordinate_type west_bloating,
                               coordinate_type east_bloating,
                               coordinate_type south_bloating,
                               coordinate_type north_bloating) {
      point_data<coordinate_type> first_pt = poly[0];
      point_data<coordinate_type> second_pt = poly[1];
      point_data<coordinate_type> prev_pt = poly[0];
      point_data<coordinate_type> current_pt = poly[1];
      for(std::size_t i = 2; i < poly.size(); ++i) {
        point_data<coordinate_type> next_pt = poly[i];
        modify_pt(poly[i-1], prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating);
        prev_pt = current_pt;
        current_pt = next_pt;
      }
      point_data<coordinate_type> next_pt = first_pt;
      modify_pt(poly.back(), prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating);
      prev_pt = current_pt;
      current_pt = next_pt;
      next_pt = second_pt;
      modify_pt(poly[0], prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating);
      remove_colinear_pts(poly);
    }
    static bool resize_poly_down(std::vector<point_data<coordinate_type> >& poly, 
                                 coordinate_type west_shrinking,
                                 coordinate_type east_shrinking,
                                 coordinate_type south_shrinking,
                                 coordinate_type north_shrinking) {
      rectangle_data<coordinate_type> extents_rectangle;
      set_points(extents_rectangle, poly[0], poly[0]);
      point_data<coordinate_type> first_pt = poly[0];
      point_data<coordinate_type> second_pt = poly[1];
      point_data<coordinate_type> prev_pt = poly[0];
      point_data<coordinate_type> current_pt = poly[1];
      encompass(extents_rectangle, current_pt);
      for(int i = 2; i < poly.size(); ++i) {
        point_data<coordinate_type> next_pt = poly[i];
        encompass(extents_rectangle, next_pt);
        modify_pt(poly[i-1], prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking);
        prev_pt = current_pt;
        current_pt = next_pt;
      }
      if(delta(extents_rectangle, HORIZONTAL) < std::abs(west_shrinking + east_shrinking))
        return false;
      if(delta(extents_rectangle, VERTICAL) < std::abs(north_shrinking + south_shrinking))
        return false;
      point_data<coordinate_type> next_pt = first_pt;
      modify_pt(poly.back(), prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking);
      prev_pt = current_pt;
      current_pt = next_pt;
      next_pt = second_pt;
      modify_pt(poly[0], prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking);
      return remove_colinear_pts(poly);
    }

    static bool remove_colinear_pts(std::vector<point_data<coordinate_type> >& poly) {
      bool found_colinear = true;
      while(found_colinear && poly.size() >= 4) {
        found_colinear = false;
        typename std::vector<point_data<coordinate_type> >::iterator itr = poly.begin(); 
        itr += poly.size() - 1; //get last element position
        typename std::vector<point_data<coordinate_type> >::iterator itr2 = poly.begin();
        typename std::vector<point_data<coordinate_type> >::iterator itr3 = itr2;
        ++itr3;
        std::size_t count = 0;
        for( ; itr3 < poly.end(); ++itr3) {
          if(((*itr).x() == (*itr2).x() && (*itr).x() == (*itr3).x()) ||
             ((*itr).y() == (*itr2).y() && (*itr).y() == (*itr3).y()) ) {
            ++count;
            found_colinear = true;
          } else {
            itr = itr2;
            ++itr2;
          }
          *itr2 = *itr3;
        }
        itr3 = poly.begin();
        if(((*itr).x() == (*itr2).x() && (*itr).x() == (*itr3).x()) ||
           ((*itr).y() == (*itr2).y() && (*itr).y() == (*itr3).y()) ) {
          ++count;
          found_colinear = true;
        }
        poly.erase(poly.end() - count, poly.end());
      }
      return poly.size() >= 4;
    }    

    polygon_90_set_data&
    bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating,
           typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating,
           typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating,
           typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) {
      std::list<polygon_45_with_holes_data<coordinate_type> > polys;
      get(polys);
      clear();
      for(typename std::list<polygon_45_with_holes_data<coordinate_type> >::iterator itr = polys.begin();
          itr != polys.end(); ++itr) {
        //polygon_90_set_data<coordinate_type> psref;
        //psref.insert(view_as<polygon_90_concept>((*itr).self_));
        //rectangle_data<coordinate_type> prerect;
        //psref.extents(prerect);
        resize_poly_up((*itr).self_.coords_, west_bloating, east_bloating, south_bloating, north_bloating);
        iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
          begin_input(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE), 
          end_input(view_as<polygon_90_concept>((*itr).self_), HIGH, orient_, false, true, COUNTERCLOCKWISE);
        insert(begin_input, end_input, orient_);
        //polygon_90_set_data<coordinate_type> pstest;
        //pstest.insert(view_as<polygon_90_concept>((*itr).self_));
        //psref.bloat2(west_bloating, east_bloating, south_bloating, north_bloating);
        //if(!equivalence(psref, pstest)) {
        // std::cout << "test failed\n";
        //}
        for(typename std::list<polygon_45_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin();
            itrh != (*itr).holes_.end(); ++itrh) {
          //rectangle_data<coordinate_type> rect;
          //psref.extents(rect);
          //polygon_90_set_data<coordinate_type> psrefhole;
          //psrefhole.insert(prerect);
          //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true);
          //polygon_45_data<coordinate_type> testpoly(*itrh);
          if(resize_poly_down((*itrh).coords_, west_bloating, east_bloating, south_bloating, north_bloating)) {
            iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
              begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true), 
              end_input2(view_as<polygon_90_concept>(*itrh), HIGH, orient_, true, true);
            insert(begin_input2, end_input2, orient_);
            //polygon_90_set_data<coordinate_type> pstesthole;
            //pstesthole.insert(rect);
            //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
            // begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true); 
            //pstesthole.insert(begin_input2, end_input, orient_);
            //psrefhole.bloat2(west_bloating, east_bloating, south_bloating, north_bloating);
            //if(!equivalence(psrefhole, pstesthole)) {
            // std::cout << (winding(testpoly) == CLOCKWISE) << std::endl;
            // std::cout << (winding(*itrh) == CLOCKWISE) << std::endl;
            // polygon_90_set_data<coordinate_type> c(psrefhole);
            // c.clean();
            // polygon_90_set_data<coordinate_type> a(pstesthole);
            // polygon_90_set_data<coordinate_type> b(pstesthole);
            // a.sort();
            // b.clean();
            // std::cout << "test hole failed\n";
            // //std::cout << testpoly << std::endl;
            //}
          }
        }
      }
      return *this;
    }

    polygon_90_set_data&
    shrink(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking,
           typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking,
           typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking,
           typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) {
      std::list<polygon_45_with_holes_data<coordinate_type> > polys;
      get(polys);
      clear();
      for(typename std::list<polygon_45_with_holes_data<coordinate_type> >::iterator itr = polys.begin();
          itr != polys.end(); ++itr) {
        //polygon_90_set_data<coordinate_type> psref;
        //psref.insert(view_as<polygon_90_concept>((*itr).self_));
        //rectangle_data<coordinate_type> prerect;
        //psref.extents(prerect);
        //polygon_45_data<coordinate_type> testpoly((*itr).self_);
        if(resize_poly_down((*itr).self_.coords_, -west_shrinking, -east_shrinking, -south_shrinking, -north_shrinking)) {
          iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
            begin_input(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE), 
            end_input(view_as<polygon_90_concept>((*itr).self_), HIGH, orient_, false, true, COUNTERCLOCKWISE);
          insert(begin_input, end_input, orient_);
          //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
          //  begin_input2(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE); 
          //polygon_90_set_data<coordinate_type> pstest;
          //pstest.insert(begin_input2, end_input, orient_);
          //psref.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
          //if(!equivalence(psref, pstest)) {
          //  std::cout << "test failed\n";
          //}
          for(typename std::list<polygon_45_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin();
              itrh != (*itr).holes_.end(); ++itrh) {
            //rectangle_data<coordinate_type> rect;
            //psref.extents(rect);
            //polygon_90_set_data<coordinate_type> psrefhole;
            //psrefhole.insert(prerect);
            //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true);
            //polygon_45_data<coordinate_type> testpoly(*itrh);
            resize_poly_up((*itrh).coords_, -west_shrinking, -east_shrinking, -south_shrinking, -north_shrinking);
            iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
              begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true), 
              end_input2(view_as<polygon_90_concept>(*itrh), HIGH, orient_, true, true);
            insert(begin_input2, end_input2, orient_);
            //polygon_90_set_data<coordinate_type> pstesthole;
            //pstesthole.insert(rect);
            //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
            //  begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true); 
            //pstesthole.insert(begin_input2, end_input, orient_);
            //psrefhole.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
            //if(!equivalence(psrefhole, pstesthole)) {
            //  std::cout << (winding(testpoly) == CLOCKWISE) << std::endl;
            //  std::cout << (winding(*itrh) == CLOCKWISE) << std::endl;
            //  polygon_90_set_data<coordinate_type> c(psrefhole);
            //  c.clean();
            //  polygon_90_set_data<coordinate_type> a(pstesthole);
            //  polygon_90_set_data<coordinate_type> b(pstesthole);
            //  a.sort();
            //  b.clean();
            //  std::cout << "test hole failed\n";
            //  //std::cout << testpoly << std::endl;
            //}
          }
        }
      }
      return *this;
    }

    polygon_90_set_data&
    shrink2(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking,
            typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking,
            typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking,
            typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) {
      rectangle_data<coordinate_type> externalBoundary;
      if(!extents(externalBoundary)) return *this;
      ::boost::polygon::bloat(externalBoundary, 10); //bloat by diferential ammount
      //insert a hole that encompasses the data
      insert(externalBoundary, true); //note that the set is in a dirty state now
      sort();  //does not apply implicit OR operation
      std::vector<rectangle_data<coordinate_type> > rects;
      rects.reserve(data_.size() / 2); 
      //begin does not apply implicit or operation, this is a dirty range
      form_rectangles(rects, data_.begin(), data_.end(), orient_, rectangle_concept());
      clear();
      rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)east_shrinking), 
                                                                                          (coordinate_type)west_shrinking),
                                                           interval_data<coordinate_type>(-((coordinate_type)north_shrinking), 
                                                                                          (coordinate_type)south_shrinking));
      for(typename std::vector<rectangle_data<coordinate_type> >::iterator itr = rects.begin();
          itr != rects.end(); ++itr) {
        rectangle_data<coordinate_type>& rect = *itr;
        convolve(rect, convolutionRectangle);
        //insert rectangle as a hole
        insert(rect, true);
      }
      convolve(externalBoundary, convolutionRectangle);
      //insert duplicate of external boundary as solid to cancel out the external hole boundaries
      insert(externalBoundary);
      clean(); //we have negative values in the set, so we need to apply an OR operation to make it valid input to a boolean
      return *this;
    }

    polygon_90_set_data&
    shrink(direction_2d dir, typename coordinate_traits<coordinate_type>::unsigned_area_type shrinking) {
      if(dir == WEST)
        return shrink(shrinking, 0, 0, 0);
      if(dir == EAST)
        return shrink(0, shrinking, 0, 0);
      if(dir == SOUTH)
        return shrink(0, 0, shrinking, 0);
      return shrink(0, 0, 0, shrinking);
    }

    polygon_90_set_data&
    bloat(direction_2d dir, typename coordinate_traits<coordinate_type>::unsigned_area_type shrinking) {
      if(dir == WEST)
        return bloat(shrinking, 0, 0, 0);
      if(dir == EAST)
        return bloat(0, shrinking, 0, 0);
      if(dir == SOUTH)
        return bloat(0, 0, shrinking, 0);
      return bloat(0, 0, 0, shrinking);
    }

    polygon_90_set_data&
    resize(coordinate_type west, coordinate_type east, coordinate_type south, coordinate_type north); 

    polygon_90_set_data& move(coordinate_type x_delta, coordinate_type y_delta) {
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator 
            itr = data_.begin(); itr != data_.end(); ++itr) {
        if(orient_ == orientation_2d(VERTICAL)) {
          (*itr).first += x_delta;
          (*itr).second.first += y_delta;
        } else {
          (*itr).second.first += x_delta;
          (*itr).first += y_delta;
        }
      }
      return *this;
    }

    // transform set
    template <typename transformation_type>
    polygon_90_set_data& transform(const transformation_type& transformation) {
      direction_2d dir1, dir2;
      transformation.get_directions(dir1, dir2);
      int sign = dir1.get_sign() * dir2.get_sign();
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator
            itr = data_.begin(); itr != data_.end(); ++itr) {
        if(orient_ == orientation_2d(VERTICAL)) {
          transformation.transform((*itr).first, (*itr).second.first);
        } else {
          transformation.transform((*itr).second.first, (*itr).first);
        }
        (*itr).second.second *= sign;
      }
      if(dir1 != EAST || dir2 != NORTH)
        unsorted_ = true; //some mirroring or rotation must have happened
      return *this;
    }

    // scale set
    polygon_90_set_data& scale_up(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator 
            itr = data_.begin(); itr != data_.end(); ++itr) {
        (*itr).first *= (coordinate_type)factor;
        (*itr).second.first *= (coordinate_type)factor;
      }
      return *this;
    }
    polygon_90_set_data& scale_down(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
      typedef typename coordinate_traits<coordinate_type>::coordinate_distance dt;
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator 
            itr = data_.begin(); itr != data_.end(); ++itr) {
        (*itr).first = scaling_policy<coordinate_type>::round((dt)((*itr).first) / (dt)factor);
        (*itr).second.first = scaling_policy<coordinate_type>::round((dt)((*itr).second.first) / (dt)factor);
      }
      unsorted_ = true; //scaling down can make coordinates equal that were not previously equal
      return *this;
    }
    template <typename scaling_type>
    polygon_90_set_data& scale(const anisotropic_scale_factor<scaling_type>& scaling) {
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator 
            itr = data_.begin(); itr != data_.end(); ++itr) {
        if(orient_ == orientation_2d(VERTICAL)) {
          scaling.scale((*itr).first, (*itr).second.first);
        } else {
          scaling.scale((*itr).second.first, (*itr).first);
        }
      }
      unsorted_ = true;
      return *this;
    }
    template <typename scaling_type>
    polygon_90_set_data& scale_with(const scaling_type& scaling) {
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator 
            itr = data_.begin(); itr != data_.end(); ++itr) {
        if(orient_ == orientation_2d(VERTICAL)) {
          scaling.scale((*itr).first, (*itr).second.first);
        } else {
          scaling.scale((*itr).second.first, (*itr).first);
        }
      }
      unsorted_ = true;
      return *this;
    }
    polygon_90_set_data& scale(double factor) {
      typedef typename coordinate_traits<coordinate_type>::coordinate_distance dt;
      for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator 
            itr = data_.begin(); itr != data_.end(); ++itr) {
        (*itr).first = scaling_policy<coordinate_type>::round((dt)((*itr).first) * (dt)factor);
        (*itr).second.first = scaling_policy<coordinate_type>::round((dt)((*itr).second.first) * (dt)factor);
      }
      unsorted_ = true; //scaling make coordinates equal that were not previously equal
      return *this;
    }

    polygon_90_set_data& self_xor() {
      sort();
      if(dirty_) { //if it is clean it is a no-op
        boolean_op::default_arg_workaround<boolean_op::UnaryCount>::applyBooleanOr(data_);
        dirty_ = false;
      }
      return *this;
    }

    polygon_90_set_data& self_intersect() {
      sort();
      if(dirty_) { //if it is clean it is a no-op
        interval_data<coordinate_type> ivl((std::numeric_limits<coordinate_type>::min)(), (std::numeric_limits<coordinate_type>::max)());
        rectangle_data<coordinate_type> rect(ivl, ivl);
        insert(rect, true);
        clean();
      }
      return *this;
    }

    inline polygon_90_set_data& interact(const polygon_90_set_data& that) {
      typedef coordinate_type Unit;
      if(that.dirty_) that.clean();
      typename touch_90_operation<Unit>::TouchSetData tsd;
      touch_90_operation<Unit>::populateTouchSetData(tsd, that.data_, 0);
      std::vector<polygon_90_data<Unit> > polys;
      get(polys);
      std::vector<std::set<int> > graph(polys.size()+1, std::set<int>());
      for(std::size_t i = 0; i < polys.size(); ++i){
        polygon_90_set_data<Unit> psTmp(that.orient_);
        psTmp.insert(polys[i]);
        psTmp.clean();
        touch_90_operation<Unit>::populateTouchSetData(tsd, psTmp.data_, i+1);
      }
      touch_90_operation<Unit>::performTouch(graph, tsd);
      clear();
      for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){
        insert(polys[(*itr)-1]);
      }
      dirty_ = false;
      return *this;
    }


    template <class T2, typename iterator_type_1, typename iterator_type_2>
    void applyBooleanBinaryOp(iterator_type_1 itr1, iterator_type_1 itr1_end,
                              iterator_type_2 itr2, iterator_type_2 itr2_end,
                              T2 defaultCount) {
      data_.clear();
      boolean_op::applyBooleanBinaryOp(data_, itr1, itr1_end, itr2, itr2_end, defaultCount);
    }

  private:
    orientation_2d orient_;
    mutable value_type data_;
    mutable bool dirty_;
    mutable bool unsorted_;
  
  private:
    //functions
    template <typename output_container>
    void get_dispatch(output_container& output, rectangle_concept ) const {
      clean();
      form_rectangles(output, data_.begin(), data_.end(), orient_, rectangle_concept());
    }
    template <typename output_container>
    void get_dispatch(output_container& output, polygon_90_concept tag) const {
      get_fracture(output, true, tag);
    }
    template <typename output_container>
    void get_dispatch(output_container& output, polygon_90_with_holes_concept tag) const {
      get_fracture(output, false, tag);
    }
    template <typename output_container>
    void get_dispatch(output_container& output, polygon_45_concept tag) const {
      get_fracture(output, true, tag);
    }
    template <typename output_container>
    void get_dispatch(output_container& output, polygon_45_with_holes_concept tag) const {
      get_fracture(output, false, tag);
    }
    template <typename output_container>
    void get_dispatch(output_container& output, polygon_concept tag) const {
      get_fracture(output, true, tag);
    }
    template <typename output_container>
    void get_dispatch(output_container& output, polygon_with_holes_concept tag) const {
      get_fracture(output, false, tag);
    }
    template <typename output_container, typename concept_type>
    void get_fracture(output_container& container, bool fracture_holes, concept_type tag) const {
      clean();
      ::boost::polygon::get_polygons(container, data_.begin(), data_.end(), orient_, fracture_holes, tag);
    }
  };

  template <typename coordinate_type>
  polygon_90_set_data<coordinate_type>&
  polygon_90_set_data<coordinate_type>::resize(coordinate_type west,
                                               coordinate_type east,
                                               coordinate_type south,
                                               coordinate_type north) {
    move(-west, -south);
    coordinate_type e_total = west + east;
    coordinate_type n_total = south + north;
    if((e_total < 0) ^ (n_total < 0)) {
      //different signs
      if(e_total < 0) {
        shrink(0, -e_total, 0, 0);
        if(n_total != 0)
          return bloat(0, 0, 0, n_total);
        else
          return (*this);
      } else {
        shrink(0, 0, 0, -n_total); //shrink first
        if(e_total != 0)
          return bloat(0, e_total, 0, 0);
        else
          return (*this);
      }
    } else {
      if(e_total < 0) {
        return shrink(0, -e_total, 0, -n_total);
      }
      return bloat(0, e_total, 0, n_total);
    }
  }
    
  template <typename coordinate_type, typename property_type>
  class property_merge_90 {
  private:
    std::vector<std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > > pmd_;
  public:
    inline property_merge_90() : pmd_() {}
    inline property_merge_90(const property_merge_90& that) : pmd_(that.pmd_) {}
    inline property_merge_90& operator=(const property_merge_90& that) { pmd_ = that.pmd_; return *this; }
    inline void insert(const polygon_90_set_data<coordinate_type>& ps, const property_type& property) {
      merge_scanline<coordinate_type, property_type, polygon_90_set_data<coordinate_type> >::
        populate_property_merge_data(pmd_, ps.begin(), ps.end(), property, ps.orient());
    }
    template <class GeoObjT>
    inline void insert(const GeoObjT& geoObj, const property_type& property) {
      polygon_90_set_data<coordinate_type> ps;
      ps.insert(geoObj);
      insert(ps, property);
    }
    //merge properties of input geometries and store the resulting geometries of regions
    //with unique sets of merged properties to polygons sets in a map keyed by sets of properties
    // T = std::map<std::set<property_type>, polygon_90_set_data<coordiante_type> > or
    // T = std::map<std::vector<property_type>, polygon_90_set_data<coordiante_type> >
    template <typename ResultType> 
    inline void merge(ResultType& result) {
      merge_scanline<coordinate_type, property_type, polygon_90_set_data<coordinate_type>, typename ResultType::key_type> ms;
      ms.perform_merge(result, pmd_);
    }
  };

  //ConnectivityExtraction computes the graph of connectivity between rectangle, polygon and
  //polygon set graph nodes where an edge is created whenever the geometry in two nodes overlap
  template <typename coordinate_type>
  class connectivity_extraction_90 {
  private:
    typedef typename touch_90_operation<coordinate_type>::TouchSetData tsd;
    tsd tsd_;
    unsigned int nodeCount_;
  public:
    inline connectivity_extraction_90() : tsd_(), nodeCount_(0) {}
    inline connectivity_extraction_90(const connectivity_extraction_90& that) : tsd_(that.tsd_),
                                                                          nodeCount_(that.nodeCount_) {}
    inline connectivity_extraction_90& operator=(const connectivity_extraction_90& that) { 
      tsd_ = that.tsd_; 
      nodeCount_ = that.nodeCount_; {}
      return *this;
    }
    
    //insert a polygon set graph node, the value returned is the id of the graph node
    inline unsigned int insert(const polygon_90_set_data<coordinate_type>& ps) {
      ps.clean();
      touch_90_operation<coordinate_type>::populateTouchSetData(tsd_, ps.begin(), ps.end(), nodeCount_);
      return nodeCount_++;
    }
    template <class GeoObjT>
    inline unsigned int insert(const GeoObjT& geoObj) {
      polygon_90_set_data<coordinate_type> ps;
      ps.insert(geoObj);
      return insert(ps);
    }
    
    //extract connectivity and store the edges in the graph
    //graph must be indexable by graph node id and the indexed value must be a std::set of
    //graph node id
    template <class GraphT>
    inline void extract(GraphT& graph) {
      touch_90_operation<coordinate_type>::performTouch(graph, tsd_);
    }
  };
}
}
#endif

