/* ../xa/ut_patch.c
 *
 * Copyright (C) 2017 CADCAM-Services Franz Reiter (franz.reiter@cadcam.co.at)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *
-----------------------------------------------------
TODO:
-----------------------------------------------------
Modifications:

-----------------------------------------------------
*/
#ifdef globTag
void UPAT(){}
#endif
/*!
\file  ../ut/ut_geo3d.c
\brief 3D geometric point vector line circle 
\code
=====================================================
List_functions_start:

UPAT_ipatch_disp_opts     display indexed-Opengl-patch

List_functions_end:
=====================================================
UTRI_triaNr_patch         get nr of triangles of indexed-Opengl-patch

\endcode *//*----------------------------------------








*/


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <GL/gl.h>                     // GL_TRIANGLES

#include "../ut/ut_geo.h"
#include "../ut/ut_memTab.h"           // MemTab_..
#include "../ut/ut_itmsh.h"            // MSHIG_EDGLN_.. typedef_MemTab.. Fac3
#include "../ut/ut_txt.h"              // UTX_find_chr




//================================================================
  int UPAT_ipatch_disp_opts (int gTyp, int iNr, int *ia, Point *pa,
                             int iOff, char *opts, long dbi) {
//================================================================
// display indexed-Opengl-patch
// Input:
//   iNr      nr of point-indices in ia
//   iOff     display faceNr in gravity-centerPoint; -1=none
//            iOff is added
//   opts v   disp normalvector in gravity-centerPoint
//        b   disp bounds
//        s   disp triangle shaded
//   dbi    0L   do not use DispList (write into open DispList)
//         -1L   use dynamic DispList
//         >=1   use/overwrite existing DispList
//
// see MSH_test_disp_f1


  int      irc, tNr, ii, iBnd, iVc, iTx, iVT;
  long     dli;
  char     s1[40];
  Point    ptt[4], pgc;
  Vector   vcn;
  // Fac3   *fa;
  Triangle *ta;


  printf("UPAT_ipatch_disp_opts %d |%s|\n",iOff,opts);


  if(dbi) {
    if(dbi > 0) {
      DL_SetInd (dbi);
    }
    dli = DL_StoreObj (Typ_GL_Sur, dbi, Typ_Att_Fac1);
    GL_Draw_Ini (&dli, Typ_Att_Fac1);  // init cv/surf, glNewList < GL_fix_DL_ind
  }



  //----------------------------------------------------------------
  // Must display surface before boundary.
  if(!strchr(opts, 's') ) goto L_bvi;
    // display shaded triangles
    GL_att_su (ATT_COL_GREEN);
    GL_Disp_ipatch (gTyp, iNr, ia, pa);
    // GL_Disp_patch (gTyp, tNr, ta);
    // // GL_Disp_ntria (ta, tNr);


  //----------------------------------------------------------------
  L_bvi:

  // get nr of indexed-triangles for indexed-Opengl-patch
  // fNr = UTRI_triaNr_patch (iNr, gTyp);
    // printf(" fNr=%d\n",fNr);
  tNr = UTRI_triaNr_patch (iNr, gTyp);
    printf(" tNr=%d\n",tNr);

  // get memSpc for indexed-triangles
  // fa = (Fac3*) MEM_alloc_tmp (fNr * sizeof(Fac3));
  ta = (Triangle*) MEM_alloc_tmp (tNr * sizeof(Triangle));

  // get indexed-triangles from indexed-Opengl-patch
  // irc = UFA_nfac_ipatch  (fa, &fNr, gTyp, iNr, ia);
  // if(irc < 0) return -1;
  irc = UTRI_ntria_ipatch  (ta, &tNr, gTyp, iNr, ia, pa);
  if(irc < 0) return -1;
    printf(" irc=%d tNr=%d\n",irc,tNr);


  iBnd = UTX_find_chr(opts, 'b');  // find character in string; 0=no, 1=yes
  iVc = UTX_find_chr(opts, 'v');
  // iTx = UTX_find_chr(opts, 'i');
  iTx = (iOff >= 0) ? 1 : 0; // (opts, 'i');
  iVT = iVc + iTx;
    printf(" iBnd=%d iVc=%d iTx=%d\n",iBnd,iVc,iTx);



  // loop tru triangles ta
  for(ii=0; ii<tNr; ++ii) {
    // make polygon from Triangle
    UT3D_npt_tria (ptt, &ta[ii]);

    //----------------------------------------------------------------
    // display boundary as polygon
    if(iBnd) {
      // set display-attributes for curves
      GL_att_cv (Typ_Att_hili1);
      GL_Disp_cv (4, ptt);
    }


    if(!iVT) continue;

    // get pgc = gravity-centerPoint of triangle
    UT3D_pt_gcp_3pt (&pgc, &ptt[0], &ptt[1], &ptt[2]);
      // GL_att_pt (ATT_PT_YELLOW);  // glPointSize, color ..
      // GL_Disp_npt (&pgc, 1);

    // vector normal to 3 points in pgc
    if(iVc) {
      UT3D_vc_perp3pt (&vcn, &ptt[0], &ptt[1], &ptt[2]);
      // UT3D_vc_setLength (&vcn, &vcn, 1.);
        UT3D_stru_dump (Typ_VC, &vcn, " vcn: ");
      // display vector in gravity-centerPoint
      // GL_Disp_vSym (SYM_ARROW, &pgc, &vcn, 10., 0); //ATT_COL_HILI);
      GL_Disp_vc (&vcn, &pgc, ATT_COL_CYAN);
    }


    // display faceNr in pgc
    if(iOff >= 0) {
      sprintf(s1,"%d",iOff + ii);
      GL_Disp_txtA (&pgc, s1);
    }

  }


  //----------------------------------------------------------------
  L_done:
  if(dbi) {
    GL_EndList ();     // glEndList
  }

  return 0;

}


//=====================================================================
  int UTRI_ntria_ipatch  (Triangle *tTab, int *nt,
                          int pTyp, int ptNr, int *iTab, Point *pTab) {
//=====================================================================
/// \code
/// get triangles from indexed-Opengl-patch
/// Output:
///   nt       nr of triangles in tTab
///   tTab     triangles out; SIZE MUST BE >= UTRI_triaNr_patch()
///
/// see also:
/// UTRI_triaNr_patch          get nr of triangles for [indexed-]opengl-patch
/// TSU_nfac_ipatch
/// \endcode


  int       ii, tNr;
  Triangle  *tr1 = tTab;

  printf("UTRI_ntria_ipatch nt=%d pTyp=%d ptNr=%d\n",*nt,pTyp,ptNr);


  ii = 0;

  switch (pTyp) {

    //================================================================
    case GL_TRIANGLES:  // 4

      tNr = ptNr / 3;           // total nr of triangles
      if(tNr > *nt) goto L_errEOM;

      L_T0:
        tr1->pa[0] = &pTab[*iTab];  ++iTab;
        tr1->pa[1] = &pTab[*iTab];  ++iTab;
        tr1->pa[2] = &pTab[*iTab];  ++iTab;
        ++tr1;
        ++ii;
        if(ii < tNr) goto L_T0;

      break;

    //================================================================
    default:
      TX_Error("UTRI_ntria_ipatch E001 %d",pTyp);
      return -1;

  }


  *nt = tNr;




  return 0;


  L_errEOM:
    TX_Error("UTRI_ntria_ipatch EOM");
    return -1;



}


// EOF
