// Vorosweep - Copyright (C) 2010-2014 T. Mouton
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <thibaud.mouton@gmail.com>.

#include "vorosweep.h"

using namespace vorosweep;

void Graph::handle_edgeswitch ( Event *ev )
{
  SweepEdge *se = ev->get_sweepedge();
  Event *ne = se->get_earliest_event();

  if ( ev->get_gid() == -1 )
  {
    if ( ne )
      add_event ( ne );
    else
      se->set_stopped();
    return;
  }

  // hack for not forgetting BORDEREDGESWITCH
  if ( ne && ne->get_type() == Event::BORDEREDGESWITCH )
    add_event ( ne );

  if ( se->is_stopped() )
    return;

  if ( !se->get_sweepfacet ( 0 ) || !se->get_sweepfacet ( 1 ) )
  {
    handle_simple_edgeswitch ( ev );
    add_earliest_event ( se );
    return;
  }

  double *pos = ev->get_coord();
  double time = ev->get_time();
  se->clear_events();
  se->update_current ( time );
  int gid = ev->get_gid();
  se->set_last_gid ( gid );
  // compute next edge switch event
  Event *next = next_edgeswitch ( se, pos, gid );
  se->set_next_switch ( next->get_time() );
  dbgprintf ( 5, "--> next switch event add :\n" );
  add_event ( next );
  // add sweepedge to the newly entered cell
  bucketgrid->insert_sweepedge ( se, gid );
  dbgprintf ( 5, "sweepedge se dir --> %lf %lf\n",  se->get_dir2d() [0], se->get_dir2d() [1] );

  // add event for facets
  for ( int i = 0; i < 2; i++ )
  {
    if ( se->get_sweepfacet ( i ) ) // careful to border edges
    {
      Event *ne = econtainer->get();
      ne->init ( se->get_sweepfacet ( i ),pos, time, Event::FACETSWITCH, gid ); // init event at same time
      add_event ( ne );
    }
  }
  // check for potential crash events in cell gid
  process_edge_events ( se, time, gid );
}

void Graph::handle_simple_edgeswitch ( Event *ev )
{
  dbgprintf ( 2, "--> simple edge event\n" );
  SweepEdge *se = ev->get_sweepedge();

  if ( se->is_stopped() )
    return;

  double *pos = ev->get_coord();
  double time = ev->get_time();
  se->update_current ( time );
  int gid = ev->get_gid();
  // compute next edge switch event
  Event *next = next_edgeswitch ( se, pos, gid );
  se->set_next_switch ( next->get_time() );
  dbgprintf ( 5, "--> next switch event add :\n" );
  add_event ( next );
  dbgprintf ( 5, "sweepedge se dir --> %lf %lf\n",  se->get_dir2d() [0], se->get_dir2d() [1] );

  // add event for facets
  for ( int i = 0; i < 2; i++ )
  {
    if ( se->get_sweepfacet ( i ) ) // careful to border edges
    {
      Event *ne = econtainer->get();
      ne->init ( se->get_sweepfacet ( i ),pos, time, Event::FACETSWITCH, gid ); // init event at same time
      add_event ( ne );
    }
  }
}
