import flash.display3D.Context3D;

class Triangles extends Polygon {
  private var numvert:Int;
  private var verthash( null, null ):Hash< Int >;
  private var myfaces( null, null ):Array< Face >;
  private var mykeys( null, null ):Array< String >;

  private var uv0( null, null ):UVCoord;
  private var uv1( null, null ):UVCoord;
  private var uv2( null, null ):UVCoord;

  public function new() {
    super();
    numvert = 0;
    verthash = new Hash< Int >();
    myfaces = new Array< Face >();
    mykeys = new Array< String >();
    uv0 = new UVCoord( 0.0, 0.0 );
    uv1 = new UVCoord( 1.0, 0.0 );
    uv2 = new UVCoord( 0.5, 1.0 );
  }

  // register a face, String values contain three dimensional position
  // These Strings are used as keys in hash
  public function registerFace( v0:String,
                                v1:String,
                                v2:String ):Void {
    addMyFace( new Face( getVertIndex( v0 ),
                         getVertIndex( v1 ),
                         getVertIndex( v2 ), uv0, uv1, uv2 ) );
  }

  public function getVertIndex( v:String ):Int {
    if ( verthash.exists( v ) ) {
      return( verthash.get( v ) );
    }
    verthash.set( v, numvert );
    mykeys.push( v );
    return( numvert++ );
  }

  // generate vertex and faces
  // makeFlat option is just reserved, not intended to be used now.
  private function genVertFace( makeFlat:Bool = false ):Void {
    //if ( makeFlat ) {
    //} else {
      for ( key in mykeys ) {
        // i believe hash keys are not sorted or reordered
        addVertexPos( Point3D.fromString( key ) );
      }
      for ( key in mykeys ) { // for back-face
        addVertexPos( Point3D.fromString( key ) );
      }
      for ( face in myfaces ) {
        addFace( face );
        addFace( new Face( face.ids.i + numvert,
                           face.ids.k + numvert,
                           face.ids.j + numvert,
                           uv0, uv2, uv1 ) );
      }
    //}
  }

  public override function allocate( c:Context3D,
                                     ?str:String = "Gouraud",
                                     ?color:Int = 0x00FF00,
                                     ?alpha:Float = 1.0 ):Void {
    genVertFace();
    super.allocate( c, str, color, alpha );
  }

  private function addMyFace( f:Face ):Void {
    myfaces.push( f );
  }
}
