#include "jv.h"
#include "tsai.h"
#include "model.h"
#include "funcoes_reta.h"
#include "stdio.h"

static float cores[16][3] =   {
                                 { 1.00f, 0.00f, 0.00f }, //  0 - vermelho
                                 { 0.00f, 1.00f, 0.00f }, //  1 - verde
                                 { 0.00f, 0.00f, 1.00f }, //  2 - azul
                                 { 1.00f, 1.00f, 0.00f }, //  3 - amarelo
                                 { 1.00f, 0.00f, 1.00f }, //  4 - lilas
                                 { 0.00f, 1.00f, 1.00f }, //  5 - ciano
                                 { 1.00f, 0.50f, 0.00f }, //  6 - laranja
                                 { 1.00f, 0.00f, 0.50f }, //  7 - magenta
                                 { 0.50f, 0.00f, 0.00f }, //  8 - vinho
                                 { 0.00f, 0.50f, 0.00f }, //  9 - verde escuro
                                 { 0.00f, 0.00f, 0.50f }, // 10 - azul escuro
                                 { 0.50f, 0.50f, 0.00f }, // 11 - roxo
                                 { 0.50f, 0.00f, 0.50f }, // 12 - amarelo escuro
                                 { 0.00f, 0.50f, 0.50f }, // 13 - azul feio
                                 { 0.50f, 0.25f, 0.00f }, // 14 - marron
                                 { 0.50f, 0.00f, 0.25f }  // 15 - magenta escuro
                              } ;


void create_img_ideal_interpretation( Model model, jvLine *ideal_interp, float w, float h )
{
   int l;
   for( l=0;l<model->n_lines; l++)
   {
      ideal_interp[l].v1x = ((model->lines[l].v1x / model->max_x) * w *.8f ) + w*.1f ;
      ideal_interp[l].v2x = ((model->lines[l].v2x / model->max_x) * w *.8f ) + w*.1f ;
      ideal_interp[l].v1y = ((model->lines[l].v1y / model->max_x) * h *.8f ) + h*.1f ;
      ideal_interp[l].v2y = ((model->lines[l].v2y / model->max_x) * h *.8f ) + h*.1f ;
      ideal_interp[l].valid=1;
   }
}


int razao_segmentos( jvLine *lines, int l_a, int lim_a1, int lim_a2, int l_b, int lim_b1, int lim_b2, float *r )
{
   jvLine LA, LB ;
   float x, y ;

   int valid = 1 ;

   valid &= intersecao( lines[l_a], lines[lim_a1], &x, &y ) ;
   LA.v1x = x ;
   LA.v1y = y ;
   valid &= intersecao( lines[l_a], lines[lim_a2], &x, &y ) ;
   LA.v2x = x ;
   LA.v2y = y ;

   valid &= intersecao( lines[l_b], lines[lim_b1], &x, &y ) ;
   LB.v1x = x ;
   LB.v1y = y ;
   valid &= intersecao( lines[l_b], lines[lim_b2], &x, &y ) ;
   LB.v2x = x ;
   LB.v2y = y ;

   if( !valid )
      return 0 ;


   *r = razao( LA, LB ) ;

   return 1 ;

}



void inverseOfGrayImage( int height, int width, const unsigned char *img_rgb_in, unsigned char *img_gray_out )
{
   int h, w ;

   unsigned int dim = (unsigned int)height * (unsigned int)width ;


   for( h=0 ; h<height ; h++ )
   {
      for( w=0 ; w<width ; w++ )
      {
         img_gray_out[ h*width+w ] = 255-((unsigned char)( 0.2126f*img_rgb_in[ h*width+w ] + 0.7152f*img_rgb_in[ dim +h*width+w ]+ 0.0722f*img_rgb_in[2*dim+ h*width+w ] )) ;
      }
   }
}




int generatePairs( jvLine *lines_in, Model mdl, jvPoint2D *pnts_line_in, jvPoint2D *pnts_line_mdl )
{
   int la, lb ;
   int n_pnts = 0 ;

   for( la=0 ; la<mdl->n_lines ; la++ )
   {
      for( lb=la+1 ; lb<mdl->n_lines ; lb++ )
      {
         if( lines_in[la].valid && lines_in[lb].valid )
         {
            if( mdl->vertexType[la][lb] )
            {
               intersecao( lines_in[la], lines_in[lb], &(pnts_line_in[n_pnts].x), &(pnts_line_in[n_pnts].y) ) ;
               pnts_line_mdl[n_pnts].x = mdl->interseptions[la][lb].x ;
               pnts_line_mdl[n_pnts].y = mdl->interseptions[la][lb].y ;
               n_pnts ++ ;
            }
         }
      }
   }
   return n_pnts ;
}

