// --------------------------------------------------------------------
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// --------------------------------------------------------------------

package tinylib.primitives;

import flash.display3D.Context3D;

/**
  Set of Triangles
**/

class Triangles extends Polygon {
  @:isVar public var makeFlat( get, set ):Bool;
    public function get_makeFlat():Bool { return( makeFlat ); }
    public function set_makeFlat( f:Bool ):Bool { makeFlat = f; return( makeFlat ); }

  private var numvert:Int;
  private var verthash:Map< String, Int >;
  private var myfaces:Array< Face >;
  private var mykeys:Array< String >;

  private var uv0:UVCoord;
  private var uv1:UVCoord;
  private var uv2:UVCoord;

  public function new() {
    super();
    numvert = 0;
    verthash = new Map< String, 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 );
    makeFlat = false;
  }

  // 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 ( makeFlat ) {
      mykeys.push( v );
    } else {
      if ( verthash.exists( v ) ) {
        return( verthash.get( v ) );
      }
      verthash.set( v, numvert );
      mykeys.push( v );
    }
    return( numvert++ );
  }

  // generate vertex and faces
  private function genVertFace():Void {
    for ( key in mykeys ) {
      // i believe hash keys are not sorted or reordered
      addVertexPos( Point3D.fromStringInverted( key ) );
    }
    for ( key in mykeys ) { // for back-face
      addVertexPos( Point3D.fromStringInverted( key ) );
    }
    for ( face in myfaces ) {
      addFace( face );
      addFace( new Face( face.ids.k + numvert,
                         face.ids.j + numvert,
                         face.ids.i + numvert,
                         uv2, uv1, uv0 ) );
    }
  }

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

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