///////////////////////////////////////////////////////////////////////////////
// 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.
///////////////////////////////////////////////////////////////////////////////


// le décalage signifis que l'indexation commence à 1 même en RAM.
// Le premier élément des tables correspond à l'èlèment nul.
// Nb - la logique de numérotation quand à elle commence avec m et n = 0.
// -----------------------------------------------------------------------
abstract class numerotation
    {
    public static int NULLINDEX  = 0 ;
    public static int INDEXATION = 0 ;
    public static int CREATION   = 1 ;
    public static int __Decal    = 1 ;

    int    m , n   ;
    int    UseMode ;  // Création ou indexation .

    public numerotation() { this(0,0); }
    public numerotation(int p_m, int p_n) { m = p_m ;
                                            n = p_n ;
                                            UseMode = INDEXATION ; }


             int CardinalSommet() { return m*n ; }
    abstract int CardinalArc   ();
    abstract int CardinalFace  ();

    abstract int Noeud (int i, int j);

    abstract int Arete1(int i, int j);

    abstract int Arete2(int i, int j);

             int Arete3(int i, int j) { return Arete1(i,j+1) ; }

             int Arete4(int i, int j) { return Arete2(i+1,j); }

    abstract int Face(int i, int j);

             int som1(int i, int j) { return Noeud(i,j); }

             int som2(int i, int j) { return Noeud(i+1,j); }

             int som3(int i, int j) { return Noeud(i,j+1); }

             int som4(int i, int j) { return Noeud(i+1,j+1); }
    }


class OuvertOuvert extends numerotation
    {
    public OuvertOuvert (){ super() ; }
    public OuvertOuvert ( int m, int n){ super(m,n) ; }

    int CardinalArc () { return m*(n+1) + n*(m+1); }
    int CardinalFace() { return n*m ; }

    int Noeud(int i, int j) { return j + i * ( n+1 ) + __Decal ; }

    int Arete1(int i, int j)
     { if ( UseMode == CREATION && (j > n || i == m) ) return NULLINDEX ;
       return j + n + i * ( 2*n + 1 ) + __Decal; }

    int Arete2(int i, int j)
     { if ( UseMode == CREATION && (i > m || j == n) ) return NULLINDEX ;
       return j + i * ( 2*n + 1 ) + __Decal; }

    int Face(int i, int j)
     { if ( UseMode == CREATION && (i == m || j == n) ) return NULLINDEX ;
       return Noeud(i,j)-i ; }

    } ;

class OuvertFerme extends numerotation
    {
    public OuvertFerme (){ super() ; }
    public OuvertFerme ( int m, int n){ super(m,n) ; }


    int CardinalArc () { return (2*m+1)*(n+1);}
    int CardinalFace() { return (n+1)*m; }

     int Noeud(int i, int j)
    { return (j!=n+1) ? (j + i * ( n+1 ) + __Decal) :
                        (i * ( n+1 )+ __Decal) ; }

     int Arete1(int i, int j)
    { if (UseMode == CREATION && ( j > n || i == m )) return NULLINDEX ;
      return (j!=n+1) ? (j + n + 1 + i * ( 2*n + 2 )+ __Decal) :
			               (n + 1 + i * ( 2*n + 2 )+ __Decal) ; }

     int Arete2(int i, int j)
    { if (UseMode == CREATION && (j > n || i > m ) ) return NULLINDEX ;
      return j + i * ( 2*n + 2 ) + __Decal; }

     int Face(int i, int j)
    { if (UseMode == CREATION && (j > n || i >= m) ) return NULLINDEX ;
      return Noeud(i,j); }

    }


class FermeOuvert extends numerotation
    {
    public FermeOuvert (){ super() ; }
    public FermeOuvert ( int m, int n){ super(m,n) ; }


    int CardinalArc () { return (m+1)*n + (m+1)*(n+1); }
    int CardinalFace() { return n*(m+1)       ; }

    int Noeud(int i, int j)
    { return (i!=m+1) ? (j + i * ( n+1 )+ __Decal) : (j+ __Decal) ; }

    int Arete1(int i, int j)
    { if (UseMode == CREATION && ( j > n || i > m ) ) return NULLINDEX ;
      return j + n + i * ( 2*n + 1 ) + __Decal; }

    int Arete2(int i, int j)
    { if (UseMode == CREATION && ( j == n || i > m ) ) return NULLINDEX ;
      return (i!=m+1) ? (j + i * ( 2*n + 1 )+ __Decal) : (j+ __Decal) ; }

    int Face(int i, int j)
    { if (UseMode == CREATION && (j == n || i > m ) ) return NULLINDEX ;
      return Noeud(i,j)-i; }

    }

