///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-1996 Virtual Design All Rights Reserved.
//
// Permission to use,  copy,  modify,  and  distribute  this  software and its
// documentation for NON-COMMERCIAL purposes and without fee is hereby granted.
//
// VIRTUAL DESIGN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
// OF THE SOFTWARE, EITHER EXPRESS  OR  IMPLIED,  INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// OR NON-INFRINGEMENT. VIRTUAL DESIGN SHALL  NOT  BE LIABLE FOR ANY DAMAGES
// SUFFERED BY  LICENSEE AS A RESULT OF USING,  MODIFYING OR DISTRIBUTING THIS
// SOFTWARE OR ITS DERIVATIVES.
//
// THIS SOFTWARE  IS   NOT  DESIGNED  OR  INTENDED FOR USE OR RESALE AS ONLINE
// OR NOT ONLINE CONTROL  EQUIPMENT IN HAZARDOUS  ENVIRONMENTS REQUIRING  FAIL-
// SAFE PERFORMANCE,  SUCH  AS  IN   THE   OPERATION   OF  NUCLEAR  FACILITIES,
// AIRCRAFT   NAVIGATION  OR  COMMUNICATION  SYSTEMS,  AIR   TRAFFIC   CONTROL,
// DIRECT LIFE  SUPPORT  MACHINES, OR WEAPONS SYSTEMS, IN  WHICH  THE  FAILURE
// OF  THE SOFTWARE COULD  LEAD DIRECTLY  TO DEATH, PERSONAL INJURY, OR SEVERE
// PHYSICAL OR ENVIRONMENTAL  DAMAGE ("HIGH RISK ACTIVITIES").  VIRTUAL DESIGN
// SPECIFICALLY DISCLAIMS  ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH
// RISK ACTIVITIES.
///////////////////////////////////////////////////////////////////////////////

/**
 * La classe de base des modeleurs.
 * @version Beta 1.0
 * @author  Guillaume Pelletier
 */

abstract class modeler {

  protected Vecteur3DH   m_axis   ;
  protected Sommet3DH [] m_profil ;
  protected int          m_pas    ;


  modeler ( Vecteur3DH   p_axis  ,
            Sommet3DH [] p_profil,
            int          p_pas   )
            {
            m_axis   = p_axis   ;
            m_profil = p_profil ;
            m_pas    = p_pas    ;
            }


  abstract GenerateType generateVertex( Maillage3DH p_mesh ) ;

  void generateArc( Maillage3DH p_mesh , numerotation p_num )
   {
   int l_i, l_j , l_arc ;

   p_mesh.m_arcs = new ArcD[ p_num.CardinalArc() ] ;

   p_num.UseMode =  numerotation.CREATION ;

   for ( l_i = 0 ; l_i <= p_num.m ; l_i ++ )
       {
       for ( l_j = 0 ; l_j <= p_num.n ; l_j ++ )
	        {
           l_arc = p_num.Arete2(l_i,l_j) ;


           if ( l_arc != numerotation.NULLINDEX )
              {
              p_mesh.m_arcs[ l_arc - numerotation.__Decal ] =
              new ArcD(p_num.som1(l_i,l_j), p_num.som3(l_i,l_j)) ;
              }

           l_arc = p_num.Arete1(l_i,l_j) ;
	        if ( l_arc != numerotation.NULLINDEX )
              {
              p_mesh.m_arcs[ l_arc-numerotation.__Decal  ] =
              new ArcD( p_num.som1(l_i,l_j), p_num.som2(l_i,l_j)) ;
              }
	        }
       }
    }

  void generateFace( Maillage3DH p_mesh, numerotation p_num )
   {
   int l_i, l_j , l_face ;

   p_mesh.m_faces = new Face[ p_num.CardinalFace() ] ;

   for ( l_i = 0 ; l_i <= p_num.m ; l_i ++ )
       {
       for ( l_j = 0 ; l_j <= p_num.n ; l_j ++ )
	        {
	        p_num.UseMode = numerotation.CREATION ;
           l_face = p_num.Face(l_i,l_j);

           if ( p_num.Face(l_i,l_j)!= numerotation.NULLINDEX )
              {
	           p_num.UseMode = numerotation.INDEXATION ;

              // le cas d'une facette triangulaire supérieure
	           if ( p_num.som1(l_i,l_j) == p_num.som2(l_i,l_j) )
                 {
                 p_mesh.m_faces[ l_face-numerotation.__Decal] =
                 new FaceT( p_num.Arete2(l_i,l_j),
                            p_num.Arete3(l_i,l_j),
                            p_num.Arete4(l_i,l_j)) ;
                 continue ;
                 }

              // le cas d'une facette triangulaire inférieure
	           if ( p_num.som3(l_i,l_j) == p_num.som4(l_i,l_j) )
                 {
                 p_mesh.m_faces[ l_face-numerotation.__Decal] =
                 new FaceT( p_num.Arete1(l_i,l_j),
                            p_num.Arete2(l_i,l_j),
                            p_num.Arete4(l_i,l_j)) ;

                 continue ;
                 }

              // le cas d'une facette carrée.
              p_mesh.m_faces[ l_face-numerotation.__Decal] =
              new FaceC( p_num.Arete1(l_i,l_j),
                         p_num.Arete2(l_i,l_j),
                         p_num.Arete3(l_i,l_j),
                         p_num.Arete4(l_i,l_j)) ;
	           }
           } // end for j
         } // end for i
   }



