import flash.display.BitmapData;
import flash.display3D.Context3D;

import flash.text.TextField;

class Text3D extends Square3D {
  public function new( ?width:Float = 1.0,
                       ?height:Float = 1.0 ) {
    super( width, height, true );
  }

  public override function translate( x:Float,
                                      y:Float,
                                      z:Float ):Void {
    origin.x += x;
    origin.y += y;
    origin.z += z;
  }

  public function flipBitmapData( bd:BitmapData,
                                  size:Int ):BitmapData {
    var newbie:BitmapData = new BitmapData( size, size, true, 0x00FFFFFF );
    newbie.lock();
    for ( i in 0 ... bd.width ) {
      var j:Int = 0;
      for ( j in 0 ... bd.height ) {
        var curPixel:UInt = bd.getPixel32( i, bd.height - j - 1 );
        newbie.setPixel32( i, j, curPixel );
      }
    }
    newbie.unlock();
    return( newbie );
  }

  // this function must be called eariler than allocate(c)
  public function createTextTexture( c:Context3D,
                                     tf:TextField ) {
    var size:Int = __relevantCanvasSize( Math.max( tf.width, tf.height ) );
    //var bd:BitmapData = new BitmapData( size, size, true, 0x00000000 );
    var bd:BitmapData = new BitmapData( Std.int( tf.width ),
                                        Std.int( tf.height ),
                                        true, 0x00FFFFFF );
    bd.draw( tf );
    texture = c.createTexture( size, size, flash.display3D.Context3DTextureFormat.BGRA, false );
    texture.uploadFromBitmapData( flipBitmapData( bd, size ) );
    // replaceing UV positions
    var w:Float = Std.int( tf.width ) / cast(size,Float);
    var h:Float = Std.int( tf.height ) / cast(size,Float);
    faces[0].uv0 = new UVCoord( 0, 0 );
    faces[0].uv1 = new UVCoord( 0, h );
    faces[0].uv2 = new UVCoord( w, 0 );
    faces[1].uv0 = new UVCoord( w, 0 );
    faces[1].uv1 = new UVCoord( 0, h );
    faces[1].uv2 = new UVCoord( w, h );
  }

  private function __relevantCanvasSize( width:Float ):Int {
    var ret:Int = 0;
    while( Math.pow( 2, Std.int(++ret) ) < width ) {}
    return( Std.int( Math.pow( 2, ret ) ) );
  }
}