class FermeFerme extends numerotation
    {
    public FermeFerme (){ super() ; }
    public FermeFerme ( int m, int n){ super(m,n) ; }


    int CardinalArc ()  { return (m+1)*(n+1)*2 ; }
    int CardinalFace()  { return (n+1)*(m+1)   ; }

    int Noeud(int i, int j)
    { return (j!=n+1)? ((i!=m+1)? (j + i * ( n+1 )+ __Decal):(j+ __Decal) ) :
		                 (i*(n+1)+ __Decal) ; }

    int Arete1(int i, int j)
    { if (UseMode == CREATION && (j >n || i > m ) ) return NULLINDEX ;
      return (j!=n+1) ? (j + n + 1 + i * 2 * (n+1) + __Decal) :
			               (n + 1 + i * 2 * (n+1) + __Decal) ; }

    int Arete2(int i, int j)
    { if (UseMode == CREATION && (j > n || i > m ) ) return NULLINDEX ;
      return (i!=m+1) ? (j + i * 2 * (n+1) + __Decal) : (j+ __Decal) ; }

    int Face(int i, int j)
    { if (UseMode == CREATION && (j > n || i > m ) ) return NULLINDEX ;
      return Noeud(i,j); }

    }

class OuvertOuvertOnAxisSup extends OuvertOuvert
    {
    public OuvertOuvertOnAxisSup (){ super() ; }
    public OuvertOuvertOnAxisSup ( int m, int n){ super(m,n) ; }

    int CardinalSommet () { return (m+1)*n + 1 ; }
    int CardinalArc    () { return m*n + n*(m+1);}

    int Noeud(int i, int j)
    { return (j==0)? CardinalSommet() : // __Decal est dejas implicite.
                     j - 1 + i * n + __Decal      ; }

    int Arete1(int i, int j)
    { if ( UseMode == CREATION && (j == 0 || j > n || i == m)) return NULLINDEX;
      return j + n - 1 + i * ( 2*n ) + __Decal; }

    int Arete2(int i, int j)
    { if ( UseMode == CREATION && (i > m || j == n) ) return NULLINDEX ;
      return j + i * ( 2*n ) + __Decal; }

    int som2(int i , int j)
    { return (j==0) ? som1(i,j) : Noeud(i+1,j) ; }

    }

class OuvertOuvertOnAxisInf extends OuvertOuvert
    {
    public OuvertOuvertOnAxisInf (){ super() ; }
    public OuvertOuvertOnAxisInf ( int m, int n){ super(m,n) ; }

    int CardinalSommet () { return (m+1)*n + 1 ; }
    int CardinalArc    () { return m*n + n*(m+1);}

    int Noeud(int i, int j)
    { return (j==n)? CardinalSommet() : // __Decal est dejas implicite.
		               j + i * n + __Decal      ; }

    int Arete1(int i, int j)
    { if ( UseMode == CREATION && (j == n || j > n || i == m)) return NULLINDEX;
      return j + n + i * ( 2*n ) + __Decal; }

    int Arete2(int i, int j)
    { if ( UseMode == CREATION && (i > m || j == n) ) return NULLINDEX ;
      return j + i * ( 2*n ) + __Decal; }


    int som4(int i , int j)
    { return (j==n) ? som3(i,j) : Noeud(i+1,j+1) ; }

    }

