
/// A hello-world Heaps project with both 2d and 3d rendering.
class Hello extends hxd.App {
  // This is a static var so we can locate the active app instance from other objects easily.
  public static var activeApp: Hello;

  // This is metadata we can extract for use elsewhere, or in messages or whatever.
  static public final APP_NAME = "Aldercone Hello Heaps";
  static public final APP_VERSION = "0.0.1";
  static public final APP_AUTHOR = "Aldercone Studio Collective";
  static public final APP_COPYRIGHT = "©Copyright 2025";

  // other static/final stuff can be here, like templates, constants, and whatever.
  public final ROTATION_SPEED=0.8; // radians / s

  // gamestate variables and stuff can go here
  public var cube: h3d.scene.Mesh;

  /// This sets up the game state, creates any objects that are there by default, etc. For multiple-state
  // games consider having functions which setup those states, and then calling the 'default' from here.
  // (eg. a state for main menu with an entirely different scene, a state for gameplay or whatever)
  override function init() {
    super.init();
    // assign whatever the active instance is.
    Hello.activeApp = this;

    // Setup default game state.

    // make a cube (all of this is pretty specific to built-in prims and not 3d objects in general)
    var cubeprim = new h3d.prim.Cube();
    // the cube prim usually translates/rotates around its corner, instead move it to translate around center.
    cubeprim.translate(-0.5, -0.5, -0.5);
    cubeprim.unindex(); // idk, the demo does this
    cubeprim.addNormals(); // create normals for the faces
    cubeprim.addUVs(); // create UV (texture) coordinates for the faces

    // load a texture from the res/ folder or the resources
    var texture = hxd.Res.images.aldercone.toTexture(); // this is the semi-magical way to do this, you can also specify
                                                        // a filename
    var material = h3d.mat.Material.create(texture); // this creates a material, with other properties like emissivity, glossyness etc.

    // Actually create the scenegraph object, which is a mesh
    this.cube = new h3d.scene.Mesh(cubeprim, material, s3d); // Note: s3d is a global variable pointing at the top level
                                                             // 3d scene which contains the 3d objects in the scenegraph

    // add some point lights to the scene (note the lighting model in the 'forward' renderer is weird) FIXME we should switch to PBR since the results are more predictable and less weird looking in Heaps 2 and above
    var light = new h3d.scene.fwd.PointLight(s3d);
    light.setPosition(s3d.camera.pos.x, s3d.camera.pos.y, s3d.camera.pos.z);
    light.enableSpecular = true;

    trace(s3d.camera.pos);

    light = new h3d.scene.fwd.PointLight(s3d);
    light.setPosition(2, -3, -4);
    light.enableSpecular = true;

    light = new h3d.scene.fwd.PointLight(s3d);
    light.setPosition(0, -10, -10);
    light.enableSpecular = true;

    // show a little 2d stuff
    // load a font from the resources

    // write some text on screen

  }


  /// This function is called each frame with a number of seconds passed since last call.
  override public function update(dt: Float) {
    super.update(dt);

    // rotate the cube
    cube.rotate(dt * -1 * ROTATION_SPEED, dt * ROTATION_SPEED, dt * ROTATION_SPEED);
  }

  // This overrides the main function, and sets up the resource loader prior to creating the main object.
  static function main(): Void {
    #if js
    hxd.Res.initEmbed();
    #else
    hxd.Res.initLocal();
    #end
    new Hello();
  }

}