#include "model.h"
#include "stdlib.h"
#include "funcoes_reta.h"
#include "stdio.h"


void  copyLine( jvLine * dst, jvLine *src )
{
   dst->v1x   = src->v1x   ;
   dst->v1y   = src->v1y   ;
   dst->v2x   = src->v2x   ;
   dst->v2y   = src->v2y   ;
   dst->valid = src->valid ;
}

//===========================================================================//
// Extrai do modelo as informacoes que serao usada para a restricao, a       //
// homografia e a geração dos pontos na imagem                               //
void extract_model_infos( Model mdl )
{
   int la, lb ;

   float x, y ;

   mdl->min_x = mdl->max_x = mdl->lines[0].v1x ;
   mdl->min_y = mdl->max_y = mdl->lines[0].v1y ;

   for( la=0 ; la < mdl->n_lines ; la++ )
   {
      for( lb=la ; lb < mdl->n_lines ; lb++ )
      {
         if( la == lb )
         {
            mdl->vertexType[la][lb] = NOT_A_VERTEX ;
         }
         else
         {
            if( intersecao( mdl->lines[la], mdl->lines[lb], &x, &y ) )
            {
               mdl->interseptions[la][lb].x = x ;
               mdl->interseptions[lb][la].x = x ;

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

               if( cruzando( mdl->lines[la], mdl->lines[lb] ) )
               {
                  mdl->vertexType[la][lb] = SEGMENT_INTERSEPTION ;
                  mdl->vertexType[lb][la] = SEGMENT_INTERSEPTION ;
               }
               else
               {
                  mdl->vertexType[la][lb] = LINE_INTERSEPTION ;
                  mdl->vertexType[lb][la] = LINE_INTERSEPTION ;
               }
            }
            else
            {
               mdl->vertexType[la][lb] = NOT_A_VERTEX ;
               mdl->vertexType[lb][la] = NOT_A_VERTEX ;
            }
         }
      }

      if( mdl->lines[la].v1x < mdl->min_x )
      {
         mdl->min_x = mdl->lines[la].v1x ;
      }
      else
      if( mdl->lines[la].v1x > mdl->max_x )
      {
         mdl->max_x = mdl->lines[la].v1x ;
      }

      if( mdl->lines[la].v2x < mdl->min_x )
      {
         mdl->min_x = mdl->lines[la].v2x ;
      }
      else
      if( mdl->lines[la].v2x > mdl->max_x )
      {
         mdl->max_x = mdl->lines[la].v2x ;
      }

      if( mdl->lines[la].v1y < mdl->min_y)
      {
         mdl->min_y = mdl->lines[la].v1y ;
      }
      else
      if( mdl->lines[la].v1y > mdl->max_y )
      {
         mdl->max_y = mdl->lines[la].v1y ;
      }

      if( mdl->lines[la].v2y < mdl->min_y )
      {
         mdl->min_y = mdl->lines[la].v2y ;
      }
      else
      if( mdl->lines[la].v2y > mdl->max_y )
      {
         mdl->max_y = mdl->lines[la].v2y ;
      }
   }
}











//===========================================================================//
// Libera memoria usada para guardar as informacoes do modelo                //
void destroy_model( Model *mdl )
{
   free( (*mdl) ) ;

   (*mdl) = NULL ;
}
//===========================================================================//
// Aloca memoria para guardar as informacoes do modelo                       //
Model create_model( char *file_name )
{
   FILE  *mdl_file ;
   Model  mdl ;
   int    l ;

   // File
   mdl_file = fopen( file_name, "rt" ) ;
   if( !mdl_file )
      return NULL ;

   // Information about number of lines is crucial
   if( fscanf( mdl_file, "%d", &l ) != 1 )
   {
      fclose( mdl_file ) ;
      return NULL ;
   }

   // Model
   mdl = (Model) malloc( sizeof ( struct model_st ) ) ;
   if( !mdl )
   {
      fclose( mdl_file ) ;
      return NULL ;
   }

   mdl->n_lines = l ;

   for( l=0 ; l< mdl->n_lines ; l++ )
   {
      if( fscanf( mdl_file, "%f%f%f%f", &(mdl->lines[l].v1x), &(mdl->lines[l].v1y), &(mdl->lines[l].v2x), &(mdl->lines[l].v2y)) !=4 )
      {
         fclose( mdl_file ) ;
         destroy_model( &mdl ) ;
         return NULL ;
      }
   }

   fclose( mdl_file ) ;

   extract_model_infos( mdl ) ;

   return mdl ;
}



