package SModeling;

import java.io.StreamTokenizer;
import java.io.InputStream;

/** 
 *  Subclass of ModelParser which takes a file in Wavefront .obj format and
 *  creates an object of class model.<p>
 *
 * <hr>
 * Copyright (c) 1995, H. Robert Frost, Stanford University.
 * All rights reserved.<p>
 * Copyright (c) 1996, H. Robert Frost, Enterprise Integration Technologies,
 * Inc. All rights reserved.<p>
 *
 * RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by the 
 * Government is subject to restrictions as set forth in 
 * subparagraph(c)(1)(ii) of the Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 and in similar clauses in the
 * FAR and NASA FAR supplement.<p>
 * 
 * This software is bound by the terms and conditions listed in the
 * attached <a href="../LICENSE">LICENSE file</A>.
 * <hr>
 * @author <A HREF="http://cdr.stanford.edu/html/people/frost-bio.html"> Rob Frost</A>
 * @version 5/21/96 for Java(tm) Language Version 1.0.2
 */


public class ObjectFormatParser extends ModelParser {
 
  /**
   * Build a model from a .obj file which is read from an InputStream.
   * @param is InputStream which contains the .obj file
   * @return The resulting model
   */

  public static model ParseInputStream(InputStream is){

    StreamTokenizer st;
    
    model M = new model();
    st = new StreamTokenizer(is);
    st.eolIsSignificant(true);
    st.commentChar('#');
    
    try{
      
    scan:
    
    while (true) {
      
      switch (st.nextToken()) {
	
      default:
	break scan;
	
      case StreamTokenizer.TT_EOL: /* break at end of line */
	break;
	
      case StreamTokenizer.TT_WORD:
  	
	if ("v".equals(st.sval)) {
	  
	  hpoint vertex;
	  double x = 0, y = 0, z = 0;
	  if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
	    x = st.nval;
	    if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
	      y = st.nval;
	      if (st.nextToken() == StreamTokenizer.TT_NUMBER)
		z = st.nval;
	    }
	  }
	  vertex = new hpoint((float) x, (float) y, (float) z, 1);
	  M.add_vertex(vertex);
	  while (st.ttype != StreamTokenizer.TT_EOL &&
		 st.ttype != StreamTokenizer.TT_EOF)
	    st.nextToken();
	  
	} else if ("f".equals(st.sval)) {
	  
	  face f = new face(20, 5);

	  while (true) {
	    if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
	      f.addV((int)st.nval);
	    } else if (st.ttype == '/') { 
	      st.nextToken();
	    } else { 
	      break;
	    }
	  }
	  M.add_face(f);
	  if (st.ttype != StreamTokenizer.TT_EOL) {
	    break scan;
	  }  
	} else {
	  
	  while (st.nextToken() != StreamTokenizer.TT_EOL &&
		 st.ttype != StreamTokenizer.TT_EOF);
	}
      }
    }
    is.close();
    if (st.ttype != StreamTokenizer.TT_EOF) {
      throw new Exception(st.toString());
    }

  } catch (Exception e){
    
  }

    M.ReduceModel();
    return M;
  }
 
}




