/*----------------------------------------------------------------------*/
/*  GroupGraph -- holds the following information:
        1. the possible orientations of the solid
        2. how to move from one orientation to another
        3. which orientations have the same top face
        4. the minimal number of rotations from the starting position 
            for each orientation
        5. which blank face is equivalent to the top face for each 
            orientation
     All the information is read in from a *G.dat file
                                                                        */ 
/*----------------------------------------------------------------------*/
/*             Jim Morey  -  morey@math.ubc.ca  -  Jan 28,1996          */
/*----------------------------------------------------------------------*/
  
import java.io.*;
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.lang.*;
import Solid;

/*----------------------------------------------------------------------*/

class GroupGraph{
  public Omatrix element[],tilt;
  public int[] arrows[],minRot,blank,smallestFace;
  public int pos,ngen,nelement;

  GroupGraph(InputStream is) throws IOException{
    String str, name, thing;
    int count, geni;
    Omatrix tmp,tmp2,gen[];

    pos = 0;

    StreamTokenizer token = new StreamTokenizer(is);
    token.eolIsSignificant(false);
    token.commentChar('#');
    tmp = new Omatrix();
    tmp2 = new Omatrix();

    /* .. get the info .. */
    /* .. get tilt -- so that more faces can be seen .. */
    token.nextToken();
    tmp.Rotation(0,1,token.nval);
    token.nextToken();
    tmp2.Rotation(1,2,token.nval);
    tmp2 = tmp2.Times(tmp);
    token.nextToken();
    tmp.Rotation(0,1,token.nval);
    tilt = tmp.Times(tmp2);

    /* .. get generating matrices .. */
    token.nextToken();
    nelement = (int)token.nval;
    gen = new Omatrix[nelement];
    for (int i=0;i<nelement;i++){
      gen[i] = new Omatrix();
      for (int j=0;j<3;j++){
        for (int k=0;k<3;k++){
          token.nextToken();
          gen[i].M[j][k] = token.nval;
        }
      }
    }

    token.nextToken();
    nelement = (int)token.nval;

    /* .. get each of the nelement orientations .. */
    element = new Omatrix[nelement];
    token.nextToken();
    ngen = (int)token.nval;
    arrows = new int[nelement][ngen];
    smallestFace = new int[nelement];
    blank = new int[nelement];
    minRot = new int[nelement];
    for (int i=0;i<nelement;i++){
      element[i] = new Omatrix();
      token.nextToken();  
      smallestFace[i] = (int)token.nval;
      token.nextToken();  
      blank[i] = (int)token.nval;

      for (int j=0;j<ngen;j++){
        token.nextToken();  
        arrows[i][j] = (int)token.nval;
      }
      token.nextToken();
      minRot[i] = (int)token.nval;
      for (int j=0;j<minRot[i];j++){
        token.nextToken();
        geni =(int)token.nval; 
        element[i] = gen[geni].Times(element[i]);
      }
      element[i] = tilt.Times(element[i]);
    }
  }

  /*  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  */
  public String toString() {
    String              str;
 
    /* .. this was only for debugging .. */
    str ="GroupGraph ";
    for (int i=0;i<nelement;i++){
      str =str.concat(element[i].toString());
      str = str.concat("A ");
      for (int j=0;j<ngen;j++){
        str = str.concat(", "+ arrows[i][j]);
      }
    }
    return str;
  }
}