// Extrai do modelo as informacoes que serao usada para a restricao, a       //
// homografia e a geração dos pontos na imagem                               //
void print_model( Model mdl )
{
   /*
   int ir = 0 ,
       vm = 0 ,
       w, z ;

   FILE *fp = fopen( "infos.txt", "wt" );
 
   for( ir=0 ; ir < inf_mdl->n_intersecoes_retas ; ir++ )
   {

      fprintf( fp, "%3d %3d  %8.3f %8.3f\n", 
            inf_mdl->intersecao_retas[ir].i_linha_1,
            inf_mdl->intersecao_retas[ir].i_linha_2,
            inf_mdl->intersecao_retas[ir].x, 
            inf_mdl->intersecao_retas[ir].y ) ;
   }
    fprintf( fp, "\n\n\n\n" ) ;
   for( vm=0 ; vm < inf_mdl->n_vertices_modelo ; vm++ )
   {

      fprintf( fp, "%3d %3d  %8.3f %8.3f\n", 
            inf_mdl->vertices_modelo[vm].i_linha_1,
            inf_mdl->vertices_modelo[vm].i_linha_2,
            inf_mdl->vertices_modelo[vm].x, 
            inf_mdl->vertices_modelo[vm].y ) ;
   }

   fprintf( fp, "\n\n\n\n" ) ;

   fprintf( fp, "    " ) ;
   for( z=0 ; z < inf_mdl->n_linhas_mdl ; z++ )
   {
      fprintf( fp, "   %2d  ", z ) ;
   }
   fprintf( fp, " \n   -") ;

   for( w=0 ; w < inf_mdl->n_linhas_mdl ; w++ )
   {
      fprintf( fp, "|------", inf_mdl->nao_pode_cruzar[w][z] ) ;
   }
   fprintf( fp, "|\n", z ) ;

   for( z=0 ; z < inf_mdl->n_linhas_mdl ; z++ )
   {
      fprintf( fp, "%2d  ", z ) ;
      for( w=0 ; w < inf_mdl->n_linhas_mdl ; w++ )
      {
         fprintf( fp, "|  %2d  ", inf_mdl->nao_pode_cruzar[w][z] ) ;
      }
      fprintf( fp, "|\n   -") ;
      for( w=0 ; w < inf_mdl->n_linhas_mdl ; w++ )
      {
         fprintf( fp, "|------", inf_mdl->nao_pode_cruzar[w][z] ) ;
      }
      fprintf( fp, "|\n", z ) ;
   }
   fclose(fp);
   */
}











/*
unsigned char inter_transposta[200] ;
int nao_pode_cruzar[15][15] = 
{
//  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14  
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, //  0
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, //  1
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, //  2
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, //  3
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, //  4
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, //  5
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, //  6
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, //  7
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, //  8
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, //  9
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, // 10
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, // 11
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1 }, // 12
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, // 13
   {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }  // 14
};

void init_restricao( void )
{
   nao_pode_cruzar[0][1] = 1 ;
   nao_pode_cruzar[0][9] = 1 ;
   nao_pode_cruzar[0][11] = 1 ;
   nao_pode_cruzar[2][11] = 1 ;
   nao_pode_cruzar[4][3] = 1 ;
   nao_pode_cruzar[4][1] = 1 ;
   nao_pode_cruzar[6][9] = 1 ;
   nao_pode_cruzar[6][11] = 1 ;
   nao_pode_cruzar[8][1] = 1 ;
   nao_pode_cruzar[8][3] = 1 ;
   nao_pode_cruzar[10][1] = 1 ;
   nao_pode_cruzar[10][11] = 1 ;
   nao_pode_cruzar[1][0] = 1 ;
   nao_pode_cruzar[9][0] = 1 ;
   nao_pode_cruzar[11][0] = 1 ;
   nao_pode_cruzar[11][2] = 1 ;
   nao_pode_cruzar[3][4] = 1 ;
   nao_pode_cruzar[1][4] = 1 ;
   nao_pode_cruzar[9][6] = 1 ;
   nao_pode_cruzar[11][6] = 1 ;
   nao_pode_cruzar[1][8] = 1 ;
   nao_pode_cruzar[3][8] = 1 ;
   nao_pode_cruzar[1][10] = 1 ;
   nao_pode_cruzar[11][10] =1 ;
}

int  funcao_restricao_gattass( int nlines_img,
                        jvLine* lines_img,
                        int nlines_mdl,
                        jvLine* lines_mdl,
                        unsigned char* current_interpretation ) 
{
   int i, j ;
   int linha_modelo =0;

   // Monta a matriz tranposta para 0( n_linhas_modelo ^2 ) 
   for( i=0 ; i<nlines_img ; i++ )
   {
      int linha_modelo = current_interpretation[ i ] ;
      if(  linha_modelo != 255 )
      {
         inter_transposta[ linha_modelo ] = i ;
      }
   }


   for( i=0 ; i<nlines_mdl ; i++ )
   {
      for( j=0 ; j<nlines_mdl ; j++ )

      // Se o modelo diz q nao podem se cruzar entao confere pra ver se 
      // na imagem violam e se cruzam. 
      if( !nao_pode_cruzar[ i ][ i ] ) 
      {
         if( cruzando( lines_img[ inter_transposta[ i ] ],  lines_img[ inter_transposta[ j ] ]   ) )
         {
            return 0 ;
         }
      }
   }
   return 1 ;
}
*/