/* simple3d.cc */

#include "simple3d.h"
#include "view3d.h"

//static window view_window( screenWid, screenHgt, "VIEW_WINDOW" );

static triple main_view_pos = triple( 0, 400, 1200 );
matrix simple_R = matrix::unity(3);

dc_view main_view( "main_view", main_view_pos, simple_R );

void draw_link( triple src, triple tgt, bool /*directed*/, 
		const color c = red_col ) {
  if( !gfx_on ) return;
  /*  point src_pt = project_to_screen( src );
  point tgt_pt = project_to_screen( tgt );*/

  /*  if( directed ) {
    view_window.draw_arrow( src_pt, tgt_pt, c );
  } else {
    view_window.draw_segment( src_pt, tgt_pt, c );
  } */

  if( !DRAW_GL ) {
    dc_view *V;
    forall( V, view_list ) {
      V->draw_line( src, tgt, c );
    }
  }
}

// /* wp is world point.  wWid & wHgt are width and height of screen in world space
//    sWid & sHgt are width and height of screen in screen space.  wZ is distance 
//    of screen from origin in world space */
// point project_to_screen( triple wp ) {
//   /* sp is where projection of line from ( 0, 0, 0 ) to wp, intersects plane
//      defined by x-y plane at sZ from origin */
//   double scale = ( wp(2) + disp_size ) / ( worldZ + disp_size );
//   if( Y_AXIS_UP ) {
//     return point( x_off + wp(0) * scale * ( disp_size / worldWid ), 
// 		  y_off + wp(1) * scale * ( disp_size / worldHgt ) );
//   } else {
//     return point( x_off + wp(0) * scale * ( disp_size / worldWid ), 
// 		  y_off - wp(1) * scale * ( disp_size / worldHgt ));
//   }
// }

void init_view( void ) {
  //view_window.display();
}

void close_view( void ) {
  //view_window.close();
}

void clear_view( void ) {
  if( !gfx_on() ) return;
  
  dc_view *V;
  forall( V, view_list ) {
    V->clear();
  }
}

void draw_shape( Shape &s, const color C ) {
  if( !gfx_on() ) return;

  if( s.body == nil ) {
    cerr << "draw_shape -- failed to draw disconnected shape\n";
    return;
  }

  EntityHook::EntityType etype = s.type();
  if( etype == EntityHook::MULTISHAPE ) {
    llist_iter<Shape *>iter = ( ( MultiShape * )&s )->children;
    while( iter ) {
      draw_shape( *( iter() ), C );
      iter++;
    }
  } else if( etype == EntityHook::POLY3D ) {
    if( DRAW_GL ) {
      int npts = ( ( Poly3d * )&s )->ndegree;
      if( s.user_data == nil ) {
	triple *pts = new triple[npts];
	s.user_data = pts;
	for( int i = 0 ; i < npts ; i++ ) {
	  pts[i] = ( ( Poly3d * )&s )->bp(i);
	}
      }
      dc_view *V;
      forall( V, view_list ) {
	V->draw_poly( ( triple * )s.user_data, npts, ( ( RigidBody * )s.body )->
		      r, ( ( RigidBody * )s.body )->x, C );
      }
    } else {
      list<triple> pts;
      for( int i = 0 ; i < ( ( Poly3d * )&s )->ndegree ; i++ ) {
	triple wp = s.body->T( ( ( Poly3d * )&s )->bp( i ) );
	pts.append( wp );
      }
      dc_view *V;
      forall( V, view_list ) {
	V->draw_poly( pts, C );
      }
      pts.clear();
    }
  }
}

// void draw_constraint( const EConstraint *E ) {
//   switch( E->type() ) {
//   case EntityHook::NAIL :
//     cerr << "draw_constraint -- draw nail not written yet\n";
//     exit(1);
//     break;
//   case EntityHook::PINJOINT :
//     cerr << "draw_pinjoint -- draw pinjoint not written yet\n";
//     exit(1);
//     break;
//   default :;
//   }
// }
