/*
 *  segment.h
 *  VSweep
 *
 *  Created by Chema on 10/18/10.
 *  Copyright 2010 __MyCompanyName__. All rights reserved.
 *
 */

#include <vector>
#include <list>
#include <set>
#include "vec.h"

#ifndef segment_H
#define segment_H

struct Edge {
    enum eType {eLeft, eRight};
    typedef std::vector<Edge> vector;
    typedef std::list<Edge*> list;
    
    DReal2 p_;
    dreal y_;
    dreal dxdy_;
    dreal dzdy_;
    const DReal3* vx_[2];
    list::iterator aitr_; //active itr

    Edge(): p_(0,0), y_(0), dzdy_(0), dxdy_(0)
    {
        vx_[0]=0;
        vx_[1]=0;
    }
    
    void init(const DReal3* a, const DReal3*b);
    void reset(list& aet);
    void inc(dreal level);
    
    bool operator==(const Edge& ref) const {
        return p_==ref.p_;
    }
    bool operator!=(const Edge& ref) const {
        return !(*this==ref);
    }
};

struct Segment;

struct Event {
    enum eType {eLeft, eRight, eInterx};

    typedef std::multiset<Event> queue; // ordered list for events
//    typedef std::list<Event> queue; // ordered list for events  

    eType type_; // event type: LEFT or RIGHT vertex or INTERX
    DReal2 p_; // event vertex
    Segment* sa_; // event segment or above segment
    Segment* sb_; // event below segment 

    // left or right event
    Event(Segment* seg, const eType& type);
    // intersection event
    Event(Segment* sa, Segment* sb, const DReal2& p);
        
    // lexicographical ordering (first x, then y)
    bool operator<(const Event& ref) const;

};


struct Segment {
    enum ePosition {eAbove, eBelow};
    struct Compare: public std::binary_function<const Segment*,const Segment*,bool> {
        bool operator()(const Segment* lhs, const Segment* rhs) const;
    };    
    typedef std::multiset<Segment*,Compare> tree; // balanced binary tree for SL segments
    typedef std::vector<Segment> vector;
    
    unsigned index_;
    Edge* aeg_[2]; // active edges
    dreal m_;  // segment slope (wrt x (or [0]) component)
    const struct Triangle* tri_; // triangle this segment belongs to
    tree::iterator titr_;   // tree iterator

    bool hot_; // flag for segment compare
   // Edge::eType d_; // decide edge (left if sweep is before intersecx, right if sweep is after intersecx) 

    Segment() 
        : index_(0)
        , hot_(false)
        //, d_(Edge::eLeft)
        , m_(0)
    {
        aeg_[0]=0;
        aeg_[1]=0;
    }
    
    void init(Edge* l, Edge* r);

    void reset(Event::queue& events);
    void activateEdges(Edge::list& aet);
    void deActivateEdges(Edge::list& aet);

    bool operator==(const Segment& ref) const {
        return aeg_[0] == ref.aeg_[0] && aeg_[1]==ref.aeg_[1];
    }
    bool operator!=(const Segment& ref) const {
        return !(*this==ref);
    }
};

#endif