#include <gp/coord.h>
#include "frame_buffer.h"
pMatrix transform_construct(pFrame_Buffer& demo_frame_buffer);
void
render(pFrame_Buffer& demo_frame_buffer)
{
      vector<pCoor> coors_os;
    
      vector<int32_t> colors;
          
           coors_os << pCoor( 0, 0, 0 );
    
        coors_os << pCoor( 9, 6, -9 ) << pCoor( 0, 7, -5 );
        colors << 0xffffff;
      coors_os << pCoor(7,4,-2) << pCoor(-3,5,-9) << pCoor(9,2,-2);
  colors << 0xff0000;  
      pMatrix win_from_object = transform_construct(demo_frame_buffer);
        
          vector<pCoor> coors_window = homogenize( win_from_object * coors_os );
    
  if ( demo_frame_buffer.frame_count_get() == 1 )
    {
      pCoors_print(coors_os,"Obj");
      pCoors_print(coors_window,"Win");
    }
  const int win_width = demo_frame_buffer.width_get();
  auto ic = colors.begin();
  for ( auto it = coors_window.begin(); it != coors_window.end(); )
    {
                  pCoor w0 = *it++,  w1 = *it++,  w2 = *it++;
      uint32_t color = *ic++;
                              
      pVect v20(w2,w0), v21(w2,w1);
      const float db0 = 1/max(fabs(v20.x),fabs(v20.y));
      const float db1 = 1/max(fabs(v21.x),fabs(v21.y));
                              for ( float b0=0; b0<=1; b0 += db0 )
        for ( float b1=0; b1<=1-b0; b1 += db1 )
          {
            pCoor c = w2 + b0 * v20 + b1 * v21;
            demo_frame_buffer[ c.x + int(c.y) * win_width ] = color;
          }
    }
}
pMatrix
transform_construct(pFrame_Buffer& demo_frame_buffer)
{
      
      pCoor eye_location = pCoor(1,.5,10.2);
  pVect eye_direction = pVect(0,0,-1);
      const int win_width = demo_frame_buffer.width_get();
  const int win_height = demo_frame_buffer.height_get();
  const float aspect = 1.0 * win_width / win_height;
  const float width_m = 1.6;
  const float height_m = width_m / aspect;
      pMatrix_Translate center_eye(-eye_location);
  pMatrix_Rotation rotate_eye(eye_direction,pVect(0,0,-1));
  pMatrix eye_from_object = rotate_eye * center_eye;
      pMatrix_Frustum clip_from_eye
    ( -width_m/2, width_m/2,  -height_m/2, height_m/2,  1, 5000 );
  pMatrix clip_from_object = clip_from_eye * eye_from_object;
      pMatrix_Translate recenter(pVect(1,1,0));
  pMatrix_Scale scale( win_width/2, win_height/2, 1 );
  pMatrix win_from_clip = scale * recenter;
  pMatrix win_from_object = win_from_clip * clip_from_object;
  return win_from_object;
}
int
main(int argc, char **argv)
{
  pFrame_Buffer demo_frame_buffer(argc,argv);
  demo_frame_buffer.show(render);
  return 0;
}