  public void generate( Maillage3DH p_mesh )
   {
   GenerateType l_type   ; // ref sur un objet
   numerotation l_num    ; // ref sur un objet

   l_type = generateVertex( p_mesh) ;

   l_num  = allocNumerotation( l_type ) ;

   generateArc ( p_mesh  , l_num ) ;
   //generateFace( p_mesh, l_num ) ;
   }


  numerotation allocNumerotation( GenerateType p_type )
   {
   if ( p_type.m_phor == GenerateType.HOR_CLOSE )
     {
     // ici le profil est fermé horizontalement
     if ( p_type.m_pvert == GenerateType.VERT_OPEN )
        {
        // ici le profil est férmé horizontalement et ouvert horizontalement
        if ( p_type.m_ponaxis == GenerateType.EXTR_BOTH )
           return new FermeOuvertOnAxisBoth(m_pas-1,m_profil.length-1) ;

        if ( p_type.m_ponaxis == GenerateType.EXTR_SUP  )
           return new FermeOuvertOnAxisSup(m_pas-1,m_profil.length-1)  ;

        if ( p_type.m_ponaxis == GenerateType.EXTR_INF  )
           return new FermeOuvertOnAxisInf(m_pas-1,m_profil.length-1)  ;

        return new FermeOuvert(m_pas-1,m_profil.length-1);
        }
     return new FermeFerme(m_pas-1,m_profil.length-2);
     }

   // ici le profil est ouvert horizontalement

   if ( p_type.m_pvert == GenerateType.VERT_CLOSE )
      // ici le profil est ouvert horizontalement et fermé verticalement
      return new OuvertFerme(m_pas-1,m_profil.length-2) ;

   // ici le profil est ouvert horizontalement et ouvert verticalement
   if ( p_type.m_ponaxis == GenerateType.EXTR_BOTH )
      return new OuvertOuvertOnAxisBoth(m_pas-1,m_profil.length-1) ;

   if ( p_type.m_ponaxis == GenerateType.EXTR_SUP  )
      return new OuvertOuvertOnAxisSup(m_pas-1,m_profil.length-1)  ;

   if ( p_type.m_ponaxis == GenerateType.EXTR_INF  )
      return new OuvertOuvertOnAxisInf(m_pas-1,m_profil.length-1)  ;

   return new OuvertOuvert(m_pas-1,m_profil.length-1)	   ;
   }

  }


/**
 * La classe des modeleurs de translation.
 * @version Beta 1.0
 * @author  Guillaume Pelletier
 */

class modelerTrans extends modeler {

  public modelerTrans( Vecteur3DH   p_axis  ,
                       Sommet3DH [] p_profil,
                       int          p_pas   )
                     { super(p_axis, p_profil, p_pas) ; }


  GenerateType generateVertex( Maillage3DH p_mesh )
   {
   GenerateType l_type = new GenerateType();

   modtrans l_model = new modtrans() ;

   l_model.GenerateVertex( m_profil,
			                  p_mesh  ,
			                  l_type  ,
			                  m_axis  ,
			                  m_pas   );

   return l_type ;
   }

  }



/**
 * La classe des modeleurs de rotation avec passage de profil.
 * @version Beta 1.0
 * @author  Guillaume Pelletier
 */

class modelerRotatePToP extends modeler {

  float       m_angle   ;
  Sommet3DH[] m_profil1 ;

  public modelerRotatePToP( Vecteur3DH   p_axis   ,
                            Sommet3DH [] p_profil ,
                            Sommet3DH [] p_profil1,
                            float        p_angle  ,
                            int          p_pas    )
                          { super(p_axis, p_profil, p_pas) ;
                            m_angle = p_angle ;
                            m_profil1 = p_profil1 ;}


  GenerateType generateVertex( Maillage3DH p_mesh )
   {
   int l_error ;
   GenerateType l_type = new GenerateType();

   modrot l_model = new modrot() ;

   if ( (l_error = l_model.GenerateVertex( m_profil ,
                                           m_profil1,
			                                  p_mesh   ,
			                                  l_type   ,
			                                  m_angle  ,
			                                  m_pas    )) != modrot.SUCCESS )
   {
   System.out.println( "Erreur du modeleur de rotation " + l_error ) ;
   }

   return l_type ;
   }

  }

/**
 * La classe des modeleurs de rotation sans passage de profil.
 * @version Beta 1.0
 * @author  Guillaume Pelletier
 */

class modelerRotate extends  modelerRotatePToP {

  public modelerRotate( Vecteur3DH   p_axis  ,
                        Sommet3DH [] p_profil,
                        float        p_angle ,
                        int          p_pas   )
                      { super(p_axis, p_profil, p_profil , p_angle, p_pas);}


  }