class OuvertOuvertOnAxisBoth extends OuvertOuvert
    {
    public OuvertOuvertOnAxisBoth (){ super() ; }
    public OuvertOuvertOnAxisBoth ( int m, int n){ super(m,n) ; }

    int CardinalSommet () { return (m+1)*(n-1)+2; }
    int CardinalArc    () { return (m+1)*n + m*(n-1); }

    int Noeud(int i, int j)
    { return (j==0)? CardinalSommet()-1 : // __Decal est dejas implicite.
		               ((j ==n)? CardinalSommet() : // Idem.
			                      j - 1 + i * ( n-1 ) + __Decal ) ; }

    int Arete1(int i, int j)
    { if ( UseMode == CREATION &&
	  (j == 0 || j == n || j > n || i == m) ) return NULLINDEX ;
      return j + (n-1) + i * ( 2 * n - 1 ) + __Decal; }

    int Arete2(int i, int j)
    { if ( UseMode == CREATION && (i > m || j == n) ) return NULLINDEX ;
      return j + i * ( 2*n-1 ) + __Decal; }

    int som2(int i , int j)
    { return (j==0) ? som1(i,j) : Noeud(i+1,j) ; }

    int som4(int i , int j)
    { return (j==n) ? som3(i,j) : Noeud(i+1,j+1) ; }

    }

class FermeOuvertOnAxisSup extends FermeOuvert
    {
    public FermeOuvertOnAxisSup (){ super() ; }
    public FermeOuvertOnAxisSup ( int m, int n){ super(m,n) ; }

    int CardinalSommet(){ return n*(m+1) + 1 ;}
    int CardinalArc   (){ return (m+1)*n*2; }

    int Noeud(int i, int j)
    { return (j==0)? CardinalSommet() :
	                 (i!=m+1) ? (j - 1 + i * n + __Decal) :
                               (j - 1 + __Decal) ; }

    int Arete1(int i, int j)
    { if (UseMode == CREATION && ( j ==0 || j > n || i > m ) ) return NULLINDEX ;
      return j + n - 1 + i * ( 2*n ) + __Decal; }

    int Arete2(int i, int j)
    { if (UseMode == CREATION && ( j == n || i > m ) ) return NULLINDEX ;
      return (i!=m+1) ? (j + i * ( 2*n )+ __Decal) : (j+ __Decal) ; }

    int som2(int i , int j)
    { return (j==0) ? som1(i,j) : Noeud(i+1,j) ; }

    }

class FermeOuvertOnAxisInf extends FermeOuvert
    {
    public FermeOuvertOnAxisInf (){ super() ; }
    public FermeOuvertOnAxisInf ( int m, int n){ super(m,n) ; }

    int CardinalSommet(){ return n*(m+1) + 1 ;}
    int CardinalArc   (){ return (m+1)*n*2; }

    int Noeud(int i, int j)
    { return (j==n)? CardinalSommet() :
	                  (i!=m+1) ? (j + i * n + __Decal) :
                                (j + __Decal) ; }

    int Arete1(int i, int j)
    { if (UseMode == CREATION && ( j ==n || j > n || i > m )) return NULLINDEX ;
      return j + n + i * ( 2*n ) + __Decal; }

    int Arete2(int i, int j)
    { if (UseMode == CREATION && ( j == n || i > m ) ) return NULLINDEX ;
      return (i!=m+1) ? (j + i * ( 2*n )+ __Decal) : (j+ __Decal) ; }

    int som4(int i , int j)
    { return (j==n) ? som3(i,j) : Noeud(i+1,j+1) ; }

    }

class FermeOuvertOnAxisBoth extends FermeOuvert
    {
    public FermeOuvertOnAxisBoth (){ super() ; }
    public FermeOuvertOnAxisBoth ( int m, int n){ super(m,n) ; }

    int CardinalSommet(){ return (m+1)*(n-1) +2 ; }
    int CardinalArc   (){ return (m+1)*n + (m+1)*(n-1); }

    int Noeud(int i, int j)
    { return (j==0)? CardinalSommet()-1 :
		               (j==n)? CardinalSommet() :
			                    (i!=m+1) ? (j - 1 + i * ( n - 1 )+ __Decal) :
					                         (j - 1 + __Decal) ; }

    int Arete1(int i, int j)
    { if (UseMode == CREATION &&
	       (j ==n || j == 0 || j > n || i > m ) ) return NULLINDEX ;
      return j + (n-1) + i * ( 2*n-1 ) + __Decal; }

    int Arete2(int i, int j)
    { if (UseMode == CREATION && ( j == n || i > m ) ) return NULLINDEX ;
      return (i!=m+1) ? (j + i * ( 2*n-1)+ __Decal) : (j+ __Decal) ; }

    int som2(int i , int j)
    { return (j==0) ? som1(i,j) : Noeud(i+1,j) ; }

    int som4(int i , int j)
    { return (j==n) ? som3(i,j) : Noeud(i+1,j+1) ; }

    }