int correctPoints( float *h_matrix, Model mdl, jvPoint2D *model_pnts_projected )
{
   int la, lb ;
   int n_pnts = 0 ;
   for( la=0 ; la<mdl->n_lines ; la++ )
   {
      for( lb=la+1 ; lb<mdl->n_lines ; lb++ )
      {
         if( mdl->vertexType[la][lb] )
         {
            float x_mdl, y_mdl  ;
            float x_prj, y_prj, w_prj  ;

            x_mdl = mdl->interseptions[la][lb].x ;
            y_mdl = mdl->interseptions[la][lb].y ;

            x_prj =  h_matrix[0]*x_mdl +
                     h_matrix[1]*y_mdl +
                     h_matrix[2] ;


            y_prj =  h_matrix[3]*x_mdl+
                     h_matrix[4]*y_mdl +
                     h_matrix[5] ;

            w_prj =  h_matrix[6]*x_mdl +
                     h_matrix[7]*y_mdl +
                     h_matrix[8] ;

            model_pnts_projected[n_pnts].x = x_prj / w_prj ;
            model_pnts_projected[n_pnts].y = y_prj / w_prj ;

            n_pnts ++ ;
         }
      }
   }

   return n_pnts ;
}


int correctPoints2( float *h_matrix, int np, jvPoint2D *model_pnts, jvPoint2D *model_pnts_projected )
{
   int l ;
   for( l=0 ; l < np  ; l++ )
   {
      float x_mdl, y_mdl  ;
      float x_prj, y_prj, w_prj  ;

      x_mdl = model_pnts[l].x ;
      y_mdl = model_pnts[l].y ;

      x_prj =  h_matrix[0]*x_mdl +
               h_matrix[1]*y_mdl +
               h_matrix[2] ;


      y_prj =  h_matrix[3]*x_mdl+
               h_matrix[4]*y_mdl +
               h_matrix[5] ;

      w_prj =  h_matrix[6]*x_mdl +
               h_matrix[7]*y_mdl +
               h_matrix[8] ;

      model_pnts_projected[l].x = x_prj / w_prj ;
      model_pnts_projected[l].y = y_prj / w_prj ;
   }

   return np ;
}



void correctLines ( float *h_matrix, Model mdl, jvLine *model_lines_projected )
{
   int l ;
   for( l=0 ; l<mdl->n_lines ; l++ )
   {
      float x_mdl, y_mdl  ;
      float x_prj, y_prj, w_prj  ;

      x_mdl = mdl->lines[l].v1x ;
      y_mdl = mdl->lines[l].v1y ;

      x_prj =  h_matrix[0]*x_mdl +
               h_matrix[1]*y_mdl +
               h_matrix[2] ;


      y_prj =  h_matrix[3]*x_mdl+
               h_matrix[4]*y_mdl +
               h_matrix[5] ;

      w_prj =  h_matrix[6]*x_mdl +
               h_matrix[7]*y_mdl +
               h_matrix[8] ;

      model_lines_projected[l].v1x = x_prj / w_prj ;
      model_lines_projected[l].v1y = y_prj / w_prj ;


      x_mdl = mdl->lines[l].v2x ;
      y_mdl = mdl->lines[l].v2y ;

      x_prj =  h_matrix[0]*x_mdl +
               h_matrix[1]*y_mdl +
               h_matrix[2] ;


      y_prj =  h_matrix[3]*x_mdl+
               h_matrix[4]*y_mdl +
               h_matrix[5] ;

      w_prj =  h_matrix[6]*x_mdl +
               h_matrix[7]*y_mdl +
               h_matrix[8] ;

      model_lines_projected[l].v2x = x_prj / w_prj ;
      model_lines_projected[l].v2y = y_prj / w_prj ;
   }
}

void  convertPoints( int n_pnts, jvPoint2D* pnts_mdl, jvPoint2D* pnts_img, float *mdl_xs, float *mdl_ys, float *img_xs, float *img_ys, float w_window, float h_window ) 
{
   int p ;
   for( p=0 ; p<n_pnts ; p++ )
   {
      mdl_xs[p] = pnts_mdl[p].x ;
      mdl_ys[p] = pnts_mdl[p].y ;
      img_xs[p] = pnts_img[p].x - w_window/2.0f ;
      img_ys[p] = pnts_img[p].y - h_window/2.0f  ;
   }
}